mfplat: Remove duplicated GUID entry from attribute tracing.
[wine/zf.git] / dlls / rpcrt4 / ndr_marshall.c
blob764b304a047d9f49aff5592b01caa5aa06f3d033
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 <assert.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <limits.h>
36 #define NONAMELESSUNION
37 #include "windef.h"
38 #include "winbase.h"
39 #include "winerror.h"
41 #include "ndr_misc.h"
42 #include "rpcndr.h"
43 #include "ndrtypes.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 static inline void align_length( ULONG *len, unsigned int align )
94 *len = (*len + align - 1) & ~(align - 1);
97 static inline void align_pointer( unsigned char **ptr, unsigned int align )
99 ULONG_PTR mask = align - 1;
100 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
103 static inline void align_pointer_clear( unsigned char **ptr, unsigned int align )
105 ULONG_PTR mask = align - 1;
106 memset( *ptr, 0, (align - (ULONG_PTR)*ptr) & mask );
107 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
110 static inline void align_pointer_offset( unsigned char **ptr, unsigned char *base, unsigned int align )
112 ULONG_PTR mask = align - 1;
113 *ptr = base + (((ULONG_PTR)(*ptr - base) + mask) & ~mask);
116 static inline void align_pointer_offset_clear( unsigned char **ptr, unsigned char *base, unsigned int align )
118 ULONG_PTR mask = align - 1;
119 memset( *ptr, 0, (align - (ULONG_PTR)(*ptr - base)) & mask );
120 *ptr = base + (((ULONG_PTR)(*ptr - base) + mask) & ~mask);
123 #define STD_OVERFLOW_CHECK(_Msg) do { \
124 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
125 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
126 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
127 } while (0)
129 #define NDR_POINTER_ID_BASE 0x20000
130 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
131 #define NDR_TABLE_SIZE 128
132 #define NDR_TABLE_MASK 127
134 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
135 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
136 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
137 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
138 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
140 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
141 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
142 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
144 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING);
145 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
146 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
147 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
149 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
151 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
152 unsigned char *pMemory,
153 PFORMAT_STRING pFormat,
154 PFORMAT_STRING pPointer);
155 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
156 unsigned char *pMemory,
157 PFORMAT_STRING pFormat,
158 PFORMAT_STRING pPointer);
159 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
160 unsigned char *pMemory,
161 PFORMAT_STRING pFormat,
162 PFORMAT_STRING pPointer,
163 unsigned char fMustAlloc);
164 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
165 PFORMAT_STRING pFormat,
166 PFORMAT_STRING pPointer);
167 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
168 unsigned char *pMemory,
169 PFORMAT_STRING pFormat,
170 PFORMAT_STRING pPointer);
172 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
174 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
175 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
176 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
177 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
178 /* 0x10 */
179 NdrBaseTypeMarshall,
180 /* 0x11 */
181 NdrPointerMarshall, NdrPointerMarshall,
182 NdrPointerMarshall, NdrPointerMarshall,
183 /* 0x15 */
184 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
185 NdrConformantStructMarshall, NdrConformantStructMarshall,
186 NdrConformantVaryingStructMarshall,
187 NdrComplexStructMarshall,
188 /* 0x1b */
189 NdrConformantArrayMarshall,
190 NdrConformantVaryingArrayMarshall,
191 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
192 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
193 NdrComplexArrayMarshall,
194 /* 0x22 */
195 NdrConformantStringMarshall, 0, 0,
196 NdrConformantStringMarshall,
197 NdrNonConformantStringMarshall, 0, 0, 0,
198 /* 0x2a */
199 NdrEncapsulatedUnionMarshall,
200 NdrNonEncapsulatedUnionMarshall,
201 NdrByteCountPointerMarshall,
202 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
203 /* 0x2f */
204 NdrInterfacePointerMarshall,
205 /* 0x30 */
206 NdrContextHandleMarshall,
207 /* 0xb1 */
208 0, 0, 0,
209 NdrUserMarshalMarshall,
210 0, 0,
211 /* 0xb7 */
212 NdrRangeMarshall,
213 NdrBaseTypeMarshall,
214 NdrBaseTypeMarshall
216 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
218 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
219 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
220 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
221 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
222 /* 0x10 */
223 NdrBaseTypeUnmarshall,
224 /* 0x11 */
225 NdrPointerUnmarshall, NdrPointerUnmarshall,
226 NdrPointerUnmarshall, NdrPointerUnmarshall,
227 /* 0x15 */
228 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
229 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
230 NdrConformantVaryingStructUnmarshall,
231 NdrComplexStructUnmarshall,
232 /* 0x1b */
233 NdrConformantArrayUnmarshall,
234 NdrConformantVaryingArrayUnmarshall,
235 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
236 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
237 NdrComplexArrayUnmarshall,
238 /* 0x22 */
239 NdrConformantStringUnmarshall, 0, 0,
240 NdrConformantStringUnmarshall,
241 NdrNonConformantStringUnmarshall, 0, 0, 0,
242 /* 0x2a */
243 NdrEncapsulatedUnionUnmarshall,
244 NdrNonEncapsulatedUnionUnmarshall,
245 NdrByteCountPointerUnmarshall,
246 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
247 /* 0x2f */
248 NdrInterfacePointerUnmarshall,
249 /* 0x30 */
250 NdrContextHandleUnmarshall,
251 /* 0xb1 */
252 0, 0, 0,
253 NdrUserMarshalUnmarshall,
254 0, 0,
255 /* 0xb7 */
256 NdrRangeUnmarshall,
257 NdrBaseTypeUnmarshall,
258 NdrBaseTypeUnmarshall
260 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
262 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
263 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
264 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
265 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
266 /* 0x10 */
267 NdrBaseTypeBufferSize,
268 /* 0x11 */
269 NdrPointerBufferSize, NdrPointerBufferSize,
270 NdrPointerBufferSize, NdrPointerBufferSize,
271 /* 0x15 */
272 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
273 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
274 NdrConformantVaryingStructBufferSize,
275 NdrComplexStructBufferSize,
276 /* 0x1b */
277 NdrConformantArrayBufferSize,
278 NdrConformantVaryingArrayBufferSize,
279 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
280 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
281 NdrComplexArrayBufferSize,
282 /* 0x22 */
283 NdrConformantStringBufferSize, 0, 0,
284 NdrConformantStringBufferSize,
285 NdrNonConformantStringBufferSize, 0, 0, 0,
286 /* 0x2a */
287 NdrEncapsulatedUnionBufferSize,
288 NdrNonEncapsulatedUnionBufferSize,
289 NdrByteCountPointerBufferSize,
290 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
291 /* 0x2f */
292 NdrInterfacePointerBufferSize,
293 /* 0x30 */
294 NdrContextHandleBufferSize,
295 /* 0xb1 */
296 0, 0, 0,
297 NdrUserMarshalBufferSize,
298 0, 0,
299 /* 0xb7 */
300 NdrRangeBufferSize,
301 NdrBaseTypeBufferSize,
302 NdrBaseTypeBufferSize
304 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
306 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
307 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
308 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
309 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
310 /* 0x10 */
311 NdrBaseTypeMemorySize,
312 /* 0x11 */
313 NdrPointerMemorySize, NdrPointerMemorySize,
314 NdrPointerMemorySize, NdrPointerMemorySize,
315 /* 0x15 */
316 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
317 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
318 NdrConformantVaryingStructMemorySize,
319 NdrComplexStructMemorySize,
320 /* 0x1b */
321 NdrConformantArrayMemorySize,
322 NdrConformantVaryingArrayMemorySize,
323 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
324 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
325 NdrComplexArrayMemorySize,
326 /* 0x22 */
327 NdrConformantStringMemorySize, 0, 0,
328 NdrConformantStringMemorySize,
329 NdrNonConformantStringMemorySize, 0, 0, 0,
330 /* 0x2a */
331 NdrEncapsulatedUnionMemorySize,
332 NdrNonEncapsulatedUnionMemorySize,
333 NdrByteCountPointerMemorySize,
334 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
335 /* 0x2f */
336 NdrInterfacePointerMemorySize,
337 /* 0x30 */
339 /* 0xb1 */
340 0, 0, 0,
341 NdrUserMarshalMemorySize,
342 0, 0,
343 /* 0xb7 */
344 NdrRangeMemorySize,
345 NdrBaseTypeMemorySize,
346 NdrBaseTypeMemorySize
348 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
350 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
351 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
352 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
353 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
354 /* 0x10 */
355 NdrBaseTypeFree,
356 /* 0x11 */
357 NdrPointerFree, NdrPointerFree,
358 NdrPointerFree, NdrPointerFree,
359 /* 0x15 */
360 NdrSimpleStructFree, NdrSimpleStructFree,
361 NdrConformantStructFree, NdrConformantStructFree,
362 NdrConformantVaryingStructFree,
363 NdrComplexStructFree,
364 /* 0x1b */
365 NdrConformantArrayFree,
366 NdrConformantVaryingArrayFree,
367 NdrFixedArrayFree, NdrFixedArrayFree,
368 NdrVaryingArrayFree, NdrVaryingArrayFree,
369 NdrComplexArrayFree,
370 /* 0x22 */
371 0, 0, 0,
372 0, 0, 0, 0, 0,
373 /* 0x2a */
374 NdrEncapsulatedUnionFree,
375 NdrNonEncapsulatedUnionFree,
377 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
378 /* 0x2f */
379 NdrInterfacePointerFree,
380 /* 0x30 */
382 /* 0xb1 */
383 0, 0, 0,
384 NdrUserMarshalFree,
385 0, 0,
386 /* 0xb7 */
387 NdrRangeFree,
388 NdrBaseTypeFree,
389 NdrBaseTypeFree
392 typedef struct _NDR_MEMORY_LIST
394 ULONG magic;
395 ULONG size;
396 ULONG reserved;
397 struct _NDR_MEMORY_LIST *next;
398 } NDR_MEMORY_LIST;
400 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
402 /***********************************************************************
403 * NdrAllocate [RPCRT4.@]
405 * Allocates a block of memory using pStubMsg->pfnAllocate.
407 * PARAMS
408 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
409 * len [I] Size of memory block to allocate.
411 * RETURNS
412 * The memory block of size len that was allocated.
414 * NOTES
415 * The memory block is always 8-byte aligned.
416 * If the function is unable to allocate memory an RPC_X_NO_MEMORY
417 * exception is raised.
419 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
421 SIZE_T aligned_len;
422 SIZE_T adjusted_len;
423 void *p;
424 NDR_MEMORY_LIST *mem_list;
426 aligned_len = (len + 7) & ~7;
427 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
428 /* check for overflow */
429 if (adjusted_len < len)
431 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
432 RpcRaiseException(RPC_X_BAD_STUB_DATA);
435 p = pStubMsg->pfnAllocate(adjusted_len);
436 if (!p) RpcRaiseException(RPC_X_NO_MEMORY);
438 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
439 mem_list->magic = MEML_MAGIC;
440 mem_list->size = aligned_len;
441 mem_list->reserved = 0;
442 mem_list->next = pStubMsg->pMemoryList;
443 pStubMsg->pMemoryList = mem_list;
445 TRACE("-- %p\n", p);
446 return p;
449 static void *NdrAllocateZero(MIDL_STUB_MESSAGE *stubmsg, SIZE_T len)
451 void *mem = NdrAllocate(stubmsg, len);
452 memset(mem, 0, len);
453 return mem;
456 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
458 TRACE("(%p, %p)\n", pStubMsg, Pointer);
460 pStubMsg->pfnFree(Pointer);
463 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
465 return (*(const ULONG *)pFormat != -1);
468 static inline PFORMAT_STRING SkipConformance(const PMIDL_STUB_MESSAGE pStubMsg, const PFORMAT_STRING pFormat)
470 return pFormat + 4 + pStubMsg->CorrDespIncrement;
473 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
475 align_pointer(&pStubMsg->Buffer, 4);
476 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
477 RpcRaiseException(RPC_X_BAD_STUB_DATA);
478 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
479 pStubMsg->Buffer += 4;
480 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
481 return SkipConformance(pStubMsg, pFormat);
484 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
486 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
488 pStubMsg->Offset = 0;
489 pStubMsg->ActualCount = pStubMsg->MaxCount;
490 goto done;
493 align_pointer(&pStubMsg->Buffer, 4);
494 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
495 RpcRaiseException(RPC_X_BAD_STUB_DATA);
496 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
497 pStubMsg->Buffer += 4;
498 TRACE("offset is %d\n", pStubMsg->Offset);
499 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
500 pStubMsg->Buffer += 4;
501 TRACE("variance is %d\n", pStubMsg->ActualCount);
503 if ((pStubMsg->ActualCount > MaxValue) ||
504 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
506 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
507 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
508 RpcRaiseException(RPC_S_INVALID_BOUND);
509 return NULL;
512 done:
513 return SkipConformance(pStubMsg, pFormat);
516 /* writes the conformance value to the buffer */
517 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
519 align_pointer_clear(&pStubMsg->Buffer, 4);
520 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
521 RpcRaiseException(RPC_X_BAD_STUB_DATA);
522 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
523 pStubMsg->Buffer += 4;
526 /* writes the variance values to the buffer */
527 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
529 align_pointer_clear(&pStubMsg->Buffer, 4);
530 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
531 RpcRaiseException(RPC_X_BAD_STUB_DATA);
532 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
533 pStubMsg->Buffer += 4;
534 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
535 pStubMsg->Buffer += 4;
538 /* requests buffer space for the conformance value */
539 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
541 align_length(&pStubMsg->BufferLength, 4);
542 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
543 RpcRaiseException(RPC_X_BAD_STUB_DATA);
544 pStubMsg->BufferLength += 4;
547 /* requests buffer space for the variance values */
548 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
550 align_length(&pStubMsg->BufferLength, 4);
551 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
552 RpcRaiseException(RPC_X_BAD_STUB_DATA);
553 pStubMsg->BufferLength += 8;
556 PFORMAT_STRING ComputeConformanceOrVariance(
557 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
558 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
560 BYTE dtype = pFormat[0] & 0xf;
561 short ofs = *(const short *)&pFormat[2];
562 LPVOID ptr = NULL;
563 ULONG_PTR data = 0;
565 if (!IsConformanceOrVariancePresent(pFormat)) {
566 /* null descriptor */
567 *pCount = def;
568 goto finish_conf;
571 switch (pFormat[0] & 0xf0) {
572 case FC_NORMAL_CONFORMANCE:
573 TRACE("normal conformance, ofs=%d\n", ofs);
574 ptr = pMemory;
575 break;
576 case FC_POINTER_CONFORMANCE:
577 TRACE("pointer conformance, ofs=%d\n", ofs);
578 ptr = pStubMsg->Memory;
579 break;
580 case FC_TOP_LEVEL_CONFORMANCE:
581 TRACE("toplevel conformance, ofs=%d\n", ofs);
582 if (pStubMsg->StackTop) {
583 ptr = pStubMsg->StackTop;
585 else {
586 /* -Os mode, *pCount is already set */
587 goto finish_conf;
589 break;
590 case FC_CONSTANT_CONFORMANCE:
591 data = ofs | ((DWORD)pFormat[1] << 16);
592 TRACE("constant conformance, val=%ld\n", data);
593 *pCount = data;
594 goto finish_conf;
595 case FC_TOP_LEVEL_MULTID_CONFORMANCE:
596 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
597 if (pStubMsg->StackTop) {
598 ptr = pStubMsg->StackTop;
600 else {
601 /* ? */
602 goto done_conf_grab;
604 break;
605 default:
606 FIXME("unknown conformance type %x, expect crash.\n", pFormat[0] & 0xf0);
607 goto finish_conf;
610 switch (pFormat[1]) {
611 case FC_DEREFERENCE:
612 ptr = *(LPVOID*)((char *)ptr + ofs);
613 break;
614 case FC_CALLBACK:
616 unsigned char *old_stack_top = pStubMsg->StackTop;
617 ULONG_PTR max_count, old_max_count = pStubMsg->MaxCount;
619 pStubMsg->StackTop = ptr;
621 /* ofs is index into StubDesc->apfnExprEval */
622 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
623 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
625 pStubMsg->StackTop = old_stack_top;
627 /* the callback function always stores the computed value in MaxCount */
628 max_count = pStubMsg->MaxCount;
629 pStubMsg->MaxCount = old_max_count;
630 *pCount = max_count;
631 goto finish_conf;
633 default:
634 ptr = (char *)ptr + ofs;
635 break;
638 switch (dtype) {
639 case FC_LONG:
640 case FC_ULONG:
641 data = *(DWORD*)ptr;
642 break;
643 case FC_SHORT:
644 data = *(SHORT*)ptr;
645 break;
646 case FC_USHORT:
647 data = *(USHORT*)ptr;
648 break;
649 case FC_CHAR:
650 case FC_SMALL:
651 data = *(CHAR*)ptr;
652 break;
653 case FC_BYTE:
654 case FC_USMALL:
655 data = *(UCHAR*)ptr;
656 break;
657 case FC_HYPER:
658 data = *(ULONGLONG *)ptr;
659 break;
660 default:
661 FIXME("unknown conformance data type %x\n", dtype);
662 goto done_conf_grab;
664 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
666 done_conf_grab:
667 switch (pFormat[1]) {
668 case FC_DEREFERENCE: /* already handled */
669 case 0: /* no op */
670 *pCount = data;
671 break;
672 case FC_ADD_1:
673 *pCount = data + 1;
674 break;
675 case FC_SUB_1:
676 *pCount = data - 1;
677 break;
678 case FC_MULT_2:
679 *pCount = data * 2;
680 break;
681 case FC_DIV_2:
682 *pCount = data / 2;
683 break;
684 default:
685 FIXME("unknown conformance op %d\n", pFormat[1]);
686 goto finish_conf;
689 finish_conf:
690 TRACE("resulting conformance is %ld\n", *pCount);
692 return SkipConformance(pStubMsg, pFormat);
695 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
697 return SkipConformance( pStubMsg, pFormat );
700 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
701 * the result overflows 32-bits */
702 static inline ULONG safe_multiply(ULONG a, ULONG b)
704 ULONGLONG ret = (ULONGLONG)a * b;
705 if (ret > 0xffffffff)
707 RpcRaiseException(RPC_S_INVALID_BOUND);
708 return 0;
710 return ret;
713 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
715 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
716 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
717 RpcRaiseException(RPC_X_BAD_STUB_DATA);
718 pStubMsg->Buffer += size;
721 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
723 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
725 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
726 pStubMsg->BufferLength, size);
727 RpcRaiseException(RPC_X_BAD_STUB_DATA);
729 pStubMsg->BufferLength += size;
732 /* copies data from the buffer, checking that there is enough data in the buffer
733 * to do so */
734 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
736 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
737 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
739 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
740 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
741 RpcRaiseException(RPC_X_BAD_STUB_DATA);
743 if (p == pStubMsg->Buffer)
744 ERR("pointer is the same as the buffer\n");
745 memcpy(p, pStubMsg->Buffer, size);
746 pStubMsg->Buffer += size;
749 /* copies data to the buffer, checking that there is enough space to do so */
750 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
752 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
753 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
755 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
756 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
757 size);
758 RpcRaiseException(RPC_X_BAD_STUB_DATA);
760 memcpy(pStubMsg->Buffer, p, size);
761 pStubMsg->Buffer += size;
764 /* verify that string data sitting in the buffer is valid and safe to
765 * unmarshall */
766 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
768 ULONG i;
770 /* verify the buffer is safe to access */
771 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
772 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
774 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
775 pStubMsg->BufferEnd, pStubMsg->Buffer);
776 RpcRaiseException(RPC_X_BAD_STUB_DATA);
779 /* strings must always have null terminating bytes */
780 if (bufsize < esize)
782 ERR("invalid string length of %d\n", bufsize / esize);
783 RpcRaiseException(RPC_S_INVALID_BOUND);
786 for (i = bufsize - esize; i < bufsize; i++)
787 if (pStubMsg->Buffer[i] != 0)
789 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
790 i, pStubMsg->Buffer[i]);
791 RpcRaiseException(RPC_S_INVALID_BOUND);
795 static inline void dump_pointer_attr(unsigned char attr)
797 if (attr & FC_ALLOCATE_ALL_NODES)
798 TRACE(" FC_ALLOCATE_ALL_NODES");
799 if (attr & FC_DONT_FREE)
800 TRACE(" FC_DONT_FREE");
801 if (attr & FC_ALLOCED_ON_STACK)
802 TRACE(" FC_ALLOCED_ON_STACK");
803 if (attr & FC_SIMPLE_POINTER)
804 TRACE(" FC_SIMPLE_POINTER");
805 if (attr & FC_POINTER_DEREF)
806 TRACE(" FC_POINTER_DEREF");
807 TRACE("\n");
810 /***********************************************************************
811 * PointerMarshall [internal]
813 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
814 unsigned char *Buffer,
815 unsigned char *Pointer,
816 PFORMAT_STRING pFormat)
818 unsigned type = pFormat[0], attr = pFormat[1];
819 PFORMAT_STRING desc;
820 NDR_MARSHALL m;
821 ULONG pointer_id;
822 BOOL pointer_needs_marshaling;
824 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
825 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
826 pFormat += 2;
827 if (attr & FC_SIMPLE_POINTER) desc = pFormat;
828 else desc = pFormat + *(const SHORT*)pFormat;
830 switch (type) {
831 case FC_RP: /* ref pointer (always non-null) */
832 if (!Pointer)
834 ERR("NULL ref pointer is not allowed\n");
835 RpcRaiseException(RPC_X_NULL_REF_POINTER);
837 pointer_needs_marshaling = TRUE;
838 break;
839 case FC_UP: /* unique pointer */
840 case FC_OP: /* object pointer - same as unique here */
841 if (Pointer)
842 pointer_needs_marshaling = TRUE;
843 else
844 pointer_needs_marshaling = FALSE;
845 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
846 TRACE("writing 0x%08x to buffer\n", pointer_id);
847 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
848 break;
849 case FC_FP:
850 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
851 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
852 TRACE("writing 0x%08x to buffer\n", pointer_id);
853 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
854 break;
855 default:
856 FIXME("unhandled ptr type=%02x\n", type);
857 RpcRaiseException(RPC_X_BAD_STUB_DATA);
858 return;
861 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
863 if (pointer_needs_marshaling) {
864 if (attr & FC_POINTER_DEREF) {
865 Pointer = *(unsigned char**)Pointer;
866 TRACE("deref => %p\n", Pointer);
868 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
869 if (m) m(pStubMsg, Pointer, desc);
870 else FIXME("no marshaller for data type=%02x\n", *desc);
873 STD_OVERFLOW_CHECK(pStubMsg);
876 /* pPointer is the pointer that we will unmarshal into; pSrcPointer is the
877 * pointer to memory which we may attempt to reuse if non-NULL. Usually these
878 * are the same; for the case when they aren't, see EmbeddedPointerUnmarshall().
880 * fMustAlloc seems to determine whether we can allocate from the buffer (if we
881 * are on the server side). It's ignored here, since we can't allocate a pointer
882 * from the buffer. */
883 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
884 unsigned char *Buffer,
885 unsigned char **pPointer,
886 unsigned char *pSrcPointer,
887 PFORMAT_STRING pFormat,
888 unsigned char fMustAlloc)
890 unsigned type = pFormat[0], attr = pFormat[1];
891 PFORMAT_STRING desc;
892 NDR_UNMARSHALL m;
893 DWORD pointer_id = 0;
894 BOOL pointer_needs_unmarshaling, need_alloc = FALSE, inner_must_alloc = FALSE;
896 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
897 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
898 pFormat += 2;
899 if (attr & FC_SIMPLE_POINTER) desc = pFormat;
900 else desc = pFormat + *(const SHORT*)pFormat;
902 switch (type) {
903 case FC_RP: /* ref pointer (always non-null) */
904 pointer_needs_unmarshaling = TRUE;
905 break;
906 case FC_UP: /* unique pointer */
907 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
908 TRACE("pointer_id is 0x%08x\n", pointer_id);
909 if (pointer_id)
910 pointer_needs_unmarshaling = TRUE;
911 else {
912 *pPointer = NULL;
913 pointer_needs_unmarshaling = FALSE;
915 break;
916 case FC_OP: /* object pointer - we must free data before overwriting it */
917 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
918 TRACE("pointer_id is 0x%08x\n", pointer_id);
920 /* An object pointer always allocates new memory (it cannot point to the
921 * buffer). */
922 inner_must_alloc = TRUE;
924 if (pSrcPointer)
925 FIXME("free object pointer %p\n", pSrcPointer);
926 if (pointer_id)
927 pointer_needs_unmarshaling = TRUE;
928 else
930 *pPointer = NULL;
931 pointer_needs_unmarshaling = FALSE;
933 break;
934 case FC_FP:
935 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
936 TRACE("pointer_id is 0x%08x\n", pointer_id);
937 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
938 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
939 break;
940 default:
941 FIXME("unhandled ptr type=%02x\n", type);
942 RpcRaiseException(RPC_X_BAD_STUB_DATA);
943 return;
946 if (pointer_needs_unmarshaling) {
947 unsigned char **current_ptr = pPointer;
948 if (pStubMsg->IsClient) {
949 TRACE("client\n");
950 /* Try to use the existing (source) pointer to unmarshall the data into
951 * so that [in, out] or [out, ref] parameters behave correctly. If the
952 * source pointer is NULL and we are not dereferencing, we must force the
953 * inner marshalling routine to allocate, since otherwise it will crash. */
954 if (pSrcPointer)
956 TRACE("setting *pPointer to %p\n", pSrcPointer);
957 *pPointer = pSrcPointer;
959 else
960 need_alloc = inner_must_alloc = TRUE;
961 } else {
962 TRACE("server\n");
963 /* We can use an existing source pointer here only if it is on-stack,
964 * probably since otherwise NdrPointerFree() might later try to free a
965 * pointer we don't know the provenance of. Otherwise we must always
966 * allocate if we are dereferencing. We never need to force the inner
967 * routine to allocate here, since it will either write into an existing
968 * pointer, or use a pointer to the buffer. */
969 if (attr & FC_POINTER_DEREF)
971 if (pSrcPointer && (attr & FC_ALLOCED_ON_STACK))
972 *pPointer = pSrcPointer;
973 else
974 need_alloc = TRUE;
976 else
977 *pPointer = NULL;
980 if (attr & FC_ALLOCATE_ALL_NODES)
981 FIXME("FC_ALLOCATE_ALL_NODES not implemented\n");
983 if (attr & FC_POINTER_DEREF) {
984 if (need_alloc)
985 *pPointer = NdrAllocateZero(pStubMsg, sizeof(void *));
987 current_ptr = *(unsigned char***)current_ptr;
988 TRACE("deref => %p\n", current_ptr);
990 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
991 if (m) m(pStubMsg, current_ptr, desc, inner_must_alloc);
992 else FIXME("no unmarshaller for data type=%02x\n", *desc);
994 if (type == FC_FP)
995 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
996 *pPointer);
999 TRACE("pointer=%p\n", *pPointer);
1002 /***********************************************************************
1003 * PointerBufferSize [internal]
1005 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1006 unsigned char *Pointer,
1007 PFORMAT_STRING pFormat)
1009 unsigned type = pFormat[0], attr = pFormat[1];
1010 PFORMAT_STRING desc;
1011 NDR_BUFFERSIZE m;
1012 BOOL pointer_needs_sizing;
1013 ULONG pointer_id;
1015 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1016 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1017 pFormat += 2;
1018 if (attr & FC_SIMPLE_POINTER) desc = pFormat;
1019 else desc = pFormat + *(const SHORT*)pFormat;
1021 switch (type) {
1022 case FC_RP: /* ref pointer (always non-null) */
1023 if (!Pointer)
1025 ERR("NULL ref pointer is not allowed\n");
1026 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1028 break;
1029 case FC_OP:
1030 case FC_UP:
1031 /* NULL pointer has no further representation */
1032 if (!Pointer)
1033 return;
1034 break;
1035 case FC_FP:
1036 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1037 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1038 if (!pointer_needs_sizing)
1039 return;
1040 break;
1041 default:
1042 FIXME("unhandled ptr type=%02x\n", type);
1043 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1044 return;
1047 if (attr & FC_POINTER_DEREF) {
1048 Pointer = *(unsigned char**)Pointer;
1049 TRACE("deref => %p\n", Pointer);
1052 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1053 if (m) m(pStubMsg, Pointer, desc);
1054 else FIXME("no buffersizer for data type=%02x\n", *desc);
1057 /***********************************************************************
1058 * PointerMemorySize [internal]
1060 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1061 unsigned char *Buffer, PFORMAT_STRING pFormat)
1063 unsigned type = pFormat[0], attr = pFormat[1];
1064 PFORMAT_STRING desc;
1065 NDR_MEMORYSIZE m;
1066 DWORD pointer_id = 0;
1067 BOOL pointer_needs_sizing;
1069 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1070 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1071 pFormat += 2;
1072 if (attr & FC_SIMPLE_POINTER) desc = pFormat;
1073 else desc = pFormat + *(const SHORT*)pFormat;
1075 switch (type) {
1076 case FC_RP: /* ref pointer (always non-null) */
1077 pointer_needs_sizing = TRUE;
1078 break;
1079 case FC_UP: /* unique pointer */
1080 case FC_OP: /* object pointer - we must free data before overwriting it */
1081 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1082 TRACE("pointer_id is 0x%08x\n", pointer_id);
1083 if (pointer_id)
1084 pointer_needs_sizing = TRUE;
1085 else
1086 pointer_needs_sizing = FALSE;
1087 break;
1088 case FC_FP:
1090 void *pointer;
1091 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1092 TRACE("pointer_id is 0x%08x\n", pointer_id);
1093 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1094 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1095 break;
1097 default:
1098 FIXME("unhandled ptr type=%02x\n", type);
1099 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1100 return 0;
1103 if (attr & FC_POINTER_DEREF) {
1104 align_length(&pStubMsg->MemorySize, sizeof(void*));
1105 pStubMsg->MemorySize += sizeof(void*);
1106 TRACE("deref\n");
1109 if (pointer_needs_sizing) {
1110 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1111 if (m) m(pStubMsg, desc);
1112 else FIXME("no memorysizer for data type=%02x\n", *desc);
1115 return pStubMsg->MemorySize;
1118 /***********************************************************************
1119 * PointerFree [internal]
1121 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1122 unsigned char *Pointer,
1123 PFORMAT_STRING pFormat)
1125 unsigned type = pFormat[0], attr = pFormat[1];
1126 PFORMAT_STRING desc;
1127 NDR_FREE m;
1128 unsigned char *current_pointer = Pointer;
1130 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1131 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1132 if (attr & FC_DONT_FREE) return;
1133 pFormat += 2;
1134 if (attr & FC_SIMPLE_POINTER) desc = pFormat;
1135 else desc = pFormat + *(const SHORT*)pFormat;
1137 if (!Pointer) return;
1139 if (type == FC_FP) {
1140 int pointer_needs_freeing = NdrFullPointerFree(
1141 pStubMsg->FullPtrXlatTables, Pointer);
1142 if (!pointer_needs_freeing)
1143 return;
1146 if (attr & FC_POINTER_DEREF) {
1147 current_pointer = *(unsigned char**)Pointer;
1148 TRACE("deref => %p\n", current_pointer);
1151 m = NdrFreer[*desc & NDR_TABLE_MASK];
1152 if (m) m(pStubMsg, current_pointer, desc);
1154 /* this check stops us from trying to free buffer memory. we don't have to
1155 * worry about clients, since they won't call this function.
1156 * we don't have to check for the buffer being reallocated because
1157 * BufferStart and BufferEnd won't be reset when allocating memory for
1158 * sending the response. we don't have to check for the new buffer here as
1159 * it won't be used a type memory, only for buffer memory */
1160 if (Pointer >= pStubMsg->BufferStart && Pointer <= pStubMsg->BufferEnd)
1161 goto notfree;
1163 if (attr & FC_ALLOCED_ON_STACK) {
1164 TRACE("not freeing stack ptr %p\n", Pointer);
1165 return;
1167 TRACE("freeing %p\n", Pointer);
1168 NdrFree(pStubMsg, Pointer);
1169 return;
1170 notfree:
1171 TRACE("not freeing %p\n", Pointer);
1174 /***********************************************************************
1175 * EmbeddedPointerMarshall
1177 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1178 unsigned char *pMemory,
1179 PFORMAT_STRING pFormat)
1181 unsigned char *Mark = pStubMsg->BufferMark;
1182 unsigned rep, count, stride;
1183 unsigned i;
1184 unsigned char *saved_buffer = NULL;
1186 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1188 if (*pFormat != FC_PP) return NULL;
1189 pFormat += 2;
1191 if (pStubMsg->PointerBufferMark)
1193 saved_buffer = pStubMsg->Buffer;
1194 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1195 pStubMsg->PointerBufferMark = NULL;
1198 while (pFormat[0] != FC_END) {
1199 switch (pFormat[0]) {
1200 default:
1201 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1202 /* fallthrough */
1203 case FC_NO_REPEAT:
1204 rep = 1;
1205 stride = 0;
1206 count = 1;
1207 pFormat += 2;
1208 break;
1209 case FC_FIXED_REPEAT:
1210 rep = *(const WORD*)&pFormat[2];
1211 stride = *(const WORD*)&pFormat[4];
1212 count = *(const WORD*)&pFormat[8];
1213 pFormat += 10;
1214 break;
1215 case FC_VARIABLE_REPEAT:
1216 rep = (pFormat[1] == FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1217 stride = *(const WORD*)&pFormat[2];
1218 count = *(const WORD*)&pFormat[6];
1219 pFormat += 8;
1220 break;
1222 for (i = 0; i < rep; i++) {
1223 PFORMAT_STRING info = pFormat;
1224 unsigned char *membase = pMemory + (i * stride);
1225 unsigned char *bufbase = Mark + (i * stride);
1226 unsigned u;
1228 for (u=0; u<count; u++,info+=8) {
1229 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1230 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1231 unsigned char *saved_memory = pStubMsg->Memory;
1233 pStubMsg->Memory = membase;
1234 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1235 pStubMsg->Memory = saved_memory;
1238 pFormat += 8 * count;
1241 if (saved_buffer)
1243 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1244 pStubMsg->Buffer = saved_buffer;
1247 STD_OVERFLOW_CHECK(pStubMsg);
1249 return NULL;
1252 /* rpcrt4 does something bizarre with embedded pointers: instead of copying the
1253 * struct/array/union from the buffer to memory and then unmarshalling pointers
1254 * into it, it unmarshals pointers into the buffer itself and then copies it to
1255 * memory. However, it will still attempt to use a user-supplied pointer where
1256 * appropriate (i.e. one on stack). Therefore we need to pass both pointers to
1257 * this function and to PointerUnmarshall: the pointer (to the buffer) that we
1258 * will actually unmarshal into (pDstBuffer), and the pointer (to memory) that
1259 * we will attempt to use for storage if possible (pSrcMemoryPtrs). */
1260 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1261 unsigned char *pDstBuffer,
1262 unsigned char *pSrcMemoryPtrs,
1263 PFORMAT_STRING pFormat,
1264 unsigned char fMustAlloc)
1266 unsigned char *Mark = pStubMsg->BufferMark;
1267 unsigned rep, count, stride;
1268 unsigned i;
1269 unsigned char *saved_buffer = NULL;
1271 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1273 if (*pFormat != FC_PP) return NULL;
1274 pFormat += 2;
1276 if (pStubMsg->PointerBufferMark)
1278 saved_buffer = pStubMsg->Buffer;
1279 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1280 pStubMsg->PointerBufferMark = NULL;
1283 while (pFormat[0] != FC_END) {
1284 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1285 switch (pFormat[0]) {
1286 default:
1287 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1288 /* fallthrough */
1289 case FC_NO_REPEAT:
1290 rep = 1;
1291 stride = 0;
1292 count = 1;
1293 pFormat += 2;
1294 break;
1295 case FC_FIXED_REPEAT:
1296 rep = *(const WORD*)&pFormat[2];
1297 stride = *(const WORD*)&pFormat[4];
1298 count = *(const WORD*)&pFormat[8];
1299 pFormat += 10;
1300 break;
1301 case FC_VARIABLE_REPEAT:
1302 rep = (pFormat[1] == FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1303 stride = *(const WORD*)&pFormat[2];
1304 count = *(const WORD*)&pFormat[6];
1305 pFormat += 8;
1306 break;
1308 for (i = 0; i < rep; i++) {
1309 PFORMAT_STRING info = pFormat;
1310 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1311 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1312 unsigned char *bufbase = Mark + (i * stride);
1313 unsigned u;
1315 for (u=0; u<count; u++,info+=8) {
1316 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1317 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1318 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1319 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1322 pFormat += 8 * count;
1325 if (saved_buffer)
1327 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1328 pStubMsg->Buffer = saved_buffer;
1331 return NULL;
1334 /***********************************************************************
1335 * EmbeddedPointerBufferSize
1337 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1338 unsigned char *pMemory,
1339 PFORMAT_STRING pFormat)
1341 unsigned rep, count, stride;
1342 unsigned i;
1343 ULONG saved_buffer_length = 0;
1345 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1347 if (pStubMsg->IgnoreEmbeddedPointers) return;
1349 if (*pFormat != FC_PP) return;
1350 pFormat += 2;
1352 if (pStubMsg->PointerLength)
1354 saved_buffer_length = pStubMsg->BufferLength;
1355 pStubMsg->BufferLength = pStubMsg->PointerLength;
1356 pStubMsg->PointerLength = 0;
1359 while (pFormat[0] != FC_END) {
1360 switch (pFormat[0]) {
1361 default:
1362 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1363 /* fallthrough */
1364 case FC_NO_REPEAT:
1365 rep = 1;
1366 stride = 0;
1367 count = 1;
1368 pFormat += 2;
1369 break;
1370 case FC_FIXED_REPEAT:
1371 rep = *(const WORD*)&pFormat[2];
1372 stride = *(const WORD*)&pFormat[4];
1373 count = *(const WORD*)&pFormat[8];
1374 pFormat += 10;
1375 break;
1376 case FC_VARIABLE_REPEAT:
1377 rep = (pFormat[1] == FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1378 stride = *(const WORD*)&pFormat[2];
1379 count = *(const WORD*)&pFormat[6];
1380 pFormat += 8;
1381 break;
1383 for (i = 0; i < rep; i++) {
1384 PFORMAT_STRING info = pFormat;
1385 unsigned char *membase = pMemory + (i * stride);
1386 unsigned u;
1388 for (u=0; u<count; u++,info+=8) {
1389 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1390 unsigned char *saved_memory = pStubMsg->Memory;
1392 pStubMsg->Memory = membase;
1393 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1394 pStubMsg->Memory = saved_memory;
1397 pFormat += 8 * count;
1400 if (saved_buffer_length)
1402 pStubMsg->PointerLength = pStubMsg->BufferLength;
1403 pStubMsg->BufferLength = saved_buffer_length;
1407 /***********************************************************************
1408 * EmbeddedPointerMemorySize [internal]
1410 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1411 PFORMAT_STRING pFormat)
1413 unsigned char *Mark = pStubMsg->BufferMark;
1414 unsigned rep, count, stride;
1415 unsigned i;
1416 unsigned char *saved_buffer = NULL;
1418 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1420 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1422 if (pStubMsg->PointerBufferMark)
1424 saved_buffer = pStubMsg->Buffer;
1425 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1426 pStubMsg->PointerBufferMark = NULL;
1429 if (*pFormat != FC_PP) return 0;
1430 pFormat += 2;
1432 while (pFormat[0] != FC_END) {
1433 switch (pFormat[0]) {
1434 default:
1435 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1436 /* fallthrough */
1437 case FC_NO_REPEAT:
1438 rep = 1;
1439 stride = 0;
1440 count = 1;
1441 pFormat += 2;
1442 break;
1443 case FC_FIXED_REPEAT:
1444 rep = *(const WORD*)&pFormat[2];
1445 stride = *(const WORD*)&pFormat[4];
1446 count = *(const WORD*)&pFormat[8];
1447 pFormat += 10;
1448 break;
1449 case FC_VARIABLE_REPEAT:
1450 rep = (pFormat[1] == FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1451 stride = *(const WORD*)&pFormat[2];
1452 count = *(const WORD*)&pFormat[6];
1453 pFormat += 8;
1454 break;
1456 for (i = 0; i < rep; i++) {
1457 PFORMAT_STRING info = pFormat;
1458 unsigned char *bufbase = Mark + (i * stride);
1459 unsigned u;
1460 for (u=0; u<count; u++,info+=8) {
1461 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1462 PointerMemorySize(pStubMsg, bufptr, info+4);
1465 pFormat += 8 * count;
1468 if (saved_buffer)
1470 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1471 pStubMsg->Buffer = saved_buffer;
1474 return 0;
1477 /***********************************************************************
1478 * EmbeddedPointerFree [internal]
1480 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1481 unsigned char *pMemory,
1482 PFORMAT_STRING pFormat)
1484 unsigned rep, count, stride;
1485 unsigned i;
1487 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1488 if (*pFormat != FC_PP) return;
1489 pFormat += 2;
1491 while (pFormat[0] != FC_END) {
1492 switch (pFormat[0]) {
1493 default:
1494 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1495 /* fallthrough */
1496 case FC_NO_REPEAT:
1497 rep = 1;
1498 stride = 0;
1499 count = 1;
1500 pFormat += 2;
1501 break;
1502 case FC_FIXED_REPEAT:
1503 rep = *(const WORD*)&pFormat[2];
1504 stride = *(const WORD*)&pFormat[4];
1505 count = *(const WORD*)&pFormat[8];
1506 pFormat += 10;
1507 break;
1508 case FC_VARIABLE_REPEAT:
1509 rep = (pFormat[1] == FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1510 stride = *(const WORD*)&pFormat[2];
1511 count = *(const WORD*)&pFormat[6];
1512 pFormat += 8;
1513 break;
1515 for (i = 0; i < rep; i++) {
1516 PFORMAT_STRING info = pFormat;
1517 unsigned char *membase = pMemory + (i * stride);
1518 unsigned u;
1520 for (u=0; u<count; u++,info+=8) {
1521 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1522 unsigned char *saved_memory = pStubMsg->Memory;
1524 pStubMsg->Memory = membase;
1525 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1526 pStubMsg->Memory = saved_memory;
1529 pFormat += 8 * count;
1533 /***********************************************************************
1534 * NdrPointerMarshall [RPCRT4.@]
1536 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1537 unsigned char *pMemory,
1538 PFORMAT_STRING pFormat)
1540 unsigned char *Buffer;
1542 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1544 /* Increment the buffer here instead of in PointerMarshall,
1545 * as that is used by embedded pointers which already handle the incrementing
1546 * the buffer, and shouldn't write any additional pointer data to the wire */
1547 if (*pFormat != FC_RP)
1549 align_pointer_clear(&pStubMsg->Buffer, 4);
1550 Buffer = pStubMsg->Buffer;
1551 safe_buffer_increment(pStubMsg, 4);
1553 else
1554 Buffer = pStubMsg->Buffer;
1556 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1558 return NULL;
1561 /***********************************************************************
1562 * NdrPointerUnmarshall [RPCRT4.@]
1564 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1565 unsigned char **ppMemory,
1566 PFORMAT_STRING pFormat,
1567 unsigned char fMustAlloc)
1569 unsigned char *Buffer;
1571 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1573 if (*pFormat == FC_RP)
1575 Buffer = pStubMsg->Buffer;
1576 /* Do the NULL ref pointer check here because embedded pointers can be
1577 * NULL if the type the pointer is embedded in was allocated rather than
1578 * being passed in by the client */
1579 if (pStubMsg->IsClient && !*ppMemory)
1581 ERR("NULL ref pointer is not allowed\n");
1582 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1585 else
1587 /* Increment the buffer here instead of in PointerUnmarshall,
1588 * as that is used by embedded pointers which already handle the incrementing
1589 * the buffer, and shouldn't read any additional pointer data from the
1590 * buffer */
1591 align_pointer(&pStubMsg->Buffer, 4);
1592 Buffer = pStubMsg->Buffer;
1593 safe_buffer_increment(pStubMsg, 4);
1596 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1598 return NULL;
1601 /***********************************************************************
1602 * NdrPointerBufferSize [RPCRT4.@]
1604 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1605 unsigned char *pMemory,
1606 PFORMAT_STRING pFormat)
1608 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1610 /* Increment the buffer length here instead of in PointerBufferSize,
1611 * as that is used by embedded pointers which already handle the buffer
1612 * length, and shouldn't write anything more to the wire */
1613 if (*pFormat != FC_RP)
1615 align_length(&pStubMsg->BufferLength, 4);
1616 safe_buffer_length_increment(pStubMsg, 4);
1619 PointerBufferSize(pStubMsg, pMemory, pFormat);
1622 /***********************************************************************
1623 * NdrPointerMemorySize [RPCRT4.@]
1625 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1626 PFORMAT_STRING pFormat)
1628 unsigned char *Buffer = pStubMsg->Buffer;
1629 if (*pFormat != FC_RP)
1631 align_pointer(&pStubMsg->Buffer, 4);
1632 safe_buffer_increment(pStubMsg, 4);
1634 align_length(&pStubMsg->MemorySize, sizeof(void *));
1635 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1638 /***********************************************************************
1639 * NdrPointerFree [RPCRT4.@]
1641 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1642 unsigned char *pMemory,
1643 PFORMAT_STRING pFormat)
1645 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1646 PointerFree(pStubMsg, pMemory, pFormat);
1649 /***********************************************************************
1650 * NdrSimpleTypeMarshall [RPCRT4.@]
1652 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1653 unsigned char FormatChar )
1655 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1658 /***********************************************************************
1659 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1661 * Unmarshall a base type.
1663 * NOTES
1664 * Doesn't check that the buffer is long enough before copying, so the caller
1665 * should do this.
1667 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1668 unsigned char FormatChar )
1670 #define BASE_TYPE_UNMARSHALL(type) \
1671 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1672 TRACE("pMemory: %p\n", pMemory); \
1673 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1674 pStubMsg->Buffer += sizeof(type);
1676 switch(FormatChar)
1678 case FC_BYTE:
1679 case FC_CHAR:
1680 case FC_SMALL:
1681 case FC_USMALL:
1682 BASE_TYPE_UNMARSHALL(UCHAR);
1683 TRACE("value: 0x%02x\n", *pMemory);
1684 break;
1685 case FC_WCHAR:
1686 case FC_SHORT:
1687 case FC_USHORT:
1688 BASE_TYPE_UNMARSHALL(USHORT);
1689 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1690 break;
1691 case FC_LONG:
1692 case FC_ULONG:
1693 case FC_ERROR_STATUS_T:
1694 case FC_ENUM32:
1695 BASE_TYPE_UNMARSHALL(ULONG);
1696 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1697 break;
1698 case FC_FLOAT:
1699 BASE_TYPE_UNMARSHALL(float);
1700 TRACE("value: %f\n", *(float *)pMemory);
1701 break;
1702 case FC_DOUBLE:
1703 BASE_TYPE_UNMARSHALL(double);
1704 TRACE("value: %f\n", *(double *)pMemory);
1705 break;
1706 case FC_HYPER:
1707 BASE_TYPE_UNMARSHALL(ULONGLONG);
1708 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1709 break;
1710 case FC_ENUM16:
1711 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
1712 TRACE("pMemory: %p\n", pMemory);
1713 /* 16-bits on the wire, but int in memory */
1714 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1715 pStubMsg->Buffer += sizeof(USHORT);
1716 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1717 break;
1718 case FC_INT3264:
1719 align_pointer(&pStubMsg->Buffer, sizeof(INT));
1720 /* 32-bits on the wire, but int_ptr in memory */
1721 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer;
1722 pStubMsg->Buffer += sizeof(INT);
1723 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory);
1724 break;
1725 case FC_UINT3264:
1726 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
1727 /* 32-bits on the wire, but int_ptr in memory */
1728 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer;
1729 pStubMsg->Buffer += sizeof(UINT);
1730 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory);
1731 break;
1732 case FC_IGNORE:
1733 break;
1734 default:
1735 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1737 #undef BASE_TYPE_UNMARSHALL
1740 /***********************************************************************
1741 * NdrSimpleStructMarshall [RPCRT4.@]
1743 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1744 unsigned char *pMemory,
1745 PFORMAT_STRING pFormat)
1747 unsigned size = *(const WORD*)(pFormat+2);
1748 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1750 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
1752 pStubMsg->BufferMark = pStubMsg->Buffer;
1753 safe_copy_to_buffer(pStubMsg, pMemory, size);
1755 if (pFormat[0] != FC_STRUCT)
1756 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1758 return NULL;
1761 /***********************************************************************
1762 * NdrSimpleStructUnmarshall [RPCRT4.@]
1764 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1765 unsigned char **ppMemory,
1766 PFORMAT_STRING pFormat,
1767 unsigned char fMustAlloc)
1769 unsigned size = *(const WORD*)(pFormat+2);
1770 unsigned char *saved_buffer;
1771 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1773 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1775 if (fMustAlloc)
1776 *ppMemory = NdrAllocateZero(pStubMsg, size);
1777 else
1779 if (!pStubMsg->IsClient && !*ppMemory)
1780 /* for servers, we just point straight into the RPC buffer */
1781 *ppMemory = pStubMsg->Buffer;
1784 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1785 safe_buffer_increment(pStubMsg, size);
1786 if (pFormat[0] == FC_PSTRUCT)
1787 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1789 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1790 if (*ppMemory != saved_buffer)
1791 memcpy(*ppMemory, saved_buffer, size);
1793 return NULL;
1796 /***********************************************************************
1797 * NdrSimpleStructBufferSize [RPCRT4.@]
1799 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1800 unsigned char *pMemory,
1801 PFORMAT_STRING pFormat)
1803 unsigned size = *(const WORD*)(pFormat+2);
1804 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1806 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
1808 safe_buffer_length_increment(pStubMsg, size);
1809 if (pFormat[0] != FC_STRUCT)
1810 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1813 /***********************************************************************
1814 * NdrSimpleStructMemorySize [RPCRT4.@]
1816 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1817 PFORMAT_STRING pFormat)
1819 unsigned short size = *(const WORD *)(pFormat+2);
1821 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1823 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1824 pStubMsg->MemorySize += size;
1825 safe_buffer_increment(pStubMsg, size);
1827 if (pFormat[0] != FC_STRUCT)
1828 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1829 return pStubMsg->MemorySize;
1832 /***********************************************************************
1833 * NdrSimpleStructFree [RPCRT4.@]
1835 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1836 unsigned char *pMemory,
1837 PFORMAT_STRING pFormat)
1839 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1840 if (pFormat[0] != FC_STRUCT)
1841 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1844 /* Array helpers */
1846 static inline void array_compute_and_size_conformance(
1847 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1848 PFORMAT_STRING pFormat)
1850 DWORD count;
1852 switch (fc)
1854 case FC_CARRAY:
1855 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1856 SizeConformance(pStubMsg);
1857 break;
1858 case FC_CVARRAY:
1859 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1860 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1861 SizeConformance(pStubMsg);
1862 break;
1863 case FC_C_CSTRING:
1864 case FC_C_WSTRING:
1865 if (fc == FC_C_CSTRING)
1867 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1868 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1870 else
1872 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1873 pStubMsg->ActualCount = lstrlenW((LPCWSTR)pMemory)+1;
1876 if (pFormat[1] == FC_STRING_SIZED)
1877 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1878 else
1879 pStubMsg->MaxCount = pStubMsg->ActualCount;
1881 SizeConformance(pStubMsg);
1882 break;
1883 case FC_BOGUS_ARRAY:
1884 count = *(const WORD *)(pFormat + 2);
1885 pFormat += 4;
1886 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg);
1887 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count);
1888 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1889 break;
1890 default:
1891 ERR("unknown array format 0x%x\n", fc);
1892 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1896 static inline void array_buffer_size(
1897 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1898 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1900 DWORD i, size;
1901 DWORD esize;
1902 unsigned char alignment;
1904 switch (fc)
1906 case FC_CARRAY:
1907 esize = *(const WORD*)(pFormat+2);
1908 alignment = pFormat[1] + 1;
1910 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1912 align_length(&pStubMsg->BufferLength, alignment);
1914 size = safe_multiply(esize, pStubMsg->MaxCount);
1915 /* conformance value plus array */
1916 safe_buffer_length_increment(pStubMsg, size);
1918 if (fHasPointers)
1919 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1920 break;
1921 case FC_CVARRAY:
1922 esize = *(const WORD*)(pFormat+2);
1923 alignment = pFormat[1] + 1;
1925 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1926 pFormat = SkipVariance(pStubMsg, pFormat);
1928 SizeVariance(pStubMsg);
1930 align_length(&pStubMsg->BufferLength, alignment);
1932 size = safe_multiply(esize, pStubMsg->ActualCount);
1933 safe_buffer_length_increment(pStubMsg, size);
1935 if (fHasPointers)
1936 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1937 break;
1938 case FC_C_CSTRING:
1939 case FC_C_WSTRING:
1940 if (fc == FC_C_CSTRING)
1941 esize = 1;
1942 else
1943 esize = 2;
1945 SizeVariance(pStubMsg);
1947 size = safe_multiply(esize, pStubMsg->ActualCount);
1948 safe_buffer_length_increment(pStubMsg, size);
1949 break;
1950 case FC_BOGUS_ARRAY:
1951 alignment = pFormat[1] + 1;
1952 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1953 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg);
1954 pFormat = SkipVariance(pStubMsg, pFormat);
1956 align_length(&pStubMsg->BufferLength, alignment);
1958 size = pStubMsg->ActualCount;
1959 for (i = 0; i < size; i++)
1960 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1961 break;
1962 default:
1963 ERR("unknown array format 0x%x\n", fc);
1964 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1968 static inline void array_compute_and_write_conformance(
1969 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1970 PFORMAT_STRING pFormat)
1972 ULONG def;
1973 BOOL conformance_present;
1975 switch (fc)
1977 case FC_CARRAY:
1978 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1979 WriteConformance(pStubMsg);
1980 break;
1981 case FC_CVARRAY:
1982 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1983 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1984 WriteConformance(pStubMsg);
1985 break;
1986 case FC_C_CSTRING:
1987 case FC_C_WSTRING:
1988 if (fc == FC_C_CSTRING)
1990 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1991 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1993 else
1995 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1996 pStubMsg->ActualCount = lstrlenW((LPCWSTR)pMemory)+1;
1998 if (pFormat[1] == FC_STRING_SIZED)
1999 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
2000 else
2001 pStubMsg->MaxCount = pStubMsg->ActualCount;
2002 pStubMsg->Offset = 0;
2003 WriteConformance(pStubMsg);
2004 break;
2005 case FC_BOGUS_ARRAY:
2006 def = *(const WORD *)(pFormat + 2);
2007 pFormat += 4;
2008 conformance_present = IsConformanceOrVariancePresent(pFormat);
2009 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2010 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2011 if (conformance_present) WriteConformance(pStubMsg);
2012 break;
2013 default:
2014 ERR("unknown array format 0x%x\n", fc);
2015 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2019 static inline void array_write_variance_and_marshall(
2020 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
2021 PFORMAT_STRING pFormat, unsigned char fHasPointers)
2023 DWORD i, size;
2024 DWORD esize;
2025 unsigned char alignment;
2027 switch (fc)
2029 case FC_CARRAY:
2030 esize = *(const WORD*)(pFormat+2);
2031 alignment = pFormat[1] + 1;
2033 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2035 align_pointer_clear(&pStubMsg->Buffer, alignment);
2037 size = safe_multiply(esize, pStubMsg->MaxCount);
2038 if (fHasPointers)
2039 pStubMsg->BufferMark = pStubMsg->Buffer;
2040 safe_copy_to_buffer(pStubMsg, pMemory, size);
2042 if (fHasPointers)
2043 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2044 break;
2045 case FC_CVARRAY:
2046 esize = *(const WORD*)(pFormat+2);
2047 alignment = pFormat[1] + 1;
2049 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2050 pFormat = SkipVariance(pStubMsg, pFormat);
2052 WriteVariance(pStubMsg);
2054 align_pointer_clear(&pStubMsg->Buffer, alignment);
2056 size = safe_multiply(esize, pStubMsg->ActualCount);
2058 if (fHasPointers)
2059 pStubMsg->BufferMark = pStubMsg->Buffer;
2060 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
2062 if (fHasPointers)
2063 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2064 break;
2065 case FC_C_CSTRING:
2066 case FC_C_WSTRING:
2067 if (fc == FC_C_CSTRING)
2068 esize = 1;
2069 else
2070 esize = 2;
2072 WriteVariance(pStubMsg);
2074 size = safe_multiply(esize, pStubMsg->ActualCount);
2075 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2076 break;
2077 case FC_BOGUS_ARRAY:
2078 alignment = pFormat[1] + 1;
2079 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2080 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg);
2081 pFormat = SkipVariance(pStubMsg, pFormat);
2083 align_pointer_clear(&pStubMsg->Buffer, alignment);
2085 size = pStubMsg->ActualCount;
2086 for (i = 0; i < size; i++)
2087 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2088 break;
2089 default:
2090 ERR("unknown array format 0x%x\n", fc);
2091 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2095 static inline ULONG array_read_conformance(
2096 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
2098 DWORD def, esize;
2100 switch (fc)
2102 case FC_CARRAY:
2103 esize = *(const WORD*)(pFormat+2);
2104 pFormat = ReadConformance(pStubMsg, pFormat+4);
2105 return safe_multiply(esize, pStubMsg->MaxCount);
2106 case FC_CVARRAY:
2107 esize = *(const WORD*)(pFormat+2);
2108 pFormat = ReadConformance(pStubMsg, pFormat+4);
2109 return safe_multiply(esize, pStubMsg->MaxCount);
2110 case FC_C_CSTRING:
2111 case FC_C_WSTRING:
2112 if (fc == FC_C_CSTRING)
2113 esize = 1;
2114 else
2115 esize = 2;
2117 if (pFormat[1] == FC_STRING_SIZED)
2118 ReadConformance(pStubMsg, pFormat + 2);
2119 else
2120 ReadConformance(pStubMsg, NULL);
2121 return safe_multiply(esize, pStubMsg->MaxCount);
2122 case FC_BOGUS_ARRAY:
2123 def = *(const WORD *)(pFormat + 2);
2124 pFormat += 4;
2125 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2126 else
2128 pStubMsg->MaxCount = def;
2129 pFormat = SkipConformance( pStubMsg, pFormat );
2131 pFormat = SkipVariance( pStubMsg, pFormat );
2133 esize = ComplexStructSize(pStubMsg, pFormat);
2134 return safe_multiply(pStubMsg->MaxCount, esize);
2135 default:
2136 ERR("unknown array format 0x%x\n", fc);
2137 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2141 static inline ULONG array_read_variance_and_unmarshall(
2142 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2143 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2144 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2146 ULONG bufsize, memsize;
2147 WORD esize;
2148 unsigned char alignment;
2149 unsigned char *saved_buffer, *pMemory;
2150 ULONG i, offset, count;
2152 switch (fc)
2154 case FC_CARRAY:
2155 esize = *(const WORD*)(pFormat+2);
2156 alignment = pFormat[1] + 1;
2158 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2160 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2162 align_pointer(&pStubMsg->Buffer, alignment);
2164 if (fUnmarshall)
2166 if (fMustAlloc)
2167 *ppMemory = NdrAllocateZero(pStubMsg, memsize);
2168 else
2170 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2171 /* for servers, we just point straight into the RPC buffer */
2172 *ppMemory = pStubMsg->Buffer;
2175 saved_buffer = pStubMsg->Buffer;
2176 safe_buffer_increment(pStubMsg, bufsize);
2178 pStubMsg->BufferMark = saved_buffer;
2179 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2181 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2182 if (*ppMemory != saved_buffer)
2183 memcpy(*ppMemory, saved_buffer, bufsize);
2185 return bufsize;
2186 case FC_CVARRAY:
2187 esize = *(const WORD*)(pFormat+2);
2188 alignment = pFormat[1] + 1;
2190 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2192 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2194 align_pointer(&pStubMsg->Buffer, alignment);
2196 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2197 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2199 if (fUnmarshall)
2201 offset = pStubMsg->Offset;
2203 if (!fMustAlloc && !*ppMemory)
2204 fMustAlloc = TRUE;
2205 if (fMustAlloc)
2206 *ppMemory = NdrAllocateZero(pStubMsg, memsize);
2207 saved_buffer = pStubMsg->Buffer;
2208 safe_buffer_increment(pStubMsg, bufsize);
2210 pStubMsg->BufferMark = saved_buffer;
2211 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2212 fMustAlloc);
2214 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2216 return bufsize;
2217 case FC_C_CSTRING:
2218 case FC_C_WSTRING:
2219 if (fc == FC_C_CSTRING)
2220 esize = 1;
2221 else
2222 esize = 2;
2224 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2226 if (pFormat[1] != FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2228 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2229 pStubMsg->ActualCount, pStubMsg->MaxCount);
2230 RpcRaiseException(RPC_S_INVALID_BOUND);
2232 if (pStubMsg->Offset)
2234 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2235 RpcRaiseException(RPC_S_INVALID_BOUND);
2238 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2239 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2241 validate_string_data(pStubMsg, bufsize, esize);
2243 if (fUnmarshall)
2245 if (fMustAlloc)
2246 *ppMemory = NdrAllocate(pStubMsg, memsize);
2247 else
2249 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2250 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2251 /* if the data in the RPC buffer is big enough, we just point
2252 * straight into it */
2253 *ppMemory = pStubMsg->Buffer;
2254 else if (!*ppMemory)
2255 *ppMemory = NdrAllocate(pStubMsg, memsize);
2258 if (*ppMemory == pStubMsg->Buffer)
2259 safe_buffer_increment(pStubMsg, bufsize);
2260 else
2261 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2263 if (*pFormat == FC_C_CSTRING)
2264 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2265 else
2266 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2268 return bufsize;
2270 case FC_BOGUS_ARRAY:
2271 alignment = pFormat[1] + 1;
2272 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2273 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2275 esize = ComplexStructSize(pStubMsg, pFormat);
2276 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2278 assert( fUnmarshall );
2280 if (!fMustAlloc && !*ppMemory)
2281 fMustAlloc = TRUE;
2282 if (fMustAlloc)
2283 *ppMemory = NdrAllocateZero(pStubMsg, memsize);
2285 align_pointer(&pStubMsg->Buffer, alignment);
2286 saved_buffer = pStubMsg->Buffer;
2288 pMemory = *ppMemory;
2289 count = pStubMsg->ActualCount;
2290 for (i = 0; i < count; i++)
2291 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2292 return pStubMsg->Buffer - saved_buffer;
2294 default:
2295 ERR("unknown array format 0x%x\n", fc);
2296 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2300 static inline void array_memory_size(
2301 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2302 unsigned char fHasPointers)
2304 ULONG i, count, SavedMemorySize;
2305 ULONG bufsize, memsize;
2306 DWORD esize;
2307 unsigned char alignment;
2309 switch (fc)
2311 case FC_CARRAY:
2312 esize = *(const WORD*)(pFormat+2);
2313 alignment = pFormat[1] + 1;
2315 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2317 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2318 pStubMsg->MemorySize += memsize;
2320 align_pointer(&pStubMsg->Buffer, alignment);
2321 if (fHasPointers)
2322 pStubMsg->BufferMark = pStubMsg->Buffer;
2323 safe_buffer_increment(pStubMsg, bufsize);
2325 if (fHasPointers)
2326 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2327 break;
2328 case FC_CVARRAY:
2329 esize = *(const WORD*)(pFormat+2);
2330 alignment = pFormat[1] + 1;
2332 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2334 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2336 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2337 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2338 pStubMsg->MemorySize += memsize;
2340 align_pointer(&pStubMsg->Buffer, alignment);
2341 if (fHasPointers)
2342 pStubMsg->BufferMark = pStubMsg->Buffer;
2343 safe_buffer_increment(pStubMsg, bufsize);
2345 if (fHasPointers)
2346 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2347 break;
2348 case FC_C_CSTRING:
2349 case FC_C_WSTRING:
2350 if (fc == FC_C_CSTRING)
2351 esize = 1;
2352 else
2353 esize = 2;
2355 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2357 if (pFormat[1] != FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2359 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2360 pStubMsg->ActualCount, pStubMsg->MaxCount);
2361 RpcRaiseException(RPC_S_INVALID_BOUND);
2363 if (pStubMsg->Offset)
2365 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2366 RpcRaiseException(RPC_S_INVALID_BOUND);
2369 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2370 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2372 validate_string_data(pStubMsg, bufsize, esize);
2374 safe_buffer_increment(pStubMsg, bufsize);
2375 pStubMsg->MemorySize += memsize;
2376 break;
2377 case FC_BOGUS_ARRAY:
2378 alignment = pFormat[1] + 1;
2379 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2380 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2382 align_pointer(&pStubMsg->Buffer, alignment);
2384 SavedMemorySize = pStubMsg->MemorySize;
2386 esize = ComplexStructSize(pStubMsg, pFormat);
2387 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2389 count = pStubMsg->ActualCount;
2390 for (i = 0; i < count; i++)
2391 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2393 pStubMsg->MemorySize = SavedMemorySize + memsize;
2394 break;
2395 default:
2396 ERR("unknown array format 0x%x\n", fc);
2397 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2401 static inline void array_free(
2402 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2403 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2405 DWORD i, count;
2407 switch (fc)
2409 case FC_CARRAY:
2410 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2411 if (fHasPointers)
2412 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2413 break;
2414 case FC_CVARRAY:
2415 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2416 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2417 if (fHasPointers)
2418 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2419 break;
2420 case FC_C_CSTRING:
2421 case FC_C_WSTRING:
2422 /* No embedded pointers so nothing to do */
2423 break;
2424 case FC_BOGUS_ARRAY:
2425 count = *(const WORD *)(pFormat + 2);
2426 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2427 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2429 count = pStubMsg->ActualCount;
2430 for (i = 0; i < count; i++)
2431 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2432 break;
2433 default:
2434 ERR("unknown array format 0x%x\n", fc);
2435 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2440 * NdrConformantString:
2442 * What MS calls a ConformantString is, in DCE terminology,
2443 * a Varying-Conformant String.
2445 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2446 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2447 * into unmarshalled string)
2448 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2450 * data: CHARTYPE[maxlen]
2452 * ], where CHARTYPE is the appropriate character type (specified externally)
2456 /***********************************************************************
2457 * NdrConformantStringMarshall [RPCRT4.@]
2459 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2460 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2462 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2464 if (pFormat[0] != FC_C_CSTRING && pFormat[0] != FC_C_WSTRING) {
2465 ERR("Unhandled string type: %#x\n", pFormat[0]);
2466 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2469 /* allow compiler to optimise inline function by passing constant into
2470 * these functions */
2471 if (pFormat[0] == FC_C_CSTRING) {
2472 array_compute_and_write_conformance(FC_C_CSTRING, pStubMsg, pszMessage,
2473 pFormat);
2474 array_write_variance_and_marshall(FC_C_CSTRING, pStubMsg, pszMessage,
2475 pFormat, TRUE /* fHasPointers */);
2476 } else {
2477 array_compute_and_write_conformance(FC_C_WSTRING, pStubMsg, pszMessage,
2478 pFormat);
2479 array_write_variance_and_marshall(FC_C_WSTRING, pStubMsg, pszMessage,
2480 pFormat, TRUE /* fHasPointers */);
2483 return NULL;
2486 /***********************************************************************
2487 * NdrConformantStringBufferSize [RPCRT4.@]
2489 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2490 unsigned char* pMemory, PFORMAT_STRING pFormat)
2492 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2494 if (pFormat[0] != FC_C_CSTRING && pFormat[0] != FC_C_WSTRING) {
2495 ERR("Unhandled string type: %#x\n", pFormat[0]);
2496 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2499 /* allow compiler to optimise inline function by passing constant into
2500 * these functions */
2501 if (pFormat[0] == FC_C_CSTRING) {
2502 array_compute_and_size_conformance(FC_C_CSTRING, pStubMsg, pMemory,
2503 pFormat);
2504 array_buffer_size(FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2505 TRUE /* fHasPointers */);
2506 } else {
2507 array_compute_and_size_conformance(FC_C_WSTRING, pStubMsg, pMemory,
2508 pFormat);
2509 array_buffer_size(FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2510 TRUE /* fHasPointers */);
2514 /************************************************************************
2515 * NdrConformantStringMemorySize [RPCRT4.@]
2517 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2518 PFORMAT_STRING pFormat )
2520 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2522 if (pFormat[0] != FC_C_CSTRING && pFormat[0] != FC_C_WSTRING) {
2523 ERR("Unhandled string type: %#x\n", pFormat[0]);
2524 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2527 /* allow compiler to optimise inline function by passing constant into
2528 * these functions */
2529 if (pFormat[0] == FC_C_CSTRING) {
2530 array_read_conformance(FC_C_CSTRING, pStubMsg, pFormat);
2531 array_memory_size(FC_C_CSTRING, pStubMsg, pFormat,
2532 TRUE /* fHasPointers */);
2533 } else {
2534 array_read_conformance(FC_C_WSTRING, pStubMsg, pFormat);
2535 array_memory_size(FC_C_WSTRING, pStubMsg, pFormat,
2536 TRUE /* fHasPointers */);
2539 return pStubMsg->MemorySize;
2542 /************************************************************************
2543 * NdrConformantStringUnmarshall [RPCRT4.@]
2545 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2546 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2548 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2549 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2551 if (pFormat[0] != FC_C_CSTRING && pFormat[0] != FC_C_WSTRING) {
2552 ERR("Unhandled string type: %#x\n", *pFormat);
2553 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2556 /* allow compiler to optimise inline function by passing constant into
2557 * these functions */
2558 if (pFormat[0] == FC_C_CSTRING) {
2559 array_read_conformance(FC_C_CSTRING, pStubMsg, pFormat);
2560 array_read_variance_and_unmarshall(FC_C_CSTRING, pStubMsg, ppMemory,
2561 pFormat, fMustAlloc,
2562 TRUE /* fUseBufferMemoryServer */,
2563 TRUE /* fUnmarshall */);
2564 } else {
2565 array_read_conformance(FC_C_WSTRING, pStubMsg, pFormat);
2566 array_read_variance_and_unmarshall(FC_C_WSTRING, pStubMsg, ppMemory,
2567 pFormat, fMustAlloc,
2568 TRUE /* fUseBufferMemoryServer */,
2569 TRUE /* fUnmarshall */);
2572 return NULL;
2575 /***********************************************************************
2576 * NdrNonConformantStringMarshall [RPCRT4.@]
2578 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2579 unsigned char *pMemory,
2580 PFORMAT_STRING pFormat)
2582 ULONG esize, size, maxsize;
2584 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2586 maxsize = *(const USHORT *)&pFormat[2];
2588 if (*pFormat == FC_CSTRING)
2590 ULONG i = 0;
2591 const char *str = (const char *)pMemory;
2592 while (i < maxsize && str[i]) i++;
2593 TRACE("string=%s\n", debugstr_an(str, i));
2594 pStubMsg->ActualCount = i + 1;
2595 esize = 1;
2597 else if (*pFormat == FC_WSTRING)
2599 ULONG i = 0;
2600 const WCHAR *str = (const WCHAR *)pMemory;
2601 while (i < maxsize && str[i]) i++;
2602 TRACE("string=%s\n", debugstr_wn(str, i));
2603 pStubMsg->ActualCount = i + 1;
2604 esize = 2;
2606 else
2608 ERR("Unhandled string type: %#x\n", *pFormat);
2609 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2612 pStubMsg->Offset = 0;
2613 WriteVariance(pStubMsg);
2615 size = safe_multiply(esize, pStubMsg->ActualCount);
2616 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2618 return NULL;
2621 /***********************************************************************
2622 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2624 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2625 unsigned char **ppMemory,
2626 PFORMAT_STRING pFormat,
2627 unsigned char fMustAlloc)
2629 ULONG bufsize, memsize, esize, maxsize;
2631 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2632 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2634 maxsize = *(const USHORT *)&pFormat[2];
2636 ReadVariance(pStubMsg, NULL, maxsize);
2637 if (pStubMsg->Offset)
2639 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2640 RpcRaiseException(RPC_S_INVALID_BOUND);
2643 if (*pFormat == FC_CSTRING) esize = 1;
2644 else if (*pFormat == FC_WSTRING) esize = 2;
2645 else
2647 ERR("Unhandled string type: %#x\n", *pFormat);
2648 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2651 memsize = esize * maxsize;
2652 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2654 validate_string_data(pStubMsg, bufsize, esize);
2656 if (!fMustAlloc && !*ppMemory)
2657 fMustAlloc = TRUE;
2658 if (fMustAlloc)
2659 *ppMemory = NdrAllocate(pStubMsg, memsize);
2661 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2663 if (*pFormat == FC_CSTRING) {
2664 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2666 else if (*pFormat == FC_WSTRING) {
2667 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2670 return NULL;
2673 /***********************************************************************
2674 * NdrNonConformantStringBufferSize [RPCRT4.@]
2676 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2677 unsigned char *pMemory,
2678 PFORMAT_STRING pFormat)
2680 ULONG esize, maxsize;
2682 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2684 maxsize = *(const USHORT *)&pFormat[2];
2686 SizeVariance(pStubMsg);
2688 if (*pFormat == FC_CSTRING)
2690 ULONG i = 0;
2691 const char *str = (const char *)pMemory;
2692 while (i < maxsize && str[i]) i++;
2693 TRACE("string=%s\n", debugstr_an(str, i));
2694 pStubMsg->ActualCount = i + 1;
2695 esize = 1;
2697 else if (*pFormat == FC_WSTRING)
2699 ULONG i = 0;
2700 const WCHAR *str = (const WCHAR *)pMemory;
2701 while (i < maxsize && str[i]) i++;
2702 TRACE("string=%s\n", debugstr_wn(str, i));
2703 pStubMsg->ActualCount = i + 1;
2704 esize = 2;
2706 else
2708 ERR("Unhandled string type: %#x\n", *pFormat);
2709 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2712 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2715 /***********************************************************************
2716 * NdrNonConformantStringMemorySize [RPCRT4.@]
2718 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2719 PFORMAT_STRING pFormat)
2721 ULONG bufsize, memsize, esize, maxsize;
2723 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2725 maxsize = *(const USHORT *)&pFormat[2];
2727 ReadVariance(pStubMsg, NULL, maxsize);
2729 if (pStubMsg->Offset)
2731 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2732 RpcRaiseException(RPC_S_INVALID_BOUND);
2735 if (*pFormat == FC_CSTRING) esize = 1;
2736 else if (*pFormat == FC_WSTRING) esize = 2;
2737 else
2739 ERR("Unhandled string type: %#x\n", *pFormat);
2740 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2743 memsize = esize * maxsize;
2744 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2746 validate_string_data(pStubMsg, bufsize, esize);
2748 safe_buffer_increment(pStubMsg, bufsize);
2749 pStubMsg->MemorySize += memsize;
2751 return pStubMsg->MemorySize;
2754 /* Complex types */
2756 #include "pshpack1.h"
2757 typedef struct
2759 unsigned char type;
2760 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2761 ULONG low_value;
2762 ULONG high_value;
2763 } NDR_RANGE;
2764 #include "poppack.h"
2766 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2767 PFORMAT_STRING pFormat)
2769 switch (*pFormat) {
2770 case FC_STRUCT:
2771 case FC_PSTRUCT:
2772 case FC_CSTRUCT:
2773 case FC_BOGUS_STRUCT:
2774 case FC_SMFARRAY:
2775 case FC_SMVARRAY:
2776 case FC_CSTRING:
2777 return *(const WORD*)&pFormat[2];
2778 case FC_LGFARRAY:
2779 case FC_LGVARRAY:
2780 return *(const ULONG*)&pFormat[2];
2781 case FC_USER_MARSHAL:
2782 return *(const WORD*)&pFormat[4];
2783 case FC_RANGE: {
2784 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2785 case FC_BYTE:
2786 case FC_CHAR:
2787 case FC_SMALL:
2788 case FC_USMALL:
2789 return sizeof(UCHAR);
2790 case FC_WCHAR:
2791 case FC_SHORT:
2792 case FC_USHORT:
2793 return sizeof(USHORT);
2794 case FC_LONG:
2795 case FC_ULONG:
2796 case FC_ENUM32:
2797 return sizeof(ULONG);
2798 case FC_FLOAT:
2799 return sizeof(float);
2800 case FC_DOUBLE:
2801 return sizeof(double);
2802 case FC_HYPER:
2803 return sizeof(ULONGLONG);
2804 case FC_ENUM16:
2805 return sizeof(UINT);
2806 default:
2807 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2808 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2811 case FC_NON_ENCAPSULATED_UNION:
2812 pFormat += 2;
2813 pFormat = SkipConformance(pStubMsg, pFormat);
2814 pFormat += *(const SHORT*)pFormat;
2815 return *(const SHORT*)pFormat;
2816 case FC_IP:
2817 return sizeof(void *);
2818 case FC_WSTRING:
2819 return *(const WORD*)&pFormat[2] * 2;
2820 default:
2821 FIXME("unhandled embedded type %02x\n", *pFormat);
2823 return 0;
2827 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2828 PFORMAT_STRING pFormat)
2830 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2832 if (!m)
2834 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2835 return 0;
2838 return m(pStubMsg, pFormat);
2842 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2843 unsigned char *pMemory,
2844 PFORMAT_STRING pFormat,
2845 PFORMAT_STRING pPointer)
2847 unsigned char *mem_base = pMemory;
2848 PFORMAT_STRING desc;
2849 NDR_MARSHALL m;
2850 ULONG size;
2852 while (*pFormat != FC_END) {
2853 switch (*pFormat) {
2854 case FC_BYTE:
2855 case FC_CHAR:
2856 case FC_SMALL:
2857 case FC_USMALL:
2858 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2859 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2860 pMemory += 1;
2861 break;
2862 case FC_WCHAR:
2863 case FC_SHORT:
2864 case FC_USHORT:
2865 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2866 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2867 pMemory += 2;
2868 break;
2869 case FC_ENUM16:
2871 USHORT val = *(DWORD *)pMemory;
2872 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2873 if (32767 < *(DWORD*)pMemory)
2874 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2875 safe_copy_to_buffer(pStubMsg, &val, 2);
2876 pMemory += 4;
2877 break;
2879 case FC_LONG:
2880 case FC_ULONG:
2881 case FC_ENUM32:
2882 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2883 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2884 pMemory += 4;
2885 break;
2886 case FC_INT3264:
2887 case FC_UINT3264:
2889 UINT val = *(UINT_PTR *)pMemory;
2890 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2891 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2892 pMemory += sizeof(UINT_PTR);
2893 break;
2895 case FC_FLOAT:
2896 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2897 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2898 pMemory += sizeof(float);
2899 break;
2900 case FC_HYPER:
2901 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2902 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2903 pMemory += 8;
2904 break;
2905 case FC_DOUBLE:
2906 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2907 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2908 pMemory += sizeof(double);
2909 break;
2910 case FC_RP:
2911 case FC_UP:
2912 case FC_OP:
2913 case FC_FP:
2914 case FC_POINTER:
2916 unsigned char *saved_buffer;
2917 BOOL pointer_buffer_mark_set = FALSE;
2918 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2919 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2920 if (*pFormat != FC_POINTER)
2921 pPointer = pFormat;
2922 if (*pPointer != FC_RP)
2923 align_pointer_clear(&pStubMsg->Buffer, 4);
2924 saved_buffer = pStubMsg->Buffer;
2925 if (pStubMsg->PointerBufferMark)
2927 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2928 pStubMsg->PointerBufferMark = NULL;
2929 pointer_buffer_mark_set = TRUE;
2931 else if (*pPointer != FC_RP)
2932 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2933 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2934 if (pointer_buffer_mark_set)
2936 STD_OVERFLOW_CHECK(pStubMsg);
2937 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2938 pStubMsg->Buffer = saved_buffer;
2939 if (*pPointer != FC_RP)
2940 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2942 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2943 if (*pFormat == FC_POINTER)
2944 pPointer += 4;
2945 else
2946 pFormat += 4;
2947 pMemory += sizeof(void *);
2948 break;
2950 case FC_ALIGNM2:
2951 align_pointer_offset(&pMemory, mem_base, 2);
2952 break;
2953 case FC_ALIGNM4:
2954 align_pointer_offset(&pMemory, mem_base, 4);
2955 break;
2956 case FC_ALIGNM8:
2957 align_pointer_offset(&pMemory, mem_base, 8);
2958 break;
2959 case FC_STRUCTPAD1:
2960 case FC_STRUCTPAD2:
2961 case FC_STRUCTPAD3:
2962 case FC_STRUCTPAD4:
2963 case FC_STRUCTPAD5:
2964 case FC_STRUCTPAD6:
2965 case FC_STRUCTPAD7:
2966 pMemory += *pFormat - FC_STRUCTPAD1 + 1;
2967 break;
2968 case FC_EMBEDDED_COMPLEX:
2969 pMemory += pFormat[1];
2970 pFormat += 2;
2971 desc = pFormat + *(const SHORT*)pFormat;
2972 size = EmbeddedComplexSize(pStubMsg, desc);
2973 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2974 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2975 if (m)
2977 /* for some reason interface pointers aren't generated as
2978 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
2979 * they still need the dereferencing treatment that pointers are
2980 * given */
2981 if (*desc == FC_IP)
2982 m(pStubMsg, *(unsigned char **)pMemory, desc);
2983 else
2984 m(pStubMsg, pMemory, desc);
2986 else FIXME("no marshaller for embedded type %02x\n", *desc);
2987 pMemory += size;
2988 pFormat += 2;
2989 continue;
2990 case FC_PAD:
2991 break;
2992 default:
2993 FIXME("unhandled format 0x%02x\n", *pFormat);
2995 pFormat++;
2998 return pMemory;
3001 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3002 unsigned char *pMemory,
3003 PFORMAT_STRING pFormat,
3004 PFORMAT_STRING pPointer,
3005 unsigned char fMustAlloc)
3007 unsigned char *mem_base = pMemory;
3008 PFORMAT_STRING desc;
3009 NDR_UNMARSHALL m;
3010 ULONG size;
3012 while (*pFormat != FC_END) {
3013 switch (*pFormat) {
3014 case FC_BYTE:
3015 case FC_CHAR:
3016 case FC_SMALL:
3017 case FC_USMALL:
3018 safe_copy_from_buffer(pStubMsg, pMemory, 1);
3019 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
3020 pMemory += 1;
3021 break;
3022 case FC_WCHAR:
3023 case FC_SHORT:
3024 case FC_USHORT:
3025 safe_copy_from_buffer(pStubMsg, pMemory, 2);
3026 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
3027 pMemory += 2;
3028 break;
3029 case FC_ENUM16:
3031 WORD val;
3032 safe_copy_from_buffer(pStubMsg, &val, 2);
3033 *(DWORD*)pMemory = val;
3034 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
3035 if (32767 < *(DWORD*)pMemory)
3036 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3037 pMemory += 4;
3038 break;
3040 case FC_LONG:
3041 case FC_ULONG:
3042 case FC_ENUM32:
3043 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3044 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3045 pMemory += 4;
3046 break;
3047 case FC_INT3264:
3049 INT val;
3050 safe_copy_from_buffer(pStubMsg, &val, 4);
3051 *(INT_PTR *)pMemory = val;
3052 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3053 pMemory += sizeof(INT_PTR);
3054 break;
3056 case FC_UINT3264:
3058 UINT val;
3059 safe_copy_from_buffer(pStubMsg, &val, 4);
3060 *(UINT_PTR *)pMemory = val;
3061 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3062 pMemory += sizeof(UINT_PTR);
3063 break;
3065 case FC_FLOAT:
3066 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3067 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3068 pMemory += sizeof(float);
3069 break;
3070 case FC_HYPER:
3071 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3072 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3073 pMemory += 8;
3074 break;
3075 case FC_DOUBLE:
3076 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3077 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3078 pMemory += sizeof(double);
3079 break;
3080 case FC_RP:
3081 case FC_UP:
3082 case FC_OP:
3083 case FC_FP:
3084 case FC_POINTER:
3086 unsigned char *saved_buffer;
3087 BOOL pointer_buffer_mark_set = FALSE;
3088 TRACE("pointer => %p\n", pMemory);
3089 if (*pFormat != FC_POINTER)
3090 pPointer = pFormat;
3091 if (*pPointer != FC_RP)
3092 align_pointer(&pStubMsg->Buffer, 4);
3093 saved_buffer = pStubMsg->Buffer;
3094 if (pStubMsg->PointerBufferMark)
3096 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3097 pStubMsg->PointerBufferMark = NULL;
3098 pointer_buffer_mark_set = TRUE;
3100 else if (*pPointer != FC_RP)
3101 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3103 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3104 if (pointer_buffer_mark_set)
3106 STD_OVERFLOW_CHECK(pStubMsg);
3107 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3108 pStubMsg->Buffer = saved_buffer;
3109 if (*pPointer != FC_RP)
3110 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3112 if (*pFormat == FC_POINTER)
3113 pPointer += 4;
3114 else
3115 pFormat += 4;
3116 pMemory += sizeof(void *);
3117 break;
3119 case FC_ALIGNM2:
3120 align_pointer_offset_clear(&pMemory, mem_base, 2);
3121 break;
3122 case FC_ALIGNM4:
3123 align_pointer_offset_clear(&pMemory, mem_base, 4);
3124 break;
3125 case FC_ALIGNM8:
3126 align_pointer_offset_clear(&pMemory, mem_base, 8);
3127 break;
3128 case FC_STRUCTPAD1:
3129 case FC_STRUCTPAD2:
3130 case FC_STRUCTPAD3:
3131 case FC_STRUCTPAD4:
3132 case FC_STRUCTPAD5:
3133 case FC_STRUCTPAD6:
3134 case FC_STRUCTPAD7:
3135 memset(pMemory, 0, *pFormat - FC_STRUCTPAD1 + 1);
3136 pMemory += *pFormat - FC_STRUCTPAD1 + 1;
3137 break;
3138 case FC_EMBEDDED_COMPLEX:
3139 pMemory += pFormat[1];
3140 pFormat += 2;
3141 desc = pFormat + *(const SHORT*)pFormat;
3142 size = EmbeddedComplexSize(pStubMsg, desc);
3143 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3144 if (fMustAlloc)
3145 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3146 * since the type is part of the memory block that is encompassed by
3147 * the whole complex type. Memory is forced to allocate when pointers
3148 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3149 * clearing the memory we pass in to the unmarshaller */
3150 memset(pMemory, 0, size);
3151 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3152 if (m)
3154 /* for some reason interface pointers aren't generated as
3155 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3156 * they still need the dereferencing treatment that pointers are
3157 * given */
3158 if (*desc == FC_IP)
3159 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3160 else
3161 m(pStubMsg, &pMemory, desc, FALSE);
3163 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3164 pMemory += size;
3165 pFormat += 2;
3166 continue;
3167 case FC_PAD:
3168 break;
3169 default:
3170 FIXME("unhandled format %d\n", *pFormat);
3172 pFormat++;
3175 return pMemory;
3178 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3179 unsigned char *pMemory,
3180 PFORMAT_STRING pFormat,
3181 PFORMAT_STRING pPointer)
3183 unsigned char *mem_base = pMemory;
3184 PFORMAT_STRING desc;
3185 NDR_BUFFERSIZE m;
3186 ULONG size;
3188 while (*pFormat != FC_END) {
3189 switch (*pFormat) {
3190 case FC_BYTE:
3191 case FC_CHAR:
3192 case FC_SMALL:
3193 case FC_USMALL:
3194 safe_buffer_length_increment(pStubMsg, 1);
3195 pMemory += 1;
3196 break;
3197 case FC_WCHAR:
3198 case FC_SHORT:
3199 case FC_USHORT:
3200 safe_buffer_length_increment(pStubMsg, 2);
3201 pMemory += 2;
3202 break;
3203 case FC_ENUM16:
3204 safe_buffer_length_increment(pStubMsg, 2);
3205 pMemory += 4;
3206 break;
3207 case FC_LONG:
3208 case FC_ULONG:
3209 case FC_ENUM32:
3210 case FC_FLOAT:
3211 safe_buffer_length_increment(pStubMsg, 4);
3212 pMemory += 4;
3213 break;
3214 case FC_INT3264:
3215 case FC_UINT3264:
3216 safe_buffer_length_increment(pStubMsg, 4);
3217 pMemory += sizeof(INT_PTR);
3218 break;
3219 case FC_HYPER:
3220 case FC_DOUBLE:
3221 safe_buffer_length_increment(pStubMsg, 8);
3222 pMemory += 8;
3223 break;
3224 case FC_RP:
3225 case FC_UP:
3226 case FC_OP:
3227 case FC_FP:
3228 case FC_POINTER:
3229 if (*pFormat != FC_POINTER)
3230 pPointer = pFormat;
3231 if (!pStubMsg->IgnoreEmbeddedPointers)
3233 int saved_buffer_length = pStubMsg->BufferLength;
3234 pStubMsg->BufferLength = pStubMsg->PointerLength;
3235 pStubMsg->PointerLength = 0;
3236 if(!pStubMsg->BufferLength)
3237 ERR("BufferLength == 0??\n");
3238 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3239 pStubMsg->PointerLength = pStubMsg->BufferLength;
3240 pStubMsg->BufferLength = saved_buffer_length;
3242 if (*pPointer != FC_RP)
3244 align_length(&pStubMsg->BufferLength, 4);
3245 safe_buffer_length_increment(pStubMsg, 4);
3247 if (*pFormat == FC_POINTER)
3248 pPointer += 4;
3249 else
3250 pFormat += 4;
3251 pMemory += sizeof(void*);
3252 break;
3253 case FC_ALIGNM2:
3254 align_pointer_offset(&pMemory, mem_base, 2);
3255 break;
3256 case FC_ALIGNM4:
3257 align_pointer_offset(&pMemory, mem_base, 4);
3258 break;
3259 case FC_ALIGNM8:
3260 align_pointer_offset(&pMemory, mem_base, 8);
3261 break;
3262 case FC_STRUCTPAD1:
3263 case FC_STRUCTPAD2:
3264 case FC_STRUCTPAD3:
3265 case FC_STRUCTPAD4:
3266 case FC_STRUCTPAD5:
3267 case FC_STRUCTPAD6:
3268 case FC_STRUCTPAD7:
3269 pMemory += *pFormat - FC_STRUCTPAD1 + 1;
3270 break;
3271 case FC_EMBEDDED_COMPLEX:
3272 pMemory += pFormat[1];
3273 pFormat += 2;
3274 desc = pFormat + *(const SHORT*)pFormat;
3275 size = EmbeddedComplexSize(pStubMsg, desc);
3276 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3277 if (m)
3279 /* for some reason interface pointers aren't generated as
3280 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3281 * they still need the dereferencing treatment that pointers are
3282 * given */
3283 if (*desc == FC_IP)
3284 m(pStubMsg, *(unsigned char **)pMemory, desc);
3285 else
3286 m(pStubMsg, pMemory, desc);
3288 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3289 pMemory += size;
3290 pFormat += 2;
3291 continue;
3292 case FC_PAD:
3293 break;
3294 default:
3295 FIXME("unhandled format 0x%02x\n", *pFormat);
3297 pFormat++;
3300 return pMemory;
3303 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3304 unsigned char *pMemory,
3305 PFORMAT_STRING pFormat,
3306 PFORMAT_STRING pPointer)
3308 unsigned char *mem_base = pMemory;
3309 PFORMAT_STRING desc;
3310 NDR_FREE m;
3311 ULONG size;
3313 while (*pFormat != FC_END) {
3314 switch (*pFormat) {
3315 case FC_BYTE:
3316 case FC_CHAR:
3317 case FC_SMALL:
3318 case FC_USMALL:
3319 pMemory += 1;
3320 break;
3321 case FC_WCHAR:
3322 case FC_SHORT:
3323 case FC_USHORT:
3324 pMemory += 2;
3325 break;
3326 case FC_LONG:
3327 case FC_ULONG:
3328 case FC_ENUM16:
3329 case FC_ENUM32:
3330 case FC_FLOAT:
3331 pMemory += 4;
3332 break;
3333 case FC_INT3264:
3334 case FC_UINT3264:
3335 pMemory += sizeof(INT_PTR);
3336 break;
3337 case FC_HYPER:
3338 case FC_DOUBLE:
3339 pMemory += 8;
3340 break;
3341 case FC_RP:
3342 case FC_UP:
3343 case FC_OP:
3344 case FC_FP:
3345 case FC_POINTER:
3346 if (*pFormat != FC_POINTER)
3347 pPointer = pFormat;
3348 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3349 if (*pFormat == FC_POINTER)
3350 pPointer += 4;
3351 else
3352 pFormat += 4;
3353 pMemory += sizeof(void *);
3354 break;
3355 case FC_ALIGNM2:
3356 align_pointer_offset(&pMemory, mem_base, 2);
3357 break;
3358 case FC_ALIGNM4:
3359 align_pointer_offset(&pMemory, mem_base, 4);
3360 break;
3361 case FC_ALIGNM8:
3362 align_pointer_offset(&pMemory, mem_base, 8);
3363 break;
3364 case FC_STRUCTPAD1:
3365 case FC_STRUCTPAD2:
3366 case FC_STRUCTPAD3:
3367 case FC_STRUCTPAD4:
3368 case FC_STRUCTPAD5:
3369 case FC_STRUCTPAD6:
3370 case FC_STRUCTPAD7:
3371 pMemory += *pFormat - FC_STRUCTPAD1 + 1;
3372 break;
3373 case FC_EMBEDDED_COMPLEX:
3374 pMemory += pFormat[1];
3375 pFormat += 2;
3376 desc = pFormat + *(const SHORT*)pFormat;
3377 size = EmbeddedComplexSize(pStubMsg, desc);
3378 m = NdrFreer[*desc & NDR_TABLE_MASK];
3379 if (m)
3381 /* for some reason interface pointers aren't generated as
3382 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3383 * they still need the dereferencing treatment that pointers are
3384 * given */
3385 if (*desc == FC_IP)
3386 m(pStubMsg, *(unsigned char **)pMemory, desc);
3387 else
3388 m(pStubMsg, pMemory, desc);
3390 pMemory += size;
3391 pFormat += 2;
3392 continue;
3393 case FC_PAD:
3394 break;
3395 default:
3396 FIXME("unhandled format 0x%02x\n", *pFormat);
3398 pFormat++;
3401 return pMemory;
3404 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3405 PFORMAT_STRING pFormat,
3406 PFORMAT_STRING pPointer)
3408 PFORMAT_STRING desc;
3409 ULONG size = 0;
3411 while (*pFormat != FC_END) {
3412 switch (*pFormat) {
3413 case FC_BYTE:
3414 case FC_CHAR:
3415 case FC_SMALL:
3416 case FC_USMALL:
3417 size += 1;
3418 safe_buffer_increment(pStubMsg, 1);
3419 break;
3420 case FC_WCHAR:
3421 case FC_SHORT:
3422 case FC_USHORT:
3423 size += 2;
3424 safe_buffer_increment(pStubMsg, 2);
3425 break;
3426 case FC_ENUM16:
3427 size += 4;
3428 safe_buffer_increment(pStubMsg, 2);
3429 break;
3430 case FC_LONG:
3431 case FC_ULONG:
3432 case FC_ENUM32:
3433 case FC_FLOAT:
3434 size += 4;
3435 safe_buffer_increment(pStubMsg, 4);
3436 break;
3437 case FC_INT3264:
3438 case FC_UINT3264:
3439 size += sizeof(INT_PTR);
3440 safe_buffer_increment(pStubMsg, 4);
3441 break;
3442 case FC_HYPER:
3443 case FC_DOUBLE:
3444 size += 8;
3445 safe_buffer_increment(pStubMsg, 8);
3446 break;
3447 case FC_RP:
3448 case FC_UP:
3449 case FC_OP:
3450 case FC_FP:
3451 case FC_POINTER:
3453 unsigned char *saved_buffer;
3454 BOOL pointer_buffer_mark_set = FALSE;
3455 if (*pFormat != FC_POINTER)
3456 pPointer = pFormat;
3457 if (*pPointer != FC_RP)
3458 align_pointer(&pStubMsg->Buffer, 4);
3459 saved_buffer = pStubMsg->Buffer;
3460 if (pStubMsg->PointerBufferMark)
3462 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3463 pStubMsg->PointerBufferMark = NULL;
3464 pointer_buffer_mark_set = TRUE;
3466 else if (*pPointer != FC_RP)
3467 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3469 if (!pStubMsg->IgnoreEmbeddedPointers)
3470 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3471 if (pointer_buffer_mark_set)
3473 STD_OVERFLOW_CHECK(pStubMsg);
3474 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3475 pStubMsg->Buffer = saved_buffer;
3476 if (*pPointer != FC_RP)
3477 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3479 if (*pFormat == FC_POINTER)
3480 pPointer += 4;
3481 else
3482 pFormat += 4;
3483 size += sizeof(void *);
3484 break;
3486 case FC_ALIGNM2:
3487 align_length(&size, 2);
3488 break;
3489 case FC_ALIGNM4:
3490 align_length(&size, 4);
3491 break;
3492 case FC_ALIGNM8:
3493 align_length(&size, 8);
3494 break;
3495 case FC_STRUCTPAD1:
3496 case FC_STRUCTPAD2:
3497 case FC_STRUCTPAD3:
3498 case FC_STRUCTPAD4:
3499 case FC_STRUCTPAD5:
3500 case FC_STRUCTPAD6:
3501 case FC_STRUCTPAD7:
3502 size += *pFormat - FC_STRUCTPAD1 + 1;
3503 break;
3504 case FC_EMBEDDED_COMPLEX:
3505 size += pFormat[1];
3506 pFormat += 2;
3507 desc = pFormat + *(const SHORT*)pFormat;
3508 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3509 pFormat += 2;
3510 continue;
3511 case FC_PAD:
3512 break;
3513 default:
3514 FIXME("unhandled format 0x%02x\n", *pFormat);
3516 pFormat++;
3519 return size;
3522 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3524 PFORMAT_STRING desc;
3525 ULONG size = 0;
3527 while (*pFormat != FC_END) {
3528 switch (*pFormat) {
3529 case FC_BYTE:
3530 case FC_CHAR:
3531 case FC_SMALL:
3532 case FC_USMALL:
3533 size += 1;
3534 break;
3535 case FC_WCHAR:
3536 case FC_SHORT:
3537 case FC_USHORT:
3538 size += 2;
3539 break;
3540 case FC_LONG:
3541 case FC_ULONG:
3542 case FC_ENUM16:
3543 case FC_ENUM32:
3544 case FC_FLOAT:
3545 size += 4;
3546 break;
3547 case FC_INT3264:
3548 case FC_UINT3264:
3549 size += sizeof(INT_PTR);
3550 break;
3551 case FC_HYPER:
3552 case FC_DOUBLE:
3553 size += 8;
3554 break;
3555 case FC_RP:
3556 case FC_UP:
3557 case FC_OP:
3558 case FC_FP:
3559 case FC_POINTER:
3560 size += sizeof(void *);
3561 if (*pFormat != FC_POINTER)
3562 pFormat += 4;
3563 break;
3564 case FC_ALIGNM2:
3565 align_length(&size, 2);
3566 break;
3567 case FC_ALIGNM4:
3568 align_length(&size, 4);
3569 break;
3570 case FC_ALIGNM8:
3571 align_length(&size, 8);
3572 break;
3573 case FC_STRUCTPAD1:
3574 case FC_STRUCTPAD2:
3575 case FC_STRUCTPAD3:
3576 case FC_STRUCTPAD4:
3577 case FC_STRUCTPAD5:
3578 case FC_STRUCTPAD6:
3579 case FC_STRUCTPAD7:
3580 size += *pFormat - FC_STRUCTPAD1 + 1;
3581 break;
3582 case FC_EMBEDDED_COMPLEX:
3583 size += pFormat[1];
3584 pFormat += 2;
3585 desc = pFormat + *(const SHORT*)pFormat;
3586 size += EmbeddedComplexSize(pStubMsg, desc);
3587 pFormat += 2;
3588 continue;
3589 case FC_PAD:
3590 break;
3591 default:
3592 FIXME("unhandled format 0x%02x\n", *pFormat);
3594 pFormat++;
3597 return size;
3600 /***********************************************************************
3601 * NdrComplexStructMarshall [RPCRT4.@]
3603 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3604 unsigned char *pMemory,
3605 PFORMAT_STRING pFormat)
3607 PFORMAT_STRING conf_array = NULL;
3608 PFORMAT_STRING pointer_desc = NULL;
3609 unsigned char *OldMemory = pStubMsg->Memory;
3610 BOOL pointer_buffer_mark_set = FALSE;
3611 ULONG count = 0;
3612 ULONG max_count = 0;
3613 ULONG offset = 0;
3615 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3617 if (!pStubMsg->PointerBufferMark)
3619 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3620 /* save buffer length */
3621 ULONG saved_buffer_length = pStubMsg->BufferLength;
3623 /* get the buffer pointer after complex array data, but before
3624 * pointer data */
3625 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3626 pStubMsg->IgnoreEmbeddedPointers = 1;
3627 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3628 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3630 /* save it for use by embedded pointer code later */
3631 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3632 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3633 pointer_buffer_mark_set = TRUE;
3635 /* restore the original buffer length */
3636 pStubMsg->BufferLength = saved_buffer_length;
3639 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3641 pFormat += 4;
3642 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3643 pFormat += 2;
3644 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3645 pFormat += 2;
3647 pStubMsg->Memory = pMemory;
3649 if (conf_array)
3651 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3652 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3653 pMemory + struct_size, conf_array);
3654 /* these could be changed in ComplexMarshall so save them for later */
3655 max_count = pStubMsg->MaxCount;
3656 count = pStubMsg->ActualCount;
3657 offset = pStubMsg->Offset;
3660 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3662 if (conf_array)
3664 pStubMsg->MaxCount = max_count;
3665 pStubMsg->ActualCount = count;
3666 pStubMsg->Offset = offset;
3667 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3668 conf_array, TRUE /* fHasPointers */);
3671 pStubMsg->Memory = OldMemory;
3673 if (pointer_buffer_mark_set)
3675 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3676 pStubMsg->PointerBufferMark = NULL;
3679 STD_OVERFLOW_CHECK(pStubMsg);
3681 return NULL;
3684 /***********************************************************************
3685 * NdrComplexStructUnmarshall [RPCRT4.@]
3687 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3688 unsigned char **ppMemory,
3689 PFORMAT_STRING pFormat,
3690 unsigned char fMustAlloc)
3692 unsigned size = *(const WORD*)(pFormat+2);
3693 PFORMAT_STRING conf_array = NULL;
3694 PFORMAT_STRING pointer_desc = NULL;
3695 unsigned char *pMemory;
3696 BOOL pointer_buffer_mark_set = FALSE;
3697 ULONG count = 0;
3698 ULONG max_count = 0;
3699 ULONG offset = 0;
3700 ULONG array_size = 0;
3702 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3704 if (!pStubMsg->PointerBufferMark)
3706 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3707 /* save buffer pointer */
3708 unsigned char *saved_buffer = pStubMsg->Buffer;
3710 /* get the buffer pointer after complex array data, but before
3711 * pointer data */
3712 pStubMsg->IgnoreEmbeddedPointers = 1;
3713 NdrComplexStructMemorySize(pStubMsg, pFormat);
3714 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3716 /* save it for use by embedded pointer code later */
3717 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3718 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3719 pointer_buffer_mark_set = TRUE;
3721 /* restore the original buffer */
3722 pStubMsg->Buffer = saved_buffer;
3725 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3727 pFormat += 4;
3728 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3729 pFormat += 2;
3730 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3731 pFormat += 2;
3733 if (conf_array)
3735 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3736 size += array_size;
3738 /* these could be changed in ComplexMarshall so save them for later */
3739 max_count = pStubMsg->MaxCount;
3740 count = pStubMsg->ActualCount;
3741 offset = pStubMsg->Offset;
3744 if (!fMustAlloc && !*ppMemory)
3745 fMustAlloc = TRUE;
3746 if (fMustAlloc)
3747 *ppMemory = NdrAllocateZero(pStubMsg, size);
3749 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3751 if (conf_array)
3753 pStubMsg->MaxCount = max_count;
3754 pStubMsg->ActualCount = count;
3755 pStubMsg->Offset = offset;
3756 if (fMustAlloc)
3757 memset(pMemory, 0, array_size);
3758 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3759 conf_array, FALSE,
3760 FALSE /* fUseBufferMemoryServer */,
3761 TRUE /* fUnmarshall */);
3764 if (pointer_buffer_mark_set)
3766 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3767 pStubMsg->PointerBufferMark = NULL;
3770 return NULL;
3773 /***********************************************************************
3774 * NdrComplexStructBufferSize [RPCRT4.@]
3776 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3777 unsigned char *pMemory,
3778 PFORMAT_STRING pFormat)
3780 PFORMAT_STRING conf_array = NULL;
3781 PFORMAT_STRING pointer_desc = NULL;
3782 unsigned char *OldMemory = pStubMsg->Memory;
3783 int pointer_length_set = 0;
3784 ULONG count = 0;
3785 ULONG max_count = 0;
3786 ULONG offset = 0;
3788 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3790 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3792 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3794 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3795 ULONG saved_buffer_length = pStubMsg->BufferLength;
3797 /* get the buffer length after complex struct data, but before
3798 * pointer data */
3799 pStubMsg->IgnoreEmbeddedPointers = 1;
3800 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3801 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3803 /* save it for use by embedded pointer code later */
3804 pStubMsg->PointerLength = pStubMsg->BufferLength;
3805 pointer_length_set = 1;
3806 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3808 /* restore the original buffer length */
3809 pStubMsg->BufferLength = saved_buffer_length;
3812 pFormat += 4;
3813 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3814 pFormat += 2;
3815 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3816 pFormat += 2;
3818 pStubMsg->Memory = pMemory;
3820 if (conf_array)
3822 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3823 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3824 conf_array);
3826 /* these could be changed in ComplexMarshall so save them for later */
3827 max_count = pStubMsg->MaxCount;
3828 count = pStubMsg->ActualCount;
3829 offset = pStubMsg->Offset;
3832 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3834 if (conf_array)
3836 pStubMsg->MaxCount = max_count;
3837 pStubMsg->ActualCount = count;
3838 pStubMsg->Offset = offset;
3839 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3840 TRUE /* fHasPointers */);
3843 pStubMsg->Memory = OldMemory;
3845 if(pointer_length_set)
3847 pStubMsg->BufferLength = pStubMsg->PointerLength;
3848 pStubMsg->PointerLength = 0;
3853 /***********************************************************************
3854 * NdrComplexStructMemorySize [RPCRT4.@]
3856 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3857 PFORMAT_STRING pFormat)
3859 unsigned size = *(const WORD*)(pFormat+2);
3860 PFORMAT_STRING conf_array = NULL;
3861 PFORMAT_STRING pointer_desc = NULL;
3862 ULONG count = 0;
3863 ULONG max_count = 0;
3864 ULONG offset = 0;
3866 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3868 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3870 pFormat += 4;
3871 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3872 pFormat += 2;
3873 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3874 pFormat += 2;
3876 if (conf_array)
3878 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3880 /* these could be changed in ComplexStructMemorySize so save them for
3881 * later */
3882 max_count = pStubMsg->MaxCount;
3883 count = pStubMsg->ActualCount;
3884 offset = pStubMsg->Offset;
3887 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3889 if (conf_array)
3891 pStubMsg->MaxCount = max_count;
3892 pStubMsg->ActualCount = count;
3893 pStubMsg->Offset = offset;
3894 array_memory_size(conf_array[0], pStubMsg, conf_array,
3895 TRUE /* fHasPointers */);
3898 return size;
3901 /***********************************************************************
3902 * NdrComplexStructFree [RPCRT4.@]
3904 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3905 unsigned char *pMemory,
3906 PFORMAT_STRING pFormat)
3908 PFORMAT_STRING conf_array = NULL;
3909 PFORMAT_STRING pointer_desc = NULL;
3910 unsigned char *OldMemory = pStubMsg->Memory;
3912 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3914 pFormat += 4;
3915 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3916 pFormat += 2;
3917 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3918 pFormat += 2;
3920 pStubMsg->Memory = pMemory;
3922 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3924 if (conf_array)
3925 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3926 TRUE /* fHasPointers */);
3928 pStubMsg->Memory = OldMemory;
3931 /***********************************************************************
3932 * NdrConformantArrayMarshall [RPCRT4.@]
3934 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3935 unsigned char *pMemory,
3936 PFORMAT_STRING pFormat)
3938 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3939 if (pFormat[0] != FC_CARRAY)
3941 ERR("invalid format = 0x%x\n", pFormat[0]);
3942 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3945 array_compute_and_write_conformance(FC_CARRAY, pStubMsg, pMemory,
3946 pFormat);
3947 array_write_variance_and_marshall(FC_CARRAY, pStubMsg, pMemory, pFormat,
3948 TRUE /* fHasPointers */);
3950 return NULL;
3953 /***********************************************************************
3954 * NdrConformantArrayUnmarshall [RPCRT4.@]
3956 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3957 unsigned char **ppMemory,
3958 PFORMAT_STRING pFormat,
3959 unsigned char fMustAlloc)
3961 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3962 if (pFormat[0] != FC_CARRAY)
3964 ERR("invalid format = 0x%x\n", pFormat[0]);
3965 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3968 array_read_conformance(FC_CARRAY, pStubMsg, pFormat);
3969 array_read_variance_and_unmarshall(FC_CARRAY, pStubMsg, ppMemory, pFormat,
3970 fMustAlloc,
3971 TRUE /* fUseBufferMemoryServer */,
3972 TRUE /* fUnmarshall */);
3974 return NULL;
3977 /***********************************************************************
3978 * NdrConformantArrayBufferSize [RPCRT4.@]
3980 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3981 unsigned char *pMemory,
3982 PFORMAT_STRING pFormat)
3984 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3985 if (pFormat[0] != FC_CARRAY)
3987 ERR("invalid format = 0x%x\n", pFormat[0]);
3988 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3991 array_compute_and_size_conformance(FC_CARRAY, pStubMsg, pMemory, pFormat);
3992 array_buffer_size(FC_CARRAY, pStubMsg, pMemory, pFormat,
3993 TRUE /* fHasPointers */);
3996 /***********************************************************************
3997 * NdrConformantArrayMemorySize [RPCRT4.@]
3999 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4000 PFORMAT_STRING pFormat)
4002 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4003 if (pFormat[0] != FC_CARRAY)
4005 ERR("invalid format = 0x%x\n", pFormat[0]);
4006 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4009 array_read_conformance(FC_CARRAY, pStubMsg, pFormat);
4010 array_memory_size(FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4012 return pStubMsg->MemorySize;
4015 /***********************************************************************
4016 * NdrConformantArrayFree [RPCRT4.@]
4018 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4019 unsigned char *pMemory,
4020 PFORMAT_STRING pFormat)
4022 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4023 if (pFormat[0] != FC_CARRAY)
4025 ERR("invalid format = 0x%x\n", pFormat[0]);
4026 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4029 array_free(FC_CARRAY, pStubMsg, pMemory, pFormat,
4030 TRUE /* fHasPointers */);
4034 /***********************************************************************
4035 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4037 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
4038 unsigned char* pMemory,
4039 PFORMAT_STRING pFormat )
4041 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4043 if (pFormat[0] != FC_CVARRAY)
4045 ERR("invalid format type %x\n", pFormat[0]);
4046 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4047 return NULL;
4050 array_compute_and_write_conformance(FC_CVARRAY, pStubMsg, pMemory,
4051 pFormat);
4052 array_write_variance_and_marshall(FC_CVARRAY, pStubMsg, pMemory,
4053 pFormat, TRUE /* fHasPointers */);
4055 return NULL;
4059 /***********************************************************************
4060 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4062 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4063 unsigned char** ppMemory,
4064 PFORMAT_STRING pFormat,
4065 unsigned char fMustAlloc )
4067 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4069 if (pFormat[0] != FC_CVARRAY)
4071 ERR("invalid format type %x\n", pFormat[0]);
4072 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4073 return NULL;
4076 array_read_conformance(FC_CVARRAY, pStubMsg, pFormat);
4077 array_read_variance_and_unmarshall(FC_CVARRAY, pStubMsg, ppMemory,
4078 pFormat, fMustAlloc,
4079 TRUE /* fUseBufferMemoryServer */,
4080 TRUE /* fUnmarshall */);
4082 return NULL;
4086 /***********************************************************************
4087 * NdrConformantVaryingArrayFree [RPCRT4.@]
4089 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4090 unsigned char* pMemory,
4091 PFORMAT_STRING pFormat )
4093 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4095 if (pFormat[0] != FC_CVARRAY)
4097 ERR("invalid format type %x\n", pFormat[0]);
4098 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4099 return;
4102 array_free(FC_CVARRAY, pStubMsg, pMemory, pFormat,
4103 TRUE /* fHasPointers */);
4107 /***********************************************************************
4108 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4110 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4111 unsigned char* pMemory, PFORMAT_STRING pFormat )
4113 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4115 if (pFormat[0] != FC_CVARRAY)
4117 ERR("invalid format type %x\n", pFormat[0]);
4118 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4119 return;
4122 array_compute_and_size_conformance(FC_CVARRAY, pStubMsg, pMemory,
4123 pFormat);
4124 array_buffer_size(FC_CVARRAY, pStubMsg, pMemory, pFormat,
4125 TRUE /* fHasPointers */);
4129 /***********************************************************************
4130 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4132 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4133 PFORMAT_STRING pFormat )
4135 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4137 if (pFormat[0] != FC_CVARRAY)
4139 ERR("invalid format type %x\n", pFormat[0]);
4140 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4141 return pStubMsg->MemorySize;
4144 array_read_conformance(FC_CVARRAY, pStubMsg, pFormat);
4145 array_memory_size(FC_CVARRAY, pStubMsg, pFormat,
4146 TRUE /* fHasPointers */);
4148 return pStubMsg->MemorySize;
4152 /***********************************************************************
4153 * NdrComplexArrayMarshall [RPCRT4.@]
4155 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4156 unsigned char *pMemory,
4157 PFORMAT_STRING pFormat)
4159 BOOL pointer_buffer_mark_set = FALSE;
4161 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4163 if (pFormat[0] != FC_BOGUS_ARRAY)
4165 ERR("invalid format type %x\n", pFormat[0]);
4166 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4167 return NULL;
4170 if (!pStubMsg->PointerBufferMark)
4172 /* save buffer fields that may be changed by buffer sizer functions
4173 * and that may be needed later on */
4174 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4175 ULONG saved_buffer_length = pStubMsg->BufferLength;
4176 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4177 ULONG saved_offset = pStubMsg->Offset;
4178 ULONG saved_actual_count = pStubMsg->ActualCount;
4180 /* get the buffer pointer after complex array data, but before
4181 * pointer data */
4182 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4183 pStubMsg->IgnoreEmbeddedPointers = 1;
4184 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4185 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4187 /* save it for use by embedded pointer code later */
4188 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4189 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4190 pointer_buffer_mark_set = TRUE;
4192 /* restore fields */
4193 pStubMsg->ActualCount = saved_actual_count;
4194 pStubMsg->Offset = saved_offset;
4195 pStubMsg->MaxCount = saved_max_count;
4196 pStubMsg->BufferLength = saved_buffer_length;
4199 array_compute_and_write_conformance(FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4200 array_write_variance_and_marshall(FC_BOGUS_ARRAY, pStubMsg,
4201 pMemory, pFormat, TRUE /* fHasPointers */);
4203 STD_OVERFLOW_CHECK(pStubMsg);
4205 if (pointer_buffer_mark_set)
4207 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4208 pStubMsg->PointerBufferMark = NULL;
4211 return NULL;
4214 /***********************************************************************
4215 * NdrComplexArrayUnmarshall [RPCRT4.@]
4217 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4218 unsigned char **ppMemory,
4219 PFORMAT_STRING pFormat,
4220 unsigned char fMustAlloc)
4222 unsigned char *saved_buffer;
4223 BOOL pointer_buffer_mark_set = FALSE;
4224 int saved_ignore_embedded;
4226 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4228 if (pFormat[0] != FC_BOGUS_ARRAY)
4230 ERR("invalid format type %x\n", pFormat[0]);
4231 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4232 return NULL;
4235 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4236 /* save buffer pointer */
4237 saved_buffer = pStubMsg->Buffer;
4238 /* get the buffer pointer after complex array data, but before
4239 * pointer data */
4240 pStubMsg->IgnoreEmbeddedPointers = 1;
4241 pStubMsg->MemorySize = 0;
4242 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4243 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4245 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4246 if (!pStubMsg->PointerBufferMark)
4248 /* save it for use by embedded pointer code later */
4249 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4250 pointer_buffer_mark_set = TRUE;
4252 /* restore the original buffer */
4253 pStubMsg->Buffer = saved_buffer;
4255 array_read_conformance(FC_BOGUS_ARRAY, pStubMsg, pFormat);
4256 array_read_variance_and_unmarshall(FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4257 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4259 if (pointer_buffer_mark_set)
4261 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4262 pStubMsg->PointerBufferMark = NULL;
4265 return NULL;
4268 /***********************************************************************
4269 * NdrComplexArrayBufferSize [RPCRT4.@]
4271 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4272 unsigned char *pMemory,
4273 PFORMAT_STRING pFormat)
4275 int pointer_length_set = 0;
4277 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4279 if (pFormat[0] != FC_BOGUS_ARRAY)
4281 ERR("invalid format type %x\n", pFormat[0]);
4282 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4283 return;
4286 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4288 /* save buffer fields that may be changed by buffer sizer functions
4289 * and that may be needed later on */
4290 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4291 ULONG saved_buffer_length = pStubMsg->BufferLength;
4292 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4293 ULONG saved_offset = pStubMsg->Offset;
4294 ULONG saved_actual_count = pStubMsg->ActualCount;
4296 /* get the buffer pointer after complex array data, but before
4297 * pointer data */
4298 pStubMsg->IgnoreEmbeddedPointers = 1;
4299 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4300 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4302 /* save it for use by embedded pointer code later */
4303 pStubMsg->PointerLength = pStubMsg->BufferLength;
4304 pointer_length_set = 1;
4306 /* restore fields */
4307 pStubMsg->ActualCount = saved_actual_count;
4308 pStubMsg->Offset = saved_offset;
4309 pStubMsg->MaxCount = saved_max_count;
4310 pStubMsg->BufferLength = saved_buffer_length;
4313 array_compute_and_size_conformance(FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4314 array_buffer_size(FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4316 if(pointer_length_set)
4318 pStubMsg->BufferLength = pStubMsg->PointerLength;
4319 pStubMsg->PointerLength = 0;
4323 /***********************************************************************
4324 * NdrComplexArrayMemorySize [RPCRT4.@]
4326 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4327 PFORMAT_STRING pFormat)
4329 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4331 if (pFormat[0] != FC_BOGUS_ARRAY)
4333 ERR("invalid format type %x\n", pFormat[0]);
4334 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4335 return 0;
4338 array_read_conformance(FC_BOGUS_ARRAY, pStubMsg, pFormat);
4339 array_memory_size(FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4340 return pStubMsg->MemorySize;
4343 /***********************************************************************
4344 * NdrComplexArrayFree [RPCRT4.@]
4346 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4347 unsigned char *pMemory,
4348 PFORMAT_STRING pFormat)
4350 ULONG i, count, def;
4352 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4354 if (pFormat[0] != FC_BOGUS_ARRAY)
4356 ERR("invalid format type %x\n", pFormat[0]);
4357 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4358 return;
4361 def = *(const WORD*)&pFormat[2];
4362 pFormat += 4;
4364 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4365 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4367 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4368 TRACE("variance = %d\n", pStubMsg->ActualCount);
4370 count = pStubMsg->ActualCount;
4371 for (i = 0; i < count; i++)
4372 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4375 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4376 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4377 USER_MARSHAL_CB *umcb)
4379 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4380 pStubMsg->RpcMsg->DataRepresentation);
4381 umcb->pStubMsg = pStubMsg;
4382 umcb->pReserve = NULL;
4383 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4384 umcb->CBType = cbtype;
4385 umcb->pFormat = pFormat;
4386 umcb->pTypeFormat = NULL /* FIXME */;
4389 #define USER_MARSHAL_PTR_PREFIX \
4390 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4391 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4393 /***********************************************************************
4394 * NdrUserMarshalMarshall [RPCRT4.@]
4396 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4397 unsigned char *pMemory,
4398 PFORMAT_STRING pFormat)
4400 unsigned flags = pFormat[1];
4401 unsigned index = *(const WORD*)&pFormat[2];
4402 unsigned char *saved_buffer = NULL;
4403 USER_MARSHAL_CB umcb;
4405 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4406 TRACE("index=%d\n", index);
4408 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4410 if (flags & USER_MARSHAL_POINTER)
4412 align_pointer_clear(&pStubMsg->Buffer, 4);
4413 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4414 pStubMsg->Buffer += 4;
4415 if (pStubMsg->PointerBufferMark)
4417 saved_buffer = pStubMsg->Buffer;
4418 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4419 pStubMsg->PointerBufferMark = NULL;
4421 align_pointer_clear(&pStubMsg->Buffer, 8);
4423 else
4424 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4426 pStubMsg->Buffer =
4427 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4428 &umcb.Flags, pStubMsg->Buffer, pMemory);
4430 if (saved_buffer)
4432 STD_OVERFLOW_CHECK(pStubMsg);
4433 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4434 pStubMsg->Buffer = saved_buffer;
4437 STD_OVERFLOW_CHECK(pStubMsg);
4439 return NULL;
4442 /***********************************************************************
4443 * NdrUserMarshalUnmarshall [RPCRT4.@]
4445 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4446 unsigned char **ppMemory,
4447 PFORMAT_STRING pFormat,
4448 unsigned char fMustAlloc)
4450 unsigned flags = pFormat[1];
4451 unsigned index = *(const WORD*)&pFormat[2];
4452 DWORD memsize = *(const WORD*)&pFormat[4];
4453 unsigned char *saved_buffer = NULL;
4454 USER_MARSHAL_CB umcb;
4456 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4457 TRACE("index=%d\n", index);
4459 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4461 if (flags & USER_MARSHAL_POINTER)
4463 align_pointer(&pStubMsg->Buffer, 4);
4464 /* skip pointer prefix */
4465 pStubMsg->Buffer += 4;
4466 if (pStubMsg->PointerBufferMark)
4468 saved_buffer = pStubMsg->Buffer;
4469 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4470 pStubMsg->PointerBufferMark = NULL;
4472 align_pointer(&pStubMsg->Buffer, 8);
4474 else
4475 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4477 if (!fMustAlloc && !*ppMemory)
4478 fMustAlloc = TRUE;
4479 if (fMustAlloc)
4481 *ppMemory = NdrAllocate(pStubMsg, memsize);
4482 memset(*ppMemory, 0, memsize);
4485 pStubMsg->Buffer =
4486 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4487 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4489 if (saved_buffer)
4491 STD_OVERFLOW_CHECK(pStubMsg);
4492 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4493 pStubMsg->Buffer = saved_buffer;
4496 return NULL;
4499 /***********************************************************************
4500 * NdrUserMarshalBufferSize [RPCRT4.@]
4502 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4503 unsigned char *pMemory,
4504 PFORMAT_STRING pFormat)
4506 unsigned flags = pFormat[1];
4507 unsigned index = *(const WORD*)&pFormat[2];
4508 DWORD bufsize = *(const WORD*)&pFormat[6];
4509 USER_MARSHAL_CB umcb;
4510 ULONG saved_buffer_length = 0;
4512 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4513 TRACE("index=%d\n", index);
4515 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4517 if (flags & USER_MARSHAL_POINTER)
4519 align_length(&pStubMsg->BufferLength, 4);
4520 /* skip pointer prefix */
4521 safe_buffer_length_increment(pStubMsg, 4);
4522 if (pStubMsg->IgnoreEmbeddedPointers)
4523 return;
4524 if (pStubMsg->PointerLength)
4526 saved_buffer_length = pStubMsg->BufferLength;
4527 pStubMsg->BufferLength = pStubMsg->PointerLength;
4528 pStubMsg->PointerLength = 0;
4530 align_length(&pStubMsg->BufferLength, 8);
4532 else
4533 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4535 if (bufsize) {
4536 TRACE("size=%d\n", bufsize);
4537 safe_buffer_length_increment(pStubMsg, bufsize);
4539 else
4540 pStubMsg->BufferLength =
4541 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4542 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4544 if (saved_buffer_length)
4546 pStubMsg->PointerLength = pStubMsg->BufferLength;
4547 pStubMsg->BufferLength = saved_buffer_length;
4552 /***********************************************************************
4553 * NdrUserMarshalMemorySize [RPCRT4.@]
4555 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4556 PFORMAT_STRING pFormat)
4558 unsigned flags = pFormat[1];
4559 unsigned index = *(const WORD*)&pFormat[2];
4560 DWORD memsize = *(const WORD*)&pFormat[4];
4561 DWORD bufsize = *(const WORD*)&pFormat[6];
4563 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4564 TRACE("index=%d\n", index);
4566 pStubMsg->MemorySize += memsize;
4568 if (flags & USER_MARSHAL_POINTER)
4570 align_pointer(&pStubMsg->Buffer, 4);
4571 /* skip pointer prefix */
4572 pStubMsg->Buffer += 4;
4573 if (pStubMsg->IgnoreEmbeddedPointers)
4574 return pStubMsg->MemorySize;
4575 align_pointer(&pStubMsg->Buffer, 8);
4577 else
4578 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4580 if (!bufsize)
4581 FIXME("not implemented for varying buffer size\n");
4583 pStubMsg->Buffer += bufsize;
4585 return pStubMsg->MemorySize;
4588 /***********************************************************************
4589 * NdrUserMarshalFree [RPCRT4.@]
4591 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4592 unsigned char *pMemory,
4593 PFORMAT_STRING pFormat)
4595 /* unsigned flags = pFormat[1]; */
4596 unsigned index = *(const WORD*)&pFormat[2];
4597 USER_MARSHAL_CB umcb;
4599 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4600 TRACE("index=%d\n", index);
4602 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4604 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4605 &umcb.Flags, pMemory);
4608 /***********************************************************************
4609 * NdrGetUserMarshalInfo [RPCRT4.@]
4611 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4613 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4615 TRACE("(%p,%u,%p)\n", flags, level, umi);
4617 if (level != 1)
4618 return RPC_S_INVALID_ARG;
4620 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4621 umi->InformationLevel = level;
4623 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4624 return RPC_S_INVALID_ARG;
4626 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4627 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4628 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4630 switch (umcb->CBType)
4632 case USER_MARSHAL_CB_MARSHALL:
4633 case USER_MARSHAL_CB_UNMARSHALL:
4635 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4636 unsigned char *buffer_start = msg->Buffer;
4637 unsigned char *buffer_end =
4638 (unsigned char *)msg->Buffer + msg->BufferLength;
4640 if (umcb->pStubMsg->Buffer < buffer_start ||
4641 umcb->pStubMsg->Buffer > buffer_end)
4642 return RPC_X_INVALID_BUFFER;
4644 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4645 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4646 break;
4648 case USER_MARSHAL_CB_BUFFER_SIZE:
4649 case USER_MARSHAL_CB_FREE:
4650 break;
4651 default:
4652 WARN("unrecognised CBType %d\n", umcb->CBType);
4655 return RPC_S_OK;
4658 /***********************************************************************
4659 * NdrClearOutParameters [RPCRT4.@]
4661 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4662 PFORMAT_STRING pFormat,
4663 void *ArgAddr)
4665 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4668 /***********************************************************************
4669 * NdrConvert [RPCRT4.@]
4671 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4673 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4674 /* FIXME: since this stub doesn't do any converting, the proper behavior
4675 is to raise an exception */
4678 /***********************************************************************
4679 * NdrConvert2 [RPCRT4.@]
4681 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4683 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4684 pStubMsg, pFormat, NumberParams);
4685 /* FIXME: since this stub doesn't do any converting, the proper behavior
4686 is to raise an exception */
4689 #include "pshpack1.h"
4690 typedef struct _NDR_CSTRUCT_FORMAT
4692 unsigned char type;
4693 unsigned char alignment;
4694 unsigned short memory_size;
4695 short offset_to_array_description;
4696 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4697 #include "poppack.h"
4699 /***********************************************************************
4700 * NdrConformantStructMarshall [RPCRT4.@]
4702 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4703 unsigned char *pMemory,
4704 PFORMAT_STRING pFormat)
4706 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4707 PFORMAT_STRING pCArrayFormat;
4708 ULONG esize, bufsize;
4710 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4712 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4713 if ((pCStructFormat->type != FC_CPSTRUCT) && (pCStructFormat->type != FC_CSTRUCT))
4715 ERR("invalid format type %x\n", pCStructFormat->type);
4716 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4717 return NULL;
4720 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4721 pCStructFormat->offset_to_array_description;
4722 if (*pCArrayFormat != FC_CARRAY)
4724 ERR("invalid array format type %x\n", pCStructFormat->type);
4725 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4726 return NULL;
4728 esize = *(const WORD*)(pCArrayFormat+2);
4730 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4731 pCArrayFormat + 4, 0);
4733 WriteConformance(pStubMsg);
4735 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4737 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4739 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4740 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4742 ERR("integer overflow of memory_size %u with bufsize %u\n",
4743 pCStructFormat->memory_size, bufsize);
4744 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4746 /* copy constant sized part of struct */
4747 pStubMsg->BufferMark = pStubMsg->Buffer;
4748 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4750 if (pCStructFormat->type == FC_CPSTRUCT)
4751 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4753 return NULL;
4756 /***********************************************************************
4757 * NdrConformantStructUnmarshall [RPCRT4.@]
4759 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4760 unsigned char **ppMemory,
4761 PFORMAT_STRING pFormat,
4762 unsigned char fMustAlloc)
4764 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4765 PFORMAT_STRING pCArrayFormat;
4766 ULONG esize, bufsize;
4767 unsigned char *saved_buffer;
4769 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4771 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4772 if ((pCStructFormat->type != FC_CPSTRUCT) && (pCStructFormat->type != FC_CSTRUCT))
4774 ERR("invalid format type %x\n", pCStructFormat->type);
4775 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4776 return NULL;
4778 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4779 pCStructFormat->offset_to_array_description;
4780 if (*pCArrayFormat != FC_CARRAY)
4782 ERR("invalid array format type %x\n", pCStructFormat->type);
4783 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4784 return NULL;
4786 esize = *(const WORD*)(pCArrayFormat+2);
4788 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4790 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4792 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4794 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4795 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4797 ERR("integer overflow of memory_size %u with bufsize %u\n",
4798 pCStructFormat->memory_size, bufsize);
4799 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4802 if (fMustAlloc)
4804 SIZE_T size = pCStructFormat->memory_size + bufsize;
4805 *ppMemory = NdrAllocateZero(pStubMsg, size);
4807 else
4809 if (!pStubMsg->IsClient && !*ppMemory)
4810 /* for servers, we just point straight into the RPC buffer */
4811 *ppMemory = pStubMsg->Buffer;
4814 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4815 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4816 if (pCStructFormat->type == FC_CPSTRUCT)
4817 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4819 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4820 if (*ppMemory != saved_buffer)
4821 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4823 return NULL;
4826 /***********************************************************************
4827 * NdrConformantStructBufferSize [RPCRT4.@]
4829 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4830 unsigned char *pMemory,
4831 PFORMAT_STRING pFormat)
4833 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4834 PFORMAT_STRING pCArrayFormat;
4835 ULONG esize;
4837 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4839 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4840 if ((pCStructFormat->type != FC_CPSTRUCT) && (pCStructFormat->type != FC_CSTRUCT))
4842 ERR("invalid format type %x\n", pCStructFormat->type);
4843 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4844 return;
4846 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4847 pCStructFormat->offset_to_array_description;
4848 if (*pCArrayFormat != FC_CARRAY)
4850 ERR("invalid array format type %x\n", pCStructFormat->type);
4851 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4852 return;
4854 esize = *(const WORD*)(pCArrayFormat+2);
4856 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4857 SizeConformance(pStubMsg);
4859 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4861 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4863 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4864 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4866 if (pCStructFormat->type == FC_CPSTRUCT)
4867 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4870 /***********************************************************************
4871 * NdrConformantStructMemorySize [RPCRT4.@]
4873 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4874 PFORMAT_STRING pFormat)
4876 FIXME("stub\n");
4877 return 0;
4880 /***********************************************************************
4881 * NdrConformantStructFree [RPCRT4.@]
4883 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4884 unsigned char *pMemory,
4885 PFORMAT_STRING pFormat)
4887 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4888 PFORMAT_STRING pCArrayFormat;
4890 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4892 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4893 if ((pCStructFormat->type != FC_CPSTRUCT) && (pCStructFormat->type != FC_CSTRUCT))
4895 ERR("invalid format type %x\n", pCStructFormat->type);
4896 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4897 return;
4900 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4901 pCStructFormat->offset_to_array_description;
4902 if (*pCArrayFormat != FC_CARRAY)
4904 ERR("invalid array format type %x\n", pCStructFormat->type);
4905 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4906 return;
4909 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4910 pCArrayFormat + 4, 0);
4912 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4914 /* copy constant sized part of struct */
4915 pStubMsg->BufferMark = pStubMsg->Buffer;
4917 if (pCStructFormat->type == FC_CPSTRUCT)
4918 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4921 /***********************************************************************
4922 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4924 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4925 unsigned char *pMemory,
4926 PFORMAT_STRING pFormat)
4928 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4929 PFORMAT_STRING pCVArrayFormat;
4931 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4933 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4934 if (pCVStructFormat->type != FC_CVSTRUCT)
4936 ERR("invalid format type %x\n", pCVStructFormat->type);
4937 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4938 return NULL;
4941 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4942 pCVStructFormat->offset_to_array_description;
4944 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4945 pMemory + pCVStructFormat->memory_size,
4946 pCVArrayFormat);
4948 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4950 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4952 /* write constant sized part */
4953 pStubMsg->BufferMark = pStubMsg->Buffer;
4954 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4956 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4957 pMemory + pCVStructFormat->memory_size,
4958 pCVArrayFormat, FALSE /* fHasPointers */);
4960 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4962 return NULL;
4965 /***********************************************************************
4966 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4968 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4969 unsigned char **ppMemory,
4970 PFORMAT_STRING pFormat,
4971 unsigned char fMustAlloc)
4973 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4974 PFORMAT_STRING pCVArrayFormat;
4975 ULONG memsize, bufsize;
4976 unsigned char *saved_buffer, *saved_array_buffer;
4977 ULONG offset;
4978 unsigned char *array_memory;
4980 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4982 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4983 if (pCVStructFormat->type != FC_CVSTRUCT)
4985 ERR("invalid format type %x\n", pCVStructFormat->type);
4986 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4987 return NULL;
4990 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4991 pCVStructFormat->offset_to_array_description;
4993 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4994 pCVArrayFormat);
4996 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4998 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5000 /* work out how much memory to allocate if we need to do so */
5001 if (!fMustAlloc && !*ppMemory)
5002 fMustAlloc = TRUE;
5003 if (fMustAlloc)
5005 SIZE_T size = pCVStructFormat->memory_size + memsize;
5006 *ppMemory = NdrAllocateZero(pStubMsg, size);
5009 /* mark the start of the constant data */
5010 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5011 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5013 array_memory = *ppMemory + pCVStructFormat->memory_size;
5014 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
5015 &array_memory, pCVArrayFormat,
5016 FALSE /* fMustAlloc */,
5017 FALSE /* fUseServerBufferMemory */,
5018 FALSE /* fUnmarshall */);
5020 /* save offset in case unmarshalling pointers changes it */
5021 offset = pStubMsg->Offset;
5023 /* mark the start of the array data */
5024 saved_array_buffer = pStubMsg->Buffer;
5025 safe_buffer_increment(pStubMsg, bufsize);
5027 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5029 /* copy the constant data */
5030 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
5031 /* copy the array data */
5032 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
5033 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
5034 saved_array_buffer, bufsize);
5036 if (*pCVArrayFormat == FC_C_CSTRING)
5037 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5038 else if (*pCVArrayFormat == FC_C_WSTRING)
5039 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5041 return NULL;
5044 /***********************************************************************
5045 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5047 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5048 unsigned char *pMemory,
5049 PFORMAT_STRING pFormat)
5051 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5052 PFORMAT_STRING pCVArrayFormat;
5054 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5056 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5057 if (pCVStructFormat->type != FC_CVSTRUCT)
5059 ERR("invalid format type %x\n", pCVStructFormat->type);
5060 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5061 return;
5064 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5065 pCVStructFormat->offset_to_array_description;
5066 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5067 pMemory + pCVStructFormat->memory_size,
5068 pCVArrayFormat);
5070 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5072 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5074 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5076 array_buffer_size(*pCVArrayFormat, pStubMsg,
5077 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5078 FALSE /* fHasPointers */);
5080 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5083 /***********************************************************************
5084 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5086 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5087 PFORMAT_STRING pFormat)
5089 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5090 PFORMAT_STRING pCVArrayFormat;
5092 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5094 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5095 if (pCVStructFormat->type != FC_CVSTRUCT)
5097 ERR("invalid format type %x\n", pCVStructFormat->type);
5098 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5099 return 0;
5102 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5103 pCVStructFormat->offset_to_array_description;
5104 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5106 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5108 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5110 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5111 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5112 FALSE /* fHasPointers */);
5114 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5116 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5118 return pStubMsg->MemorySize;
5121 /***********************************************************************
5122 * NdrConformantVaryingStructFree [RPCRT4.@]
5124 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5125 unsigned char *pMemory,
5126 PFORMAT_STRING pFormat)
5128 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5129 PFORMAT_STRING pCVArrayFormat;
5131 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5133 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5134 if (pCVStructFormat->type != FC_CVSTRUCT)
5136 ERR("invalid format type %x\n", pCVStructFormat->type);
5137 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5138 return;
5141 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5142 pCVStructFormat->offset_to_array_description;
5143 array_free(*pCVArrayFormat, pStubMsg,
5144 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5145 FALSE /* fHasPointers */);
5147 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5149 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5152 #include "pshpack1.h"
5153 typedef struct
5155 unsigned char type;
5156 unsigned char alignment;
5157 unsigned short total_size;
5158 } NDR_SMFARRAY_FORMAT;
5160 typedef struct
5162 unsigned char type;
5163 unsigned char alignment;
5164 ULONG total_size;
5165 } NDR_LGFARRAY_FORMAT;
5166 #include "poppack.h"
5168 /***********************************************************************
5169 * NdrFixedArrayMarshall [RPCRT4.@]
5171 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5172 unsigned char *pMemory,
5173 PFORMAT_STRING pFormat)
5175 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5176 ULONG total_size;
5178 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5180 if ((pSmFArrayFormat->type != FC_SMFARRAY) &&
5181 (pSmFArrayFormat->type != FC_LGFARRAY))
5183 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5184 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5185 return NULL;
5188 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5190 if (pSmFArrayFormat->type == FC_SMFARRAY)
5192 total_size = pSmFArrayFormat->total_size;
5193 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5195 else
5197 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5198 total_size = pLgFArrayFormat->total_size;
5199 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5202 pStubMsg->BufferMark = pStubMsg->Buffer;
5203 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5205 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5207 return NULL;
5210 /***********************************************************************
5211 * NdrFixedArrayUnmarshall [RPCRT4.@]
5213 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5214 unsigned char **ppMemory,
5215 PFORMAT_STRING pFormat,
5216 unsigned char fMustAlloc)
5218 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5219 ULONG total_size;
5220 unsigned char *saved_buffer;
5222 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5224 if ((pSmFArrayFormat->type != FC_SMFARRAY) &&
5225 (pSmFArrayFormat->type != FC_LGFARRAY))
5227 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5228 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5229 return NULL;
5232 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5234 if (pSmFArrayFormat->type == FC_SMFARRAY)
5236 total_size = pSmFArrayFormat->total_size;
5237 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5239 else
5241 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5242 total_size = pLgFArrayFormat->total_size;
5243 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5246 if (fMustAlloc)
5247 *ppMemory = NdrAllocateZero(pStubMsg, total_size);
5248 else
5250 if (!pStubMsg->IsClient && !*ppMemory)
5251 /* for servers, we just point straight into the RPC buffer */
5252 *ppMemory = pStubMsg->Buffer;
5255 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5256 safe_buffer_increment(pStubMsg, total_size);
5257 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5259 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5260 if (*ppMemory != saved_buffer)
5261 memcpy(*ppMemory, saved_buffer, total_size);
5263 return NULL;
5266 /***********************************************************************
5267 * NdrFixedArrayBufferSize [RPCRT4.@]
5269 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5270 unsigned char *pMemory,
5271 PFORMAT_STRING pFormat)
5273 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5274 ULONG total_size;
5276 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5278 if ((pSmFArrayFormat->type != FC_SMFARRAY) &&
5279 (pSmFArrayFormat->type != FC_LGFARRAY))
5281 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5282 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5283 return;
5286 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5288 if (pSmFArrayFormat->type == FC_SMFARRAY)
5290 total_size = pSmFArrayFormat->total_size;
5291 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5293 else
5295 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5296 total_size = pLgFArrayFormat->total_size;
5297 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5299 safe_buffer_length_increment(pStubMsg, total_size);
5301 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5304 /***********************************************************************
5305 * NdrFixedArrayMemorySize [RPCRT4.@]
5307 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5308 PFORMAT_STRING pFormat)
5310 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5311 ULONG total_size;
5313 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5315 if ((pSmFArrayFormat->type != FC_SMFARRAY) &&
5316 (pSmFArrayFormat->type != FC_LGFARRAY))
5318 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5319 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5320 return 0;
5323 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5325 if (pSmFArrayFormat->type == FC_SMFARRAY)
5327 total_size = pSmFArrayFormat->total_size;
5328 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5330 else
5332 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5333 total_size = pLgFArrayFormat->total_size;
5334 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5336 pStubMsg->BufferMark = pStubMsg->Buffer;
5337 safe_buffer_increment(pStubMsg, total_size);
5338 pStubMsg->MemorySize += total_size;
5340 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5342 return total_size;
5345 /***********************************************************************
5346 * NdrFixedArrayFree [RPCRT4.@]
5348 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5349 unsigned char *pMemory,
5350 PFORMAT_STRING pFormat)
5352 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5354 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5356 if ((pSmFArrayFormat->type != FC_SMFARRAY) &&
5357 (pSmFArrayFormat->type != FC_LGFARRAY))
5359 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5360 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5361 return;
5364 if (pSmFArrayFormat->type == FC_SMFARRAY)
5365 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5366 else
5368 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5369 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5372 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5375 /***********************************************************************
5376 * NdrVaryingArrayMarshall [RPCRT4.@]
5378 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5379 unsigned char *pMemory,
5380 PFORMAT_STRING pFormat)
5382 unsigned char alignment;
5383 DWORD elements, esize;
5384 ULONG bufsize;
5386 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5388 if ((pFormat[0] != FC_SMVARRAY) &&
5389 (pFormat[0] != FC_LGVARRAY))
5391 ERR("invalid format type %x\n", pFormat[0]);
5392 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5393 return NULL;
5396 alignment = pFormat[1] + 1;
5398 if (pFormat[0] == FC_SMVARRAY)
5400 pFormat += 2;
5401 pFormat += sizeof(WORD);
5402 elements = *(const WORD*)pFormat;
5403 pFormat += sizeof(WORD);
5405 else
5407 pFormat += 2;
5408 pFormat += sizeof(DWORD);
5409 elements = *(const DWORD*)pFormat;
5410 pFormat += sizeof(DWORD);
5413 esize = *(const WORD*)pFormat;
5414 pFormat += sizeof(WORD);
5416 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5417 if ((pStubMsg->ActualCount > elements) ||
5418 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5420 RpcRaiseException(RPC_S_INVALID_BOUND);
5421 return NULL;
5424 WriteVariance(pStubMsg);
5426 align_pointer_clear(&pStubMsg->Buffer, alignment);
5428 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5429 pStubMsg->BufferMark = pStubMsg->Buffer;
5430 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5432 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5434 return NULL;
5437 /***********************************************************************
5438 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5440 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5441 unsigned char **ppMemory,
5442 PFORMAT_STRING pFormat,
5443 unsigned char fMustAlloc)
5445 unsigned char alignment;
5446 DWORD size, elements, esize;
5447 ULONG bufsize;
5448 unsigned char *saved_buffer;
5449 ULONG offset;
5451 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5453 if ((pFormat[0] != FC_SMVARRAY) &&
5454 (pFormat[0] != FC_LGVARRAY))
5456 ERR("invalid format type %x\n", pFormat[0]);
5457 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5458 return NULL;
5461 alignment = pFormat[1] + 1;
5463 if (pFormat[0] == FC_SMVARRAY)
5465 pFormat += 2;
5466 size = *(const WORD*)pFormat;
5467 pFormat += sizeof(WORD);
5468 elements = *(const WORD*)pFormat;
5469 pFormat += sizeof(WORD);
5471 else
5473 pFormat += 2;
5474 size = *(const DWORD*)pFormat;
5475 pFormat += sizeof(DWORD);
5476 elements = *(const DWORD*)pFormat;
5477 pFormat += sizeof(DWORD);
5480 esize = *(const WORD*)pFormat;
5481 pFormat += sizeof(WORD);
5483 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5485 align_pointer(&pStubMsg->Buffer, alignment);
5487 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5488 offset = pStubMsg->Offset;
5490 if (!fMustAlloc && !*ppMemory)
5491 fMustAlloc = TRUE;
5492 if (fMustAlloc)
5493 *ppMemory = NdrAllocateZero(pStubMsg, size);
5494 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5495 safe_buffer_increment(pStubMsg, bufsize);
5497 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5499 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5501 return NULL;
5504 /***********************************************************************
5505 * NdrVaryingArrayBufferSize [RPCRT4.@]
5507 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5508 unsigned char *pMemory,
5509 PFORMAT_STRING pFormat)
5511 unsigned char alignment;
5512 DWORD elements, esize;
5514 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5516 if ((pFormat[0] != FC_SMVARRAY) &&
5517 (pFormat[0] != FC_LGVARRAY))
5519 ERR("invalid format type %x\n", pFormat[0]);
5520 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5521 return;
5524 alignment = pFormat[1] + 1;
5526 if (pFormat[0] == FC_SMVARRAY)
5528 pFormat += 2;
5529 pFormat += sizeof(WORD);
5530 elements = *(const WORD*)pFormat;
5531 pFormat += sizeof(WORD);
5533 else
5535 pFormat += 2;
5536 pFormat += sizeof(DWORD);
5537 elements = *(const DWORD*)pFormat;
5538 pFormat += sizeof(DWORD);
5541 esize = *(const WORD*)pFormat;
5542 pFormat += sizeof(WORD);
5544 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5545 if ((pStubMsg->ActualCount > elements) ||
5546 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5548 RpcRaiseException(RPC_S_INVALID_BOUND);
5549 return;
5552 SizeVariance(pStubMsg);
5554 align_length(&pStubMsg->BufferLength, alignment);
5556 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5558 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5561 /***********************************************************************
5562 * NdrVaryingArrayMemorySize [RPCRT4.@]
5564 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5565 PFORMAT_STRING pFormat)
5567 unsigned char alignment;
5568 DWORD size, elements, esize;
5570 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5572 if ((pFormat[0] != FC_SMVARRAY) &&
5573 (pFormat[0] != FC_LGVARRAY))
5575 ERR("invalid format type %x\n", pFormat[0]);
5576 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5577 return 0;
5580 alignment = pFormat[1] + 1;
5582 if (pFormat[0] == FC_SMVARRAY)
5584 pFormat += 2;
5585 size = *(const WORD*)pFormat;
5586 pFormat += sizeof(WORD);
5587 elements = *(const WORD*)pFormat;
5588 pFormat += sizeof(WORD);
5590 else
5592 pFormat += 2;
5593 size = *(const DWORD*)pFormat;
5594 pFormat += sizeof(DWORD);
5595 elements = *(const DWORD*)pFormat;
5596 pFormat += sizeof(DWORD);
5599 esize = *(const WORD*)pFormat;
5600 pFormat += sizeof(WORD);
5602 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5604 align_pointer(&pStubMsg->Buffer, alignment);
5606 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5607 pStubMsg->MemorySize += size;
5609 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5611 return pStubMsg->MemorySize;
5614 /***********************************************************************
5615 * NdrVaryingArrayFree [RPCRT4.@]
5617 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5618 unsigned char *pMemory,
5619 PFORMAT_STRING pFormat)
5621 DWORD elements;
5623 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5625 if ((pFormat[0] != FC_SMVARRAY) &&
5626 (pFormat[0] != FC_LGVARRAY))
5628 ERR("invalid format type %x\n", pFormat[0]);
5629 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5630 return;
5633 if (pFormat[0] == FC_SMVARRAY)
5635 pFormat += 2;
5636 pFormat += sizeof(WORD);
5637 elements = *(const WORD*)pFormat;
5638 pFormat += sizeof(WORD);
5640 else
5642 pFormat += 2;
5643 pFormat += sizeof(DWORD);
5644 elements = *(const DWORD*)pFormat;
5645 pFormat += sizeof(DWORD);
5648 pFormat += sizeof(WORD);
5650 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5651 if ((pStubMsg->ActualCount > elements) ||
5652 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5654 RpcRaiseException(RPC_S_INVALID_BOUND);
5655 return;
5658 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5661 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5663 switch (fc)
5665 case FC_BYTE:
5666 case FC_CHAR:
5667 case FC_SMALL:
5668 case FC_USMALL:
5669 return *pMemory;
5670 case FC_WCHAR:
5671 case FC_SHORT:
5672 case FC_USHORT:
5673 case FC_ENUM16:
5674 return *(const USHORT *)pMemory;
5675 case FC_LONG:
5676 case FC_ULONG:
5677 case FC_ENUM32:
5678 return *(const ULONG *)pMemory;
5679 default:
5680 FIXME("Unhandled base type: 0x%02x\n", fc);
5681 return 0;
5685 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5686 ULONG discriminant,
5687 PFORMAT_STRING pFormat)
5689 unsigned short num_arms, arm, type;
5691 num_arms = *(const SHORT*)pFormat & 0x0fff;
5692 pFormat += 2;
5693 for(arm = 0; arm < num_arms; arm++)
5695 if(discriminant == *(const ULONG*)pFormat)
5697 pFormat += 4;
5698 break;
5700 pFormat += 6;
5703 type = *(const unsigned short*)pFormat;
5704 TRACE("type %04x\n", type);
5705 if(arm == num_arms) /* default arm extras */
5707 if(type == 0xffff)
5709 ERR("no arm for 0x%x and no default case\n", discriminant);
5710 RpcRaiseException(RPC_S_INVALID_TAG);
5711 return NULL;
5713 if(type == 0)
5715 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5716 return NULL;
5719 return pFormat;
5722 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5724 unsigned short type;
5726 pFormat += 2;
5728 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5729 if(!pFormat)
5730 return NULL;
5732 type = *(const unsigned short*)pFormat;
5733 if((type & 0xff00) == 0x8000)
5735 unsigned char basetype = LOBYTE(type);
5736 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5738 else
5740 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5741 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5742 if (m)
5744 unsigned char *saved_buffer = NULL;
5745 BOOL pointer_buffer_mark_set = FALSE;
5746 switch(*desc)
5748 case FC_RP:
5749 case FC_UP:
5750 case FC_OP:
5751 case FC_FP:
5752 align_pointer_clear(&pStubMsg->Buffer, 4);
5753 saved_buffer = pStubMsg->Buffer;
5754 if (pStubMsg->PointerBufferMark)
5756 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5757 pStubMsg->PointerBufferMark = NULL;
5758 pointer_buffer_mark_set = TRUE;
5760 else
5761 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5763 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5764 if (pointer_buffer_mark_set)
5766 STD_OVERFLOW_CHECK(pStubMsg);
5767 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5768 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5770 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5771 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5772 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5774 pStubMsg->Buffer = saved_buffer + 4;
5776 break;
5777 case FC_IP:
5778 /* must be dereferenced first */
5779 m(pStubMsg, *(unsigned char **)pMemory, desc);
5780 break;
5781 default:
5782 m(pStubMsg, pMemory, desc);
5785 else if (*desc)
5786 FIXME("no marshaller for embedded type %02x\n", *desc);
5788 return NULL;
5791 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5792 unsigned char **ppMemory,
5793 ULONG discriminant,
5794 PFORMAT_STRING pFormat,
5795 unsigned char fMustAlloc)
5797 unsigned short type;
5799 pFormat += 2;
5801 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5802 if(!pFormat)
5803 return NULL;
5805 type = *(const unsigned short*)pFormat;
5806 if((type & 0xff00) == 0x8000)
5808 unsigned char basetype = LOBYTE(type);
5809 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5811 else
5813 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5814 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5815 if (m)
5817 unsigned char *saved_buffer = NULL;
5818 BOOL pointer_buffer_mark_set = FALSE;
5819 switch(*desc)
5821 case FC_RP:
5822 case FC_UP:
5823 case FC_OP:
5824 case FC_FP:
5825 align_pointer(&pStubMsg->Buffer, 4);
5826 saved_buffer = pStubMsg->Buffer;
5827 if (pStubMsg->PointerBufferMark)
5829 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5830 pStubMsg->PointerBufferMark = NULL;
5831 pointer_buffer_mark_set = TRUE;
5833 else
5834 pStubMsg->Buffer += 4; /* for pointer ID */
5836 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5838 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5839 saved_buffer, pStubMsg->BufferEnd);
5840 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5843 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5844 if (pointer_buffer_mark_set)
5846 STD_OVERFLOW_CHECK(pStubMsg);
5847 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5848 pStubMsg->Buffer = saved_buffer + 4;
5850 break;
5851 case FC_IP:
5852 /* must be dereferenced first */
5853 m(pStubMsg, *(unsigned char ***)ppMemory, desc, fMustAlloc);
5854 break;
5855 default:
5856 m(pStubMsg, ppMemory, desc, fMustAlloc);
5859 else if (*desc)
5860 FIXME("no marshaller for embedded type %02x\n", *desc);
5862 return NULL;
5865 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5866 unsigned char *pMemory,
5867 ULONG discriminant,
5868 PFORMAT_STRING pFormat)
5870 unsigned short type;
5872 pFormat += 2;
5874 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5875 if(!pFormat)
5876 return;
5878 type = *(const unsigned short*)pFormat;
5879 if((type & 0xff00) == 0x8000)
5881 unsigned char basetype = LOBYTE(type);
5882 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5884 else
5886 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5887 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5888 if (m)
5890 switch(*desc)
5892 case FC_RP:
5893 case FC_UP:
5894 case FC_OP:
5895 case FC_FP:
5896 align_length(&pStubMsg->BufferLength, 4);
5897 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5898 if (!pStubMsg->IgnoreEmbeddedPointers)
5900 int saved_buffer_length = pStubMsg->BufferLength;
5901 pStubMsg->BufferLength = pStubMsg->PointerLength;
5902 pStubMsg->PointerLength = 0;
5903 if(!pStubMsg->BufferLength)
5904 ERR("BufferLength == 0??\n");
5905 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5906 pStubMsg->PointerLength = pStubMsg->BufferLength;
5907 pStubMsg->BufferLength = saved_buffer_length;
5909 break;
5910 case FC_IP:
5911 /* must be dereferenced first */
5912 m(pStubMsg, *(unsigned char **)pMemory, desc);
5913 break;
5914 default:
5915 m(pStubMsg, pMemory, desc);
5918 else if (*desc)
5919 FIXME("no buffersizer for embedded type %02x\n", *desc);
5923 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5924 ULONG discriminant,
5925 PFORMAT_STRING pFormat)
5927 unsigned short type, size;
5929 size = *(const unsigned short*)pFormat;
5930 pStubMsg->Memory += size;
5931 pFormat += 2;
5933 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5934 if(!pFormat)
5935 return 0;
5937 type = *(const unsigned short*)pFormat;
5938 if((type & 0xff00) == 0x8000)
5940 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5942 else
5944 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5945 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5946 unsigned char *saved_buffer;
5947 if (m)
5949 switch(*desc)
5951 case FC_RP:
5952 case FC_UP:
5953 case FC_OP:
5954 case FC_FP:
5955 align_pointer(&pStubMsg->Buffer, 4);
5956 saved_buffer = pStubMsg->Buffer;
5957 safe_buffer_increment(pStubMsg, 4);
5958 align_length(&pStubMsg->MemorySize, sizeof(void *));
5959 pStubMsg->MemorySize += sizeof(void *);
5960 if (!pStubMsg->IgnoreEmbeddedPointers)
5961 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5962 break;
5963 default:
5964 return m(pStubMsg, desc);
5967 else if (*desc)
5968 FIXME("no marshaller for embedded type %02x\n", *desc);
5971 TRACE("size %d\n", size);
5972 return size;
5975 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5976 unsigned char *pMemory,
5977 ULONG discriminant,
5978 PFORMAT_STRING pFormat)
5980 unsigned short type;
5982 pFormat += 2;
5984 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5985 if(!pFormat)
5986 return;
5988 type = *(const unsigned short*)pFormat;
5989 if((type & 0xff00) != 0x8000)
5991 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5992 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5993 if (m)
5995 switch(*desc)
5997 case FC_RP:
5998 case FC_UP:
5999 case FC_OP:
6000 case FC_FP:
6001 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
6002 break;
6003 case FC_IP:
6004 /* must be dereferenced first */
6005 m(pStubMsg, *(unsigned char **)pMemory, desc);
6006 break;
6007 default:
6008 m(pStubMsg, pMemory, desc);
6014 /***********************************************************************
6015 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
6017 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6018 unsigned char *pMemory,
6019 PFORMAT_STRING pFormat)
6021 unsigned char switch_type;
6022 unsigned char increment;
6023 ULONG switch_value;
6025 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6026 pFormat++;
6028 switch_type = *pFormat & 0xf;
6029 increment = (*pFormat & 0xf0) >> 4;
6030 pFormat++;
6032 align_pointer_clear(&pStubMsg->Buffer, increment);
6034 switch_value = get_discriminant(switch_type, pMemory);
6035 TRACE("got switch value 0x%x\n", switch_value);
6037 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
6038 pMemory += increment;
6040 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
6043 /***********************************************************************
6044 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
6046 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6047 unsigned char **ppMemory,
6048 PFORMAT_STRING pFormat,
6049 unsigned char fMustAlloc)
6051 unsigned char switch_type;
6052 unsigned char increment;
6053 ULONG switch_value;
6054 unsigned short size;
6055 unsigned char *pMemoryArm;
6057 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6058 pFormat++;
6060 switch_type = *pFormat & 0xf;
6061 increment = (*pFormat & 0xf0) >> 4;
6062 pFormat++;
6064 align_pointer(&pStubMsg->Buffer, increment);
6065 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6066 TRACE("got switch value 0x%x\n", switch_value);
6068 size = *(const unsigned short*)pFormat + increment;
6069 if (!fMustAlloc && !*ppMemory)
6070 fMustAlloc = TRUE;
6071 if (fMustAlloc)
6072 *ppMemory = NdrAllocate(pStubMsg, size);
6074 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6075 * since the arm is part of the memory block that is encompassed by
6076 * the whole union. Memory is forced to allocate when pointers
6077 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6078 * clearing the memory we pass in to the unmarshaller */
6079 if (fMustAlloc)
6080 memset(*ppMemory, 0, size);
6082 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6083 pMemoryArm = *ppMemory + increment;
6085 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6088 /***********************************************************************
6089 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6091 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6092 unsigned char *pMemory,
6093 PFORMAT_STRING pFormat)
6095 unsigned char switch_type;
6096 unsigned char increment;
6097 ULONG switch_value;
6099 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6100 pFormat++;
6102 switch_type = *pFormat & 0xf;
6103 increment = (*pFormat & 0xf0) >> 4;
6104 pFormat++;
6106 align_length(&pStubMsg->BufferLength, increment);
6107 switch_value = get_discriminant(switch_type, pMemory);
6108 TRACE("got switch value 0x%x\n", switch_value);
6110 /* Add discriminant size */
6111 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6112 pMemory += increment;
6114 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6117 /***********************************************************************
6118 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6120 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6121 PFORMAT_STRING pFormat)
6123 unsigned char switch_type;
6124 unsigned char increment;
6125 ULONG switch_value;
6127 switch_type = *pFormat & 0xf;
6128 increment = (*pFormat & 0xf0) >> 4;
6129 pFormat++;
6131 align_pointer(&pStubMsg->Buffer, increment);
6132 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6133 TRACE("got switch value 0x%x\n", switch_value);
6135 pStubMsg->Memory += increment;
6137 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6140 /***********************************************************************
6141 * NdrEncapsulatedUnionFree [RPCRT4.@]
6143 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6144 unsigned char *pMemory,
6145 PFORMAT_STRING pFormat)
6147 unsigned char switch_type;
6148 unsigned char increment;
6149 ULONG switch_value;
6151 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6152 pFormat++;
6154 switch_type = *pFormat & 0xf;
6155 increment = (*pFormat & 0xf0) >> 4;
6156 pFormat++;
6158 switch_value = get_discriminant(switch_type, pMemory);
6159 TRACE("got switch value 0x%x\n", switch_value);
6161 pMemory += increment;
6163 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6166 /***********************************************************************
6167 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6169 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6170 unsigned char *pMemory,
6171 PFORMAT_STRING pFormat)
6173 unsigned char switch_type;
6175 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6176 pFormat++;
6178 switch_type = *pFormat;
6179 pFormat++;
6181 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6182 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6183 /* Marshall discriminant */
6184 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6186 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6189 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6190 PFORMAT_STRING *ppFormat)
6192 LONG discriminant = 0;
6194 switch(**ppFormat)
6196 case FC_BYTE:
6197 case FC_CHAR:
6198 case FC_SMALL:
6199 case FC_USMALL:
6201 UCHAR d;
6202 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6203 discriminant = d;
6204 break;
6206 case FC_WCHAR:
6207 case FC_SHORT:
6208 case FC_USHORT:
6209 case FC_ENUM16:
6211 USHORT d;
6212 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6213 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6214 discriminant = d;
6215 break;
6217 case FC_LONG:
6218 case FC_ULONG:
6220 ULONG d;
6221 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6222 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6223 discriminant = d;
6224 break;
6226 default:
6227 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6229 (*ppFormat)++;
6231 *ppFormat = SkipConformance(pStubMsg, *ppFormat);
6232 return discriminant;
6235 /**********************************************************************
6236 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6238 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6239 unsigned char **ppMemory,
6240 PFORMAT_STRING pFormat,
6241 unsigned char fMustAlloc)
6243 LONG discriminant;
6244 unsigned short size;
6246 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6247 pFormat++;
6249 /* Unmarshall discriminant */
6250 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6251 TRACE("unmarshalled discriminant %x\n", discriminant);
6253 pFormat += *(const SHORT*)pFormat;
6255 size = *(const unsigned short*)pFormat;
6257 if (!fMustAlloc && !*ppMemory)
6258 fMustAlloc = TRUE;
6259 if (fMustAlloc)
6260 *ppMemory = NdrAllocate(pStubMsg, size);
6262 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6263 * since the arm is part of the memory block that is encompassed by
6264 * the whole union. Memory is forced to allocate when pointers
6265 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6266 * clearing the memory we pass in to the unmarshaller */
6267 if (fMustAlloc)
6268 memset(*ppMemory, 0, size);
6270 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6273 /***********************************************************************
6274 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6276 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6277 unsigned char *pMemory,
6278 PFORMAT_STRING pFormat)
6280 unsigned char switch_type;
6282 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6283 pFormat++;
6285 switch_type = *pFormat;
6286 pFormat++;
6288 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6289 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6290 /* Add discriminant size */
6291 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6293 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6296 /***********************************************************************
6297 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6299 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6300 PFORMAT_STRING pFormat)
6302 ULONG discriminant;
6304 pFormat++;
6305 /* Unmarshall discriminant */
6306 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6307 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6309 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6312 /***********************************************************************
6313 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6315 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6316 unsigned char *pMemory,
6317 PFORMAT_STRING pFormat)
6319 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6320 pFormat++;
6321 pFormat++;
6323 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6324 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6326 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6329 /***********************************************************************
6330 * NdrByteCountPointerMarshall [RPCRT4.@]
6332 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6333 unsigned char *pMemory,
6334 PFORMAT_STRING pFormat)
6336 FIXME("stub\n");
6337 return NULL;
6340 /***********************************************************************
6341 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6343 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6344 unsigned char **ppMemory,
6345 PFORMAT_STRING pFormat,
6346 unsigned char fMustAlloc)
6348 FIXME("stub\n");
6349 return NULL;
6352 /***********************************************************************
6353 * NdrByteCountPointerBufferSize [RPCRT4.@]
6355 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6356 unsigned char *pMemory,
6357 PFORMAT_STRING pFormat)
6359 FIXME("stub\n");
6362 /***********************************************************************
6363 * NdrByteCountPointerMemorySize [internal]
6365 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6366 PFORMAT_STRING pFormat)
6368 FIXME("stub\n");
6369 return 0;
6372 /***********************************************************************
6373 * NdrByteCountPointerFree [RPCRT4.@]
6375 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6376 unsigned char *pMemory,
6377 PFORMAT_STRING pFormat)
6379 FIXME("stub\n");
6382 /***********************************************************************
6383 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6385 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6386 unsigned char *pMemory,
6387 PFORMAT_STRING pFormat)
6389 FIXME("stub\n");
6390 return NULL;
6393 /***********************************************************************
6394 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6396 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6397 unsigned char **ppMemory,
6398 PFORMAT_STRING pFormat,
6399 unsigned char fMustAlloc)
6401 FIXME("stub\n");
6402 return NULL;
6405 /***********************************************************************
6406 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6408 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6409 unsigned char *pMemory,
6410 PFORMAT_STRING pFormat)
6412 FIXME("stub\n");
6415 /***********************************************************************
6416 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6418 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6419 PFORMAT_STRING pFormat)
6421 FIXME("stub\n");
6422 return 0;
6425 /***********************************************************************
6426 * NdrXmitOrRepAsFree [RPCRT4.@]
6428 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6429 unsigned char *pMemory,
6430 PFORMAT_STRING pFormat)
6432 FIXME("stub\n");
6435 /***********************************************************************
6436 * NdrRangeMarshall [internal]
6438 static unsigned char *WINAPI NdrRangeMarshall(
6439 PMIDL_STUB_MESSAGE pStubMsg,
6440 unsigned char *pMemory,
6441 PFORMAT_STRING pFormat)
6443 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6444 unsigned char base_type;
6446 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6448 if (pRange->type != FC_RANGE)
6450 ERR("invalid format type %x\n", pRange->type);
6451 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6452 return NULL;
6455 base_type = pRange->flags_type & 0xf;
6457 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6460 /***********************************************************************
6461 * NdrRangeUnmarshall [RPCRT4.@]
6463 unsigned char *WINAPI NdrRangeUnmarshall(
6464 PMIDL_STUB_MESSAGE pStubMsg,
6465 unsigned char **ppMemory,
6466 PFORMAT_STRING pFormat,
6467 unsigned char fMustAlloc)
6469 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6470 unsigned char base_type;
6472 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6474 if (pRange->type != FC_RANGE)
6476 ERR("invalid format type %x\n", pRange->type);
6477 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6478 return NULL;
6480 base_type = pRange->flags_type & 0xf;
6482 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6483 base_type, pRange->low_value, pRange->high_value);
6485 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6486 do \
6488 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6489 if (!fMustAlloc && !*ppMemory) \
6490 fMustAlloc = TRUE; \
6491 if (fMustAlloc) \
6492 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6493 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6495 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6496 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6497 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6499 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6500 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6502 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6503 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6504 (mem_type)pRange->high_value); \
6505 RpcRaiseException(RPC_S_INVALID_BOUND); \
6506 return NULL; \
6508 TRACE("*ppMemory: %p\n", *ppMemory); \
6509 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6510 pStubMsg->Buffer += sizeof(wire_type); \
6511 } while (0)
6513 switch(base_type)
6515 case FC_CHAR:
6516 case FC_SMALL:
6517 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6518 TRACE("value: 0x%02x\n", **ppMemory);
6519 break;
6520 case FC_BYTE:
6521 case FC_USMALL:
6522 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6523 TRACE("value: 0x%02x\n", **ppMemory);
6524 break;
6525 case FC_WCHAR: /* FIXME: valid? */
6526 case FC_USHORT:
6527 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6528 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6529 break;
6530 case FC_SHORT:
6531 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6532 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6533 break;
6534 case FC_LONG:
6535 case FC_ENUM32:
6536 RANGE_UNMARSHALL(LONG, LONG, "%d");
6537 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6538 break;
6539 case FC_ULONG:
6540 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6541 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6542 break;
6543 case FC_ENUM16:
6544 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6545 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6546 break;
6547 case FC_FLOAT:
6548 case FC_DOUBLE:
6549 case FC_HYPER:
6550 default:
6551 ERR("invalid range base type: 0x%02x\n", base_type);
6552 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6555 return NULL;
6558 /***********************************************************************
6559 * NdrRangeBufferSize [internal]
6561 static void WINAPI NdrRangeBufferSize(
6562 PMIDL_STUB_MESSAGE pStubMsg,
6563 unsigned char *pMemory,
6564 PFORMAT_STRING pFormat)
6566 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6567 unsigned char base_type;
6569 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6571 if (pRange->type != FC_RANGE)
6573 ERR("invalid format type %x\n", pRange->type);
6574 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6576 base_type = pRange->flags_type & 0xf;
6578 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6581 /***********************************************************************
6582 * NdrRangeMemorySize [internal]
6584 static ULONG WINAPI NdrRangeMemorySize(
6585 PMIDL_STUB_MESSAGE pStubMsg,
6586 PFORMAT_STRING pFormat)
6588 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6589 unsigned char base_type;
6591 if (pRange->type != FC_RANGE)
6593 ERR("invalid format type %x\n", pRange->type);
6594 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6595 return 0;
6597 base_type = pRange->flags_type & 0xf;
6599 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6602 /***********************************************************************
6603 * NdrRangeFree [internal]
6605 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6606 unsigned char *pMemory,
6607 PFORMAT_STRING pFormat)
6609 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6611 /* nothing to do */
6614 /***********************************************************************
6615 * NdrBaseTypeMarshall [internal]
6617 static unsigned char *WINAPI NdrBaseTypeMarshall(
6618 PMIDL_STUB_MESSAGE pStubMsg,
6619 unsigned char *pMemory,
6620 PFORMAT_STRING pFormat)
6622 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6624 switch(*pFormat)
6626 case FC_BYTE:
6627 case FC_CHAR:
6628 case FC_SMALL:
6629 case FC_USMALL:
6630 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6631 TRACE("value: 0x%02x\n", *pMemory);
6632 break;
6633 case FC_WCHAR:
6634 case FC_SHORT:
6635 case FC_USHORT:
6636 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6637 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6638 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6639 break;
6640 case FC_LONG:
6641 case FC_ULONG:
6642 case FC_ERROR_STATUS_T:
6643 case FC_ENUM32:
6644 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6645 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6646 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6647 break;
6648 case FC_FLOAT:
6649 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6650 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6651 break;
6652 case FC_DOUBLE:
6653 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6654 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6655 break;
6656 case FC_HYPER:
6657 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6658 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6659 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6660 break;
6661 case FC_ENUM16:
6663 USHORT val = *(UINT *)pMemory;
6664 /* only 16-bits on the wire, so do a sanity check */
6665 if (*(UINT *)pMemory > SHRT_MAX)
6666 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6667 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6668 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6669 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6670 break;
6672 case FC_INT3264:
6673 case FC_UINT3264:
6675 UINT val = *(UINT_PTR *)pMemory;
6676 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6677 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6678 break;
6680 case FC_IGNORE:
6681 break;
6682 default:
6683 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6686 /* FIXME: what is the correct return value? */
6687 return NULL;
6690 /***********************************************************************
6691 * NdrBaseTypeUnmarshall [internal]
6693 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6694 PMIDL_STUB_MESSAGE pStubMsg,
6695 unsigned char **ppMemory,
6696 PFORMAT_STRING pFormat,
6697 unsigned char fMustAlloc)
6699 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6701 #define BASE_TYPE_UNMARSHALL(type) do { \
6702 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6703 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6705 *ppMemory = pStubMsg->Buffer; \
6706 TRACE("*ppMemory: %p\n", *ppMemory); \
6707 safe_buffer_increment(pStubMsg, sizeof(type)); \
6709 else \
6711 if (fMustAlloc) \
6712 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6713 TRACE("*ppMemory: %p\n", *ppMemory); \
6714 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6716 } while (0)
6718 switch(*pFormat)
6720 case FC_BYTE:
6721 case FC_CHAR:
6722 case FC_SMALL:
6723 case FC_USMALL:
6724 BASE_TYPE_UNMARSHALL(UCHAR);
6725 TRACE("value: 0x%02x\n", **ppMemory);
6726 break;
6727 case FC_WCHAR:
6728 case FC_SHORT:
6729 case FC_USHORT:
6730 BASE_TYPE_UNMARSHALL(USHORT);
6731 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6732 break;
6733 case FC_LONG:
6734 case FC_ULONG:
6735 case FC_ERROR_STATUS_T:
6736 case FC_ENUM32:
6737 BASE_TYPE_UNMARSHALL(ULONG);
6738 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6739 break;
6740 case FC_FLOAT:
6741 BASE_TYPE_UNMARSHALL(float);
6742 TRACE("value: %f\n", **(float **)ppMemory);
6743 break;
6744 case FC_DOUBLE:
6745 BASE_TYPE_UNMARSHALL(double);
6746 TRACE("value: %f\n", **(double **)ppMemory);
6747 break;
6748 case FC_HYPER:
6749 BASE_TYPE_UNMARSHALL(ULONGLONG);
6750 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6751 break;
6752 case FC_ENUM16:
6754 USHORT val;
6755 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6756 if (!fMustAlloc && !*ppMemory)
6757 fMustAlloc = TRUE;
6758 if (fMustAlloc)
6759 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6760 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6761 /* 16-bits on the wire, but int in memory */
6762 **(UINT **)ppMemory = val;
6763 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6764 break;
6766 case FC_INT3264:
6767 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6768 else
6770 INT val;
6771 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6772 if (!fMustAlloc && !*ppMemory)
6773 fMustAlloc = TRUE;
6774 if (fMustAlloc)
6775 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6776 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6777 **(INT_PTR **)ppMemory = val;
6778 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6780 break;
6781 case FC_UINT3264:
6782 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6783 else
6785 UINT val;
6786 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6787 if (!fMustAlloc && !*ppMemory)
6788 fMustAlloc = TRUE;
6789 if (fMustAlloc)
6790 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6791 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6792 **(UINT_PTR **)ppMemory = val;
6793 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6795 break;
6796 case FC_IGNORE:
6797 break;
6798 default:
6799 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6801 #undef BASE_TYPE_UNMARSHALL
6803 /* FIXME: what is the correct return value? */
6805 return NULL;
6808 /***********************************************************************
6809 * NdrBaseTypeBufferSize [internal]
6811 static void WINAPI NdrBaseTypeBufferSize(
6812 PMIDL_STUB_MESSAGE pStubMsg,
6813 unsigned char *pMemory,
6814 PFORMAT_STRING pFormat)
6816 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6818 switch(*pFormat)
6820 case FC_BYTE:
6821 case FC_CHAR:
6822 case FC_SMALL:
6823 case FC_USMALL:
6824 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6825 break;
6826 case FC_WCHAR:
6827 case FC_SHORT:
6828 case FC_USHORT:
6829 case FC_ENUM16:
6830 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6831 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6832 break;
6833 case FC_LONG:
6834 case FC_ULONG:
6835 case FC_ENUM32:
6836 case FC_INT3264:
6837 case FC_UINT3264:
6838 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6839 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6840 break;
6841 case FC_FLOAT:
6842 align_length(&pStubMsg->BufferLength, sizeof(float));
6843 safe_buffer_length_increment(pStubMsg, sizeof(float));
6844 break;
6845 case FC_DOUBLE:
6846 align_length(&pStubMsg->BufferLength, sizeof(double));
6847 safe_buffer_length_increment(pStubMsg, sizeof(double));
6848 break;
6849 case FC_HYPER:
6850 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6851 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6852 break;
6853 case FC_ERROR_STATUS_T:
6854 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6855 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6856 break;
6857 case FC_IGNORE:
6858 break;
6859 default:
6860 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6864 /***********************************************************************
6865 * NdrBaseTypeMemorySize [internal]
6867 static ULONG WINAPI NdrBaseTypeMemorySize(
6868 PMIDL_STUB_MESSAGE pStubMsg,
6869 PFORMAT_STRING pFormat)
6871 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6873 switch(*pFormat)
6875 case FC_BYTE:
6876 case FC_CHAR:
6877 case FC_SMALL:
6878 case FC_USMALL:
6879 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6880 pStubMsg->MemorySize += sizeof(UCHAR);
6881 return sizeof(UCHAR);
6882 case FC_WCHAR:
6883 case FC_SHORT:
6884 case FC_USHORT:
6885 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6886 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6887 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6888 pStubMsg->MemorySize += sizeof(USHORT);
6889 return sizeof(USHORT);
6890 case FC_LONG:
6891 case FC_ULONG:
6892 case FC_ENUM32:
6893 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6894 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6895 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6896 pStubMsg->MemorySize += sizeof(ULONG);
6897 return sizeof(ULONG);
6898 case FC_FLOAT:
6899 align_pointer(&pStubMsg->Buffer, sizeof(float));
6900 safe_buffer_increment(pStubMsg, sizeof(float));
6901 align_length(&pStubMsg->MemorySize, sizeof(float));
6902 pStubMsg->MemorySize += sizeof(float);
6903 return sizeof(float);
6904 case FC_DOUBLE:
6905 align_pointer(&pStubMsg->Buffer, sizeof(double));
6906 safe_buffer_increment(pStubMsg, sizeof(double));
6907 align_length(&pStubMsg->MemorySize, sizeof(double));
6908 pStubMsg->MemorySize += sizeof(double);
6909 return sizeof(double);
6910 case FC_HYPER:
6911 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6912 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6913 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6914 pStubMsg->MemorySize += sizeof(ULONGLONG);
6915 return sizeof(ULONGLONG);
6916 case FC_ERROR_STATUS_T:
6917 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6918 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6919 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6920 pStubMsg->MemorySize += sizeof(error_status_t);
6921 return sizeof(error_status_t);
6922 case FC_ENUM16:
6923 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6924 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6925 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6926 pStubMsg->MemorySize += sizeof(UINT);
6927 return sizeof(UINT);
6928 case FC_INT3264:
6929 case FC_UINT3264:
6930 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6931 safe_buffer_increment(pStubMsg, sizeof(UINT));
6932 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6933 pStubMsg->MemorySize += sizeof(UINT_PTR);
6934 return sizeof(UINT_PTR);
6935 case FC_IGNORE:
6936 align_length(&pStubMsg->MemorySize, sizeof(void *));
6937 pStubMsg->MemorySize += sizeof(void *);
6938 return sizeof(void *);
6939 default:
6940 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6941 return 0;
6945 /***********************************************************************
6946 * NdrBaseTypeFree [internal]
6948 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6949 unsigned char *pMemory,
6950 PFORMAT_STRING pFormat)
6952 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6954 /* nothing to do */
6957 /***********************************************************************
6958 * NdrContextHandleBufferSize [internal]
6960 static void WINAPI NdrContextHandleBufferSize(
6961 PMIDL_STUB_MESSAGE pStubMsg,
6962 unsigned char *pMemory,
6963 PFORMAT_STRING pFormat)
6965 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6967 if (*pFormat != FC_BIND_CONTEXT)
6969 ERR("invalid format type %x\n", *pFormat);
6970 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6972 align_length(&pStubMsg->BufferLength, 4);
6973 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6976 /***********************************************************************
6977 * NdrContextHandleMarshall [internal]
6979 static unsigned char *WINAPI NdrContextHandleMarshall(
6980 PMIDL_STUB_MESSAGE pStubMsg,
6981 unsigned char *pMemory,
6982 PFORMAT_STRING pFormat)
6984 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6986 if (*pFormat != FC_BIND_CONTEXT)
6988 ERR("invalid format type %x\n", *pFormat);
6989 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6991 TRACE("flags: 0x%02x\n", pFormat[1]);
6993 if (pStubMsg->IsClient)
6995 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6996 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6997 else
6998 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
7000 else
7002 NDR_SCONTEXT ctxt = CONTAINING_RECORD(pMemory, struct _NDR_SCONTEXT, userContext);
7003 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
7004 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
7007 return NULL;
7010 /***********************************************************************
7011 * NdrContextHandleUnmarshall [internal]
7013 static unsigned char *WINAPI NdrContextHandleUnmarshall(
7014 PMIDL_STUB_MESSAGE pStubMsg,
7015 unsigned char **ppMemory,
7016 PFORMAT_STRING pFormat,
7017 unsigned char fMustAlloc)
7019 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
7020 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
7022 if (*pFormat != FC_BIND_CONTEXT)
7024 ERR("invalid format type %x\n", *pFormat);
7025 RpcRaiseException(RPC_S_INTERNAL_ERROR);
7027 TRACE("flags: 0x%02x\n", pFormat[1]);
7029 if (pStubMsg->IsClient)
7031 NDR_CCONTEXT *ccontext;
7032 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
7033 ccontext = *(NDR_CCONTEXT **)ppMemory;
7034 else
7035 ccontext = (NDR_CCONTEXT *)ppMemory;
7036 /* [out]-only or [ret] param */
7037 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
7038 *ccontext = NULL;
7039 NdrClientContextUnmarshall(pStubMsg, ccontext, pStubMsg->RpcMsg->Handle);
7041 else
7043 NDR_SCONTEXT ctxt;
7044 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
7045 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
7046 *(void **)ppMemory = NDRSContextValue(ctxt);
7047 else
7048 *(void **)ppMemory = *NDRSContextValue(ctxt);
7051 return NULL;
7054 /***********************************************************************
7055 * NdrClientContextMarshall [RPCRT4.@]
7057 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7058 NDR_CCONTEXT ContextHandle,
7059 int fCheck)
7061 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7063 align_pointer_clear(&pStubMsg->Buffer, 4);
7065 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7067 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7068 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7069 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7072 /* FIXME: what does fCheck do? */
7073 NDRCContextMarshall(ContextHandle,
7074 pStubMsg->Buffer);
7076 pStubMsg->Buffer += cbNDRContext;
7079 /***********************************************************************
7080 * NdrClientContextUnmarshall [RPCRT4.@]
7082 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7083 NDR_CCONTEXT * pContextHandle,
7084 RPC_BINDING_HANDLE BindHandle)
7086 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7088 align_pointer(&pStubMsg->Buffer, 4);
7090 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7091 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7093 NDRCContextUnmarshall(pContextHandle,
7094 BindHandle,
7095 pStubMsg->Buffer,
7096 pStubMsg->RpcMsg->DataRepresentation);
7098 pStubMsg->Buffer += cbNDRContext;
7101 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7102 NDR_SCONTEXT ContextHandle,
7103 NDR_RUNDOWN RundownRoutine )
7105 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7107 align_pointer(&pStubMsg->Buffer, 4);
7109 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7111 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7112 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7113 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7116 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7117 pStubMsg->Buffer, RundownRoutine, NULL,
7118 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7119 pStubMsg->Buffer += cbNDRContext;
7122 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7124 NDR_SCONTEXT ContextHandle;
7126 TRACE("(%p)\n", pStubMsg);
7128 align_pointer(&pStubMsg->Buffer, 4);
7130 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7132 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7133 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7134 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7137 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7138 pStubMsg->Buffer,
7139 pStubMsg->RpcMsg->DataRepresentation,
7140 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7141 pStubMsg->Buffer += cbNDRContext;
7143 return ContextHandle;
7146 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7147 unsigned char* pMemory,
7148 PFORMAT_STRING pFormat)
7150 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7153 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7154 PFORMAT_STRING pFormat)
7156 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7157 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7159 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7161 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7162 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7163 if (pFormat[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE)
7164 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7165 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7167 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7168 if_id = &sif->InterfaceId;
7171 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7172 pStubMsg->RpcMsg->DataRepresentation, if_id,
7173 flags);
7176 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7177 NDR_SCONTEXT ContextHandle,
7178 NDR_RUNDOWN RundownRoutine,
7179 PFORMAT_STRING pFormat)
7181 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7182 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7184 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7186 align_pointer(&pStubMsg->Buffer, 4);
7188 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7190 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7191 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7192 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7195 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7196 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7197 if (pFormat[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE)
7198 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7199 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7201 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7202 if_id = &sif->InterfaceId;
7205 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7206 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7207 pStubMsg->Buffer += cbNDRContext;
7210 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7211 PFORMAT_STRING pFormat)
7213 NDR_SCONTEXT ContextHandle;
7214 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7215 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7217 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7219 align_pointer(&pStubMsg->Buffer, 4);
7221 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7223 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7224 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7225 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7228 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7229 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7230 if (pFormat[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE)
7231 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7232 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7234 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7235 if_id = &sif->InterfaceId;
7238 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7239 pStubMsg->Buffer,
7240 pStubMsg->RpcMsg->DataRepresentation,
7241 if_id, flags);
7242 pStubMsg->Buffer += cbNDRContext;
7244 return ContextHandle;
7247 /***********************************************************************
7248 * NdrCorrelationInitialize [RPCRT4.@]
7250 * Initializes correlation validity checking.
7252 * PARAMS
7253 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7254 * pMemory [I] Pointer to memory to use as a cache.
7255 * CacheSize [I] Size of the memory pointed to by pMemory.
7256 * Flags [I] Reserved. Set to zero.
7258 * RETURNS
7259 * Nothing.
7261 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7263 static int once;
7265 if (!once++)
7266 FIXME("(%p, %p, %d, 0x%x): semi-stub\n", pStubMsg, pMemory, CacheSize, Flags);
7268 if (pStubMsg->CorrDespIncrement == 0)
7269 pStubMsg->CorrDespIncrement = 2; /* size of the normal (non-range) /robust payload */
7271 pStubMsg->fHasNewCorrDesc = TRUE;
7274 /***********************************************************************
7275 * NdrCorrelationPass [RPCRT4.@]
7277 * Performs correlation validity checking.
7279 * PARAMS
7280 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7282 * RETURNS
7283 * Nothing.
7285 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7287 FIXME("(%p): stub\n", pStubMsg);
7290 /***********************************************************************
7291 * NdrCorrelationFree [RPCRT4.@]
7293 * Frees any resources used while unmarshalling parameters that need
7294 * correlation validity checking.
7296 * PARAMS
7297 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7299 * RETURNS
7300 * Nothing.
7302 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7304 static int once;
7306 if (!once++)
7307 FIXME("(%p): stub\n", pStubMsg);