libwine: Do not restrict base address of main thread on 64 bit mac os.
[wine.git] / dlls / rpcrt4 / ndr_marshall.c
blob77bbf986ff3d3992bd0099e5dbe3c780a7595d99
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/unicode.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole);
50 #if defined(__i386__)
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
56 #else
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
64 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
65 (MAKELONG( \
66 MAKEWORD(*(pchar), *((pchar)+1)), \
67 MAKEWORD(*((pchar)+2), *((pchar)+3))))
68 #endif
70 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
71 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
72 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
73 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
74 *(pchar) = HIBYTE(HIWORD(uint32)))
76 #define BIG_ENDIAN_UINT32_READ(pchar) \
77 (MAKELONG( \
78 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
79 MAKEWORD(*((pchar)+1), *(pchar))))
81 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
82 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
83 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
84 # define NDR_LOCAL_UINT32_READ(pchar) \
85 BIG_ENDIAN_UINT32_READ(pchar)
86 #else
87 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
88 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
89 # define NDR_LOCAL_UINT32_READ(pchar) \
90 LITTLE_ENDIAN_UINT32_READ(pchar)
91 #endif
93 static inline void align_length( ULONG *len, unsigned int align )
95 *len = (*len + align - 1) & ~(align - 1);
98 static inline void align_pointer( unsigned char **ptr, unsigned int align )
100 ULONG_PTR mask = align - 1;
101 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
104 static inline void align_pointer_clear( unsigned char **ptr, unsigned int align )
106 ULONG_PTR mask = align - 1;
107 memset( *ptr, 0, (align - (ULONG_PTR)*ptr) & mask );
108 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
111 static inline void align_pointer_offset( unsigned char **ptr, unsigned char *base, unsigned int align )
113 ULONG_PTR mask = align - 1;
114 *ptr = base + (((ULONG_PTR)(*ptr - base) + mask) & ~mask);
117 static inline void align_pointer_offset_clear( unsigned char **ptr, unsigned char *base, unsigned int align )
119 ULONG_PTR mask = align - 1;
120 memset( *ptr, 0, (align - (ULONG_PTR)(*ptr - base)) & mask );
121 *ptr = base + (((ULONG_PTR)(*ptr - base) + mask) & ~mask);
124 #define STD_OVERFLOW_CHECK(_Msg) do { \
125 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
126 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
127 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
128 } while (0)
130 #define NDR_POINTER_ID_BASE 0x20000
131 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
132 #define NDR_TABLE_SIZE 128
133 #define NDR_TABLE_MASK 127
135 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
137 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
138 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
139 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
140 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
141 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
143 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
144 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
145 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
147 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING);
148 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
149 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
150 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
152 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
154 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
155 unsigned char *pMemory,
156 PFORMAT_STRING pFormat,
157 PFORMAT_STRING pPointer);
158 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
159 unsigned char *pMemory,
160 PFORMAT_STRING pFormat,
161 PFORMAT_STRING pPointer);
162 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
163 unsigned char *pMemory,
164 PFORMAT_STRING pFormat,
165 PFORMAT_STRING pPointer,
166 unsigned char fMustAlloc);
167 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
168 PFORMAT_STRING pFormat,
169 PFORMAT_STRING pPointer);
170 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
171 unsigned char *pMemory,
172 PFORMAT_STRING pFormat,
173 PFORMAT_STRING pPointer);
175 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
177 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
178 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
179 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
180 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
181 /* 0x10 */
182 NdrBaseTypeMarshall,
183 /* 0x11 */
184 NdrPointerMarshall, NdrPointerMarshall,
185 NdrPointerMarshall, NdrPointerMarshall,
186 /* 0x15 */
187 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
188 NdrConformantStructMarshall, NdrConformantStructMarshall,
189 NdrConformantVaryingStructMarshall,
190 NdrComplexStructMarshall,
191 /* 0x1b */
192 NdrConformantArrayMarshall,
193 NdrConformantVaryingArrayMarshall,
194 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
195 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
196 NdrComplexArrayMarshall,
197 /* 0x22 */
198 NdrConformantStringMarshall, 0, 0,
199 NdrConformantStringMarshall,
200 NdrNonConformantStringMarshall, 0, 0, 0,
201 /* 0x2a */
202 NdrEncapsulatedUnionMarshall,
203 NdrNonEncapsulatedUnionMarshall,
204 NdrByteCountPointerMarshall,
205 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
206 /* 0x2f */
207 NdrInterfacePointerMarshall,
208 /* 0x30 */
209 NdrContextHandleMarshall,
210 /* 0xb1 */
211 0, 0, 0,
212 NdrUserMarshalMarshall,
213 0, 0,
214 /* 0xb7 */
215 NdrRangeMarshall,
216 NdrBaseTypeMarshall,
217 NdrBaseTypeMarshall
219 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
221 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
222 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
223 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
224 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
225 /* 0x10 */
226 NdrBaseTypeUnmarshall,
227 /* 0x11 */
228 NdrPointerUnmarshall, NdrPointerUnmarshall,
229 NdrPointerUnmarshall, NdrPointerUnmarshall,
230 /* 0x15 */
231 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
232 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
233 NdrConformantVaryingStructUnmarshall,
234 NdrComplexStructUnmarshall,
235 /* 0x1b */
236 NdrConformantArrayUnmarshall,
237 NdrConformantVaryingArrayUnmarshall,
238 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
239 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
240 NdrComplexArrayUnmarshall,
241 /* 0x22 */
242 NdrConformantStringUnmarshall, 0, 0,
243 NdrConformantStringUnmarshall,
244 NdrNonConformantStringUnmarshall, 0, 0, 0,
245 /* 0x2a */
246 NdrEncapsulatedUnionUnmarshall,
247 NdrNonEncapsulatedUnionUnmarshall,
248 NdrByteCountPointerUnmarshall,
249 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
250 /* 0x2f */
251 NdrInterfacePointerUnmarshall,
252 /* 0x30 */
253 NdrContextHandleUnmarshall,
254 /* 0xb1 */
255 0, 0, 0,
256 NdrUserMarshalUnmarshall,
257 0, 0,
258 /* 0xb7 */
259 NdrRangeUnmarshall,
260 NdrBaseTypeUnmarshall,
261 NdrBaseTypeUnmarshall
263 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
265 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
266 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
267 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
268 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
269 /* 0x10 */
270 NdrBaseTypeBufferSize,
271 /* 0x11 */
272 NdrPointerBufferSize, NdrPointerBufferSize,
273 NdrPointerBufferSize, NdrPointerBufferSize,
274 /* 0x15 */
275 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
276 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
277 NdrConformantVaryingStructBufferSize,
278 NdrComplexStructBufferSize,
279 /* 0x1b */
280 NdrConformantArrayBufferSize,
281 NdrConformantVaryingArrayBufferSize,
282 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
283 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
284 NdrComplexArrayBufferSize,
285 /* 0x22 */
286 NdrConformantStringBufferSize, 0, 0,
287 NdrConformantStringBufferSize,
288 NdrNonConformantStringBufferSize, 0, 0, 0,
289 /* 0x2a */
290 NdrEncapsulatedUnionBufferSize,
291 NdrNonEncapsulatedUnionBufferSize,
292 NdrByteCountPointerBufferSize,
293 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
294 /* 0x2f */
295 NdrInterfacePointerBufferSize,
296 /* 0x30 */
297 NdrContextHandleBufferSize,
298 /* 0xb1 */
299 0, 0, 0,
300 NdrUserMarshalBufferSize,
301 0, 0,
302 /* 0xb7 */
303 NdrRangeBufferSize,
304 NdrBaseTypeBufferSize,
305 NdrBaseTypeBufferSize
307 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
309 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
310 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
311 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
312 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
313 /* 0x10 */
314 NdrBaseTypeMemorySize,
315 /* 0x11 */
316 NdrPointerMemorySize, NdrPointerMemorySize,
317 NdrPointerMemorySize, NdrPointerMemorySize,
318 /* 0x15 */
319 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
320 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
321 NdrConformantVaryingStructMemorySize,
322 NdrComplexStructMemorySize,
323 /* 0x1b */
324 NdrConformantArrayMemorySize,
325 NdrConformantVaryingArrayMemorySize,
326 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
327 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
328 NdrComplexArrayMemorySize,
329 /* 0x22 */
330 NdrConformantStringMemorySize, 0, 0,
331 NdrConformantStringMemorySize,
332 NdrNonConformantStringMemorySize, 0, 0, 0,
333 /* 0x2a */
334 NdrEncapsulatedUnionMemorySize,
335 NdrNonEncapsulatedUnionMemorySize,
336 NdrByteCountPointerMemorySize,
337 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
338 /* 0x2f */
339 NdrInterfacePointerMemorySize,
340 /* 0x30 */
342 /* 0xb1 */
343 0, 0, 0,
344 NdrUserMarshalMemorySize,
345 0, 0,
346 /* 0xb7 */
347 NdrRangeMemorySize,
348 NdrBaseTypeMemorySize,
349 NdrBaseTypeMemorySize
351 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
353 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
354 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
355 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
356 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
357 /* 0x10 */
358 NdrBaseTypeFree,
359 /* 0x11 */
360 NdrPointerFree, NdrPointerFree,
361 NdrPointerFree, NdrPointerFree,
362 /* 0x15 */
363 NdrSimpleStructFree, NdrSimpleStructFree,
364 NdrConformantStructFree, NdrConformantStructFree,
365 NdrConformantVaryingStructFree,
366 NdrComplexStructFree,
367 /* 0x1b */
368 NdrConformantArrayFree,
369 NdrConformantVaryingArrayFree,
370 NdrFixedArrayFree, NdrFixedArrayFree,
371 NdrVaryingArrayFree, NdrVaryingArrayFree,
372 NdrComplexArrayFree,
373 /* 0x22 */
374 0, 0, 0,
375 0, 0, 0, 0, 0,
376 /* 0x2a */
377 NdrEncapsulatedUnionFree,
378 NdrNonEncapsulatedUnionFree,
380 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
381 /* 0x2f */
382 NdrInterfacePointerFree,
383 /* 0x30 */
385 /* 0xb1 */
386 0, 0, 0,
387 NdrUserMarshalFree,
388 0, 0,
389 /* 0xb7 */
390 NdrRangeFree,
391 NdrBaseTypeFree,
392 NdrBaseTypeFree
395 typedef struct _NDR_MEMORY_LIST
397 ULONG magic;
398 ULONG size;
399 ULONG reserved;
400 struct _NDR_MEMORY_LIST *next;
401 } NDR_MEMORY_LIST;
403 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
405 /***********************************************************************
406 * NdrAllocate [RPCRT4.@]
408 * Allocates a block of memory using pStubMsg->pfnAllocate.
410 * PARAMS
411 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
412 * len [I] Size of memory block to allocate.
414 * RETURNS
415 * The memory block of size len that was allocated.
417 * NOTES
418 * The memory block is always 8-byte aligned.
419 * If the function is unable to allocate memory an RPC_X_NO_MEMORY
420 * exception is raised.
422 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
424 SIZE_T aligned_len;
425 SIZE_T adjusted_len;
426 void *p;
427 NDR_MEMORY_LIST *mem_list;
429 aligned_len = (len + 7) & ~7;
430 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
431 /* check for overflow */
432 if (adjusted_len < len)
434 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
435 RpcRaiseException(RPC_X_BAD_STUB_DATA);
438 p = pStubMsg->pfnAllocate(adjusted_len);
439 if (!p) RpcRaiseException(RPC_X_NO_MEMORY);
441 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
442 mem_list->magic = MEML_MAGIC;
443 mem_list->size = aligned_len;
444 mem_list->reserved = 0;
445 mem_list->next = pStubMsg->pMemoryList;
446 pStubMsg->pMemoryList = mem_list;
448 TRACE("-- %p\n", p);
449 return p;
452 static void *NdrAllocateZero(MIDL_STUB_MESSAGE *stubmsg, SIZE_T len)
454 void *mem = NdrAllocate(stubmsg, len);
455 memset(mem, 0, len);
456 return mem;
459 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
461 TRACE("(%p, %p)\n", pStubMsg, Pointer);
463 pStubMsg->pfnFree(Pointer);
466 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
468 return (*(const ULONG *)pFormat != -1);
471 static inline PFORMAT_STRING SkipConformance(const PMIDL_STUB_MESSAGE pStubMsg, const PFORMAT_STRING pFormat)
473 return pFormat + 4 + pStubMsg->CorrDespIncrement;
476 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
478 align_pointer(&pStubMsg->Buffer, 4);
479 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
480 RpcRaiseException(RPC_X_BAD_STUB_DATA);
481 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
482 pStubMsg->Buffer += 4;
483 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
484 return SkipConformance(pStubMsg, pFormat);
487 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
489 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
491 pStubMsg->Offset = 0;
492 pStubMsg->ActualCount = pStubMsg->MaxCount;
493 goto done;
496 align_pointer(&pStubMsg->Buffer, 4);
497 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
498 RpcRaiseException(RPC_X_BAD_STUB_DATA);
499 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
500 pStubMsg->Buffer += 4;
501 TRACE("offset is %d\n", pStubMsg->Offset);
502 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
503 pStubMsg->Buffer += 4;
504 TRACE("variance is %d\n", pStubMsg->ActualCount);
506 if ((pStubMsg->ActualCount > MaxValue) ||
507 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
509 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
510 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
511 RpcRaiseException(RPC_S_INVALID_BOUND);
512 return NULL;
515 done:
516 return SkipConformance(pStubMsg, pFormat);
519 /* writes the conformance value to the buffer */
520 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
522 align_pointer_clear(&pStubMsg->Buffer, 4);
523 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
524 RpcRaiseException(RPC_X_BAD_STUB_DATA);
525 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
526 pStubMsg->Buffer += 4;
529 /* writes the variance values to the buffer */
530 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
532 align_pointer_clear(&pStubMsg->Buffer, 4);
533 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
534 RpcRaiseException(RPC_X_BAD_STUB_DATA);
535 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
536 pStubMsg->Buffer += 4;
537 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
538 pStubMsg->Buffer += 4;
541 /* requests buffer space for the conformance value */
542 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
544 align_length(&pStubMsg->BufferLength, 4);
545 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
546 RpcRaiseException(RPC_X_BAD_STUB_DATA);
547 pStubMsg->BufferLength += 4;
550 /* requests buffer space for the variance values */
551 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
553 align_length(&pStubMsg->BufferLength, 4);
554 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
555 RpcRaiseException(RPC_X_BAD_STUB_DATA);
556 pStubMsg->BufferLength += 8;
559 PFORMAT_STRING ComputeConformanceOrVariance(
560 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
561 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
563 BYTE dtype = pFormat[0] & 0xf;
564 short ofs = *(const short *)&pFormat[2];
565 LPVOID ptr = NULL;
566 ULONG_PTR data = 0;
568 if (!IsConformanceOrVariancePresent(pFormat)) {
569 /* null descriptor */
570 *pCount = def;
571 goto finish_conf;
574 switch (pFormat[0] & 0xf0) {
575 case FC_NORMAL_CONFORMANCE:
576 TRACE("normal conformance, ofs=%d\n", ofs);
577 ptr = pMemory;
578 break;
579 case FC_POINTER_CONFORMANCE:
580 TRACE("pointer conformance, ofs=%d\n", ofs);
581 ptr = pStubMsg->Memory;
582 break;
583 case FC_TOP_LEVEL_CONFORMANCE:
584 TRACE("toplevel conformance, ofs=%d\n", ofs);
585 if (pStubMsg->StackTop) {
586 ptr = pStubMsg->StackTop;
588 else {
589 /* -Os mode, *pCount is already set */
590 goto finish_conf;
592 break;
593 case FC_CONSTANT_CONFORMANCE:
594 data = ofs | ((DWORD)pFormat[1] << 16);
595 TRACE("constant conformance, val=%ld\n", data);
596 *pCount = data;
597 goto finish_conf;
598 case FC_TOP_LEVEL_MULTID_CONFORMANCE:
599 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
600 if (pStubMsg->StackTop) {
601 ptr = pStubMsg->StackTop;
603 else {
604 /* ? */
605 goto done_conf_grab;
607 break;
608 default:
609 FIXME("unknown conformance type %x, expect crash.\n", pFormat[0] & 0xf0);
610 goto finish_conf;
613 switch (pFormat[1]) {
614 case FC_DEREFERENCE:
615 ptr = *(LPVOID*)((char *)ptr + ofs);
616 break;
617 case FC_CALLBACK:
619 unsigned char *old_stack_top = pStubMsg->StackTop;
620 ULONG_PTR max_count, old_max_count = pStubMsg->MaxCount;
622 pStubMsg->StackTop = ptr;
624 /* ofs is index into StubDesc->apfnExprEval */
625 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
626 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
628 pStubMsg->StackTop = old_stack_top;
630 /* the callback function always stores the computed value in MaxCount */
631 max_count = pStubMsg->MaxCount;
632 pStubMsg->MaxCount = old_max_count;
633 *pCount = max_count;
634 goto finish_conf;
636 default:
637 ptr = (char *)ptr + ofs;
638 break;
641 switch (dtype) {
642 case FC_LONG:
643 case FC_ULONG:
644 data = *(DWORD*)ptr;
645 break;
646 case FC_SHORT:
647 data = *(SHORT*)ptr;
648 break;
649 case FC_USHORT:
650 data = *(USHORT*)ptr;
651 break;
652 case FC_CHAR:
653 case FC_SMALL:
654 data = *(CHAR*)ptr;
655 break;
656 case FC_BYTE:
657 case FC_USMALL:
658 data = *(UCHAR*)ptr;
659 break;
660 case FC_HYPER:
661 data = *(ULONGLONG *)ptr;
662 break;
663 default:
664 FIXME("unknown conformance data type %x\n", dtype);
665 goto done_conf_grab;
667 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
669 done_conf_grab:
670 switch (pFormat[1]) {
671 case FC_DEREFERENCE: /* already handled */
672 case 0: /* no op */
673 *pCount = data;
674 break;
675 case FC_ADD_1:
676 *pCount = data + 1;
677 break;
678 case FC_SUB_1:
679 *pCount = data - 1;
680 break;
681 case FC_MULT_2:
682 *pCount = data * 2;
683 break;
684 case FC_DIV_2:
685 *pCount = data / 2;
686 break;
687 default:
688 FIXME("unknown conformance op %d\n", pFormat[1]);
689 goto finish_conf;
692 finish_conf:
693 TRACE("resulting conformance is %ld\n", *pCount);
695 return SkipConformance(pStubMsg, pFormat);
698 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
700 return SkipConformance( pStubMsg, pFormat );
703 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
704 * the result overflows 32-bits */
705 static inline ULONG safe_multiply(ULONG a, ULONG b)
707 ULONGLONG ret = (ULONGLONG)a * b;
708 if (ret > 0xffffffff)
710 RpcRaiseException(RPC_S_INVALID_BOUND);
711 return 0;
713 return ret;
716 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
718 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
719 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
720 RpcRaiseException(RPC_X_BAD_STUB_DATA);
721 pStubMsg->Buffer += size;
724 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
726 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
728 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
729 pStubMsg->BufferLength, size);
730 RpcRaiseException(RPC_X_BAD_STUB_DATA);
732 pStubMsg->BufferLength += size;
735 /* copies data from the buffer, checking that there is enough data in the buffer
736 * to do so */
737 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
739 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
740 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
742 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
743 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
744 RpcRaiseException(RPC_X_BAD_STUB_DATA);
746 if (p == pStubMsg->Buffer)
747 ERR("pointer is the same as the buffer\n");
748 memcpy(p, pStubMsg->Buffer, size);
749 pStubMsg->Buffer += size;
752 /* copies data to the buffer, checking that there is enough space to do so */
753 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
755 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
756 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
758 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
759 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
760 size);
761 RpcRaiseException(RPC_X_BAD_STUB_DATA);
763 memcpy(pStubMsg->Buffer, p, size);
764 pStubMsg->Buffer += size;
767 /* verify that string data sitting in the buffer is valid and safe to
768 * unmarshall */
769 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
771 ULONG i;
773 /* verify the buffer is safe to access */
774 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
775 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
777 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
778 pStubMsg->BufferEnd, pStubMsg->Buffer);
779 RpcRaiseException(RPC_X_BAD_STUB_DATA);
782 /* strings must always have null terminating bytes */
783 if (bufsize < esize)
785 ERR("invalid string length of %d\n", bufsize / esize);
786 RpcRaiseException(RPC_S_INVALID_BOUND);
789 for (i = bufsize - esize; i < bufsize; i++)
790 if (pStubMsg->Buffer[i] != 0)
792 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
793 i, pStubMsg->Buffer[i]);
794 RpcRaiseException(RPC_S_INVALID_BOUND);
798 static inline void dump_pointer_attr(unsigned char attr)
800 if (attr & FC_ALLOCATE_ALL_NODES)
801 TRACE(" FC_ALLOCATE_ALL_NODES");
802 if (attr & FC_DONT_FREE)
803 TRACE(" FC_DONT_FREE");
804 if (attr & FC_ALLOCED_ON_STACK)
805 TRACE(" FC_ALLOCED_ON_STACK");
806 if (attr & FC_SIMPLE_POINTER)
807 TRACE(" FC_SIMPLE_POINTER");
808 if (attr & FC_POINTER_DEREF)
809 TRACE(" FC_POINTER_DEREF");
810 TRACE("\n");
813 /***********************************************************************
814 * PointerMarshall [internal]
816 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
817 unsigned char *Buffer,
818 unsigned char *Pointer,
819 PFORMAT_STRING pFormat)
821 unsigned type = pFormat[0], attr = pFormat[1];
822 PFORMAT_STRING desc;
823 NDR_MARSHALL m;
824 ULONG pointer_id;
825 BOOL pointer_needs_marshaling;
827 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
828 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
829 pFormat += 2;
830 if (attr & FC_SIMPLE_POINTER) desc = pFormat;
831 else desc = pFormat + *(const SHORT*)pFormat;
833 switch (type) {
834 case FC_RP: /* ref pointer (always non-null) */
835 if (!Pointer)
837 ERR("NULL ref pointer is not allowed\n");
838 RpcRaiseException(RPC_X_NULL_REF_POINTER);
840 pointer_needs_marshaling = TRUE;
841 break;
842 case FC_UP: /* unique pointer */
843 case FC_OP: /* object pointer - same as unique here */
844 if (Pointer)
845 pointer_needs_marshaling = TRUE;
846 else
847 pointer_needs_marshaling = FALSE;
848 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
849 TRACE("writing 0x%08x to buffer\n", pointer_id);
850 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
851 break;
852 case FC_FP:
853 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
854 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
855 TRACE("writing 0x%08x to buffer\n", pointer_id);
856 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
857 break;
858 default:
859 FIXME("unhandled ptr type=%02x\n", type);
860 RpcRaiseException(RPC_X_BAD_STUB_DATA);
861 return;
864 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
866 if (pointer_needs_marshaling) {
867 if (attr & FC_POINTER_DEREF) {
868 Pointer = *(unsigned char**)Pointer;
869 TRACE("deref => %p\n", Pointer);
871 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
872 if (m) m(pStubMsg, Pointer, desc);
873 else FIXME("no marshaller for data type=%02x\n", *desc);
876 STD_OVERFLOW_CHECK(pStubMsg);
879 /* pPointer is the pointer that we will unmarshal into; pSrcPointer is the
880 * pointer to memory which we may attempt to reuse if non-NULL. Usually these
881 * are the same; for the case when they aren't, see EmbeddedPointerUnmarshall().
883 * fMustAlloc seems to determine whether we can allocate from the buffer (if we
884 * are on the server side). It's ignored here, since we can't allocate a pointer
885 * from the buffer. */
886 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
887 unsigned char *Buffer,
888 unsigned char **pPointer,
889 unsigned char *pSrcPointer,
890 PFORMAT_STRING pFormat,
891 unsigned char fMustAlloc)
893 unsigned type = pFormat[0], attr = pFormat[1];
894 PFORMAT_STRING desc;
895 NDR_UNMARSHALL m;
896 DWORD pointer_id = 0;
897 BOOL pointer_needs_unmarshaling, need_alloc = FALSE, inner_must_alloc = FALSE;
899 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
900 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
901 pFormat += 2;
902 if (attr & FC_SIMPLE_POINTER) desc = pFormat;
903 else desc = pFormat + *(const SHORT*)pFormat;
905 switch (type) {
906 case FC_RP: /* ref pointer (always non-null) */
907 pointer_needs_unmarshaling = TRUE;
908 break;
909 case FC_UP: /* unique pointer */
910 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
911 TRACE("pointer_id is 0x%08x\n", pointer_id);
912 if (pointer_id)
913 pointer_needs_unmarshaling = TRUE;
914 else {
915 *pPointer = NULL;
916 pointer_needs_unmarshaling = FALSE;
918 break;
919 case FC_OP: /* object pointer - we must free data before overwriting it */
920 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
921 TRACE("pointer_id is 0x%08x\n", pointer_id);
923 /* An object pointer always allocates new memory (it cannot point to the
924 * buffer). */
925 inner_must_alloc = TRUE;
927 if (pSrcPointer)
928 FIXME("free object pointer %p\n", pSrcPointer);
929 if (pointer_id)
930 pointer_needs_unmarshaling = TRUE;
931 else
933 *pPointer = NULL;
934 pointer_needs_unmarshaling = FALSE;
936 break;
937 case FC_FP:
938 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
939 TRACE("pointer_id is 0x%08x\n", pointer_id);
940 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
941 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
942 break;
943 default:
944 FIXME("unhandled ptr type=%02x\n", type);
945 RpcRaiseException(RPC_X_BAD_STUB_DATA);
946 return;
949 if (pointer_needs_unmarshaling) {
950 unsigned char **current_ptr = pPointer;
951 if (pStubMsg->IsClient) {
952 TRACE("client\n");
953 /* Try to use the existing (source) pointer to unmarshall the data into
954 * so that [in, out] or [out, ref] parameters behave correctly. If the
955 * source pointer is NULL and we are not dereferencing, we must force the
956 * inner marshalling routine to allocate, since otherwise it will crash. */
957 if (pSrcPointer)
959 TRACE("setting *pPointer to %p\n", pSrcPointer);
960 *pPointer = pSrcPointer;
962 else
963 need_alloc = inner_must_alloc = TRUE;
964 } else {
965 TRACE("server\n");
966 /* We can use an existing source pointer here only if it is on-stack,
967 * probably since otherwise NdrPointerFree() might later try to free a
968 * pointer we don't know the provenance of. Otherwise we must always
969 * allocate if we are dereferencing. We never need to force the inner
970 * routine to allocate here, since it will either write into an existing
971 * pointer, or use a pointer to the buffer. */
972 if (attr & FC_POINTER_DEREF)
974 if (pSrcPointer && (attr & FC_ALLOCED_ON_STACK))
975 *pPointer = pSrcPointer;
976 else
977 need_alloc = TRUE;
979 else
980 *pPointer = NULL;
983 if (attr & FC_ALLOCATE_ALL_NODES)
984 FIXME("FC_ALLOCATE_ALL_NODES not implemented\n");
986 if (attr & FC_POINTER_DEREF) {
987 if (need_alloc)
988 *pPointer = NdrAllocateZero(pStubMsg, sizeof(void *));
990 current_ptr = *(unsigned char***)current_ptr;
991 TRACE("deref => %p\n", current_ptr);
993 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
994 if (m) m(pStubMsg, current_ptr, desc, inner_must_alloc);
995 else FIXME("no unmarshaller for data type=%02x\n", *desc);
997 if (type == FC_FP)
998 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
999 *pPointer);
1002 TRACE("pointer=%p\n", *pPointer);
1005 /***********************************************************************
1006 * PointerBufferSize [internal]
1008 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1009 unsigned char *Pointer,
1010 PFORMAT_STRING pFormat)
1012 unsigned type = pFormat[0], attr = pFormat[1];
1013 PFORMAT_STRING desc;
1014 NDR_BUFFERSIZE m;
1015 BOOL pointer_needs_sizing;
1016 ULONG pointer_id;
1018 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1019 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1020 pFormat += 2;
1021 if (attr & FC_SIMPLE_POINTER) desc = pFormat;
1022 else desc = pFormat + *(const SHORT*)pFormat;
1024 switch (type) {
1025 case FC_RP: /* ref pointer (always non-null) */
1026 if (!Pointer)
1028 ERR("NULL ref pointer is not allowed\n");
1029 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1031 break;
1032 case FC_OP:
1033 case FC_UP:
1034 /* NULL pointer has no further representation */
1035 if (!Pointer)
1036 return;
1037 break;
1038 case FC_FP:
1039 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1040 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1041 if (!pointer_needs_sizing)
1042 return;
1043 break;
1044 default:
1045 FIXME("unhandled ptr type=%02x\n", type);
1046 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1047 return;
1050 if (attr & FC_POINTER_DEREF) {
1051 Pointer = *(unsigned char**)Pointer;
1052 TRACE("deref => %p\n", Pointer);
1055 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1056 if (m) m(pStubMsg, Pointer, desc);
1057 else FIXME("no buffersizer for data type=%02x\n", *desc);
1060 /***********************************************************************
1061 * PointerMemorySize [internal]
1063 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1064 unsigned char *Buffer, PFORMAT_STRING pFormat)
1066 unsigned type = pFormat[0], attr = pFormat[1];
1067 PFORMAT_STRING desc;
1068 NDR_MEMORYSIZE m;
1069 DWORD pointer_id = 0;
1070 BOOL pointer_needs_sizing;
1072 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1073 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1074 pFormat += 2;
1075 if (attr & FC_SIMPLE_POINTER) desc = pFormat;
1076 else desc = pFormat + *(const SHORT*)pFormat;
1078 switch (type) {
1079 case FC_RP: /* ref pointer (always non-null) */
1080 pointer_needs_sizing = TRUE;
1081 break;
1082 case FC_UP: /* unique pointer */
1083 case FC_OP: /* object pointer - we must free data before overwriting it */
1084 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1085 TRACE("pointer_id is 0x%08x\n", pointer_id);
1086 if (pointer_id)
1087 pointer_needs_sizing = TRUE;
1088 else
1089 pointer_needs_sizing = FALSE;
1090 break;
1091 case FC_FP:
1093 void *pointer;
1094 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1095 TRACE("pointer_id is 0x%08x\n", pointer_id);
1096 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1097 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1098 break;
1100 default:
1101 FIXME("unhandled ptr type=%02x\n", type);
1102 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1103 return 0;
1106 if (attr & FC_POINTER_DEREF) {
1107 align_length(&pStubMsg->MemorySize, sizeof(void*));
1108 pStubMsg->MemorySize += sizeof(void*);
1109 TRACE("deref\n");
1112 if (pointer_needs_sizing) {
1113 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1114 if (m) m(pStubMsg, desc);
1115 else FIXME("no memorysizer for data type=%02x\n", *desc);
1118 return pStubMsg->MemorySize;
1121 /***********************************************************************
1122 * PointerFree [internal]
1124 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1125 unsigned char *Pointer,
1126 PFORMAT_STRING pFormat)
1128 unsigned type = pFormat[0], attr = pFormat[1];
1129 PFORMAT_STRING desc;
1130 NDR_FREE m;
1131 unsigned char *current_pointer = Pointer;
1133 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1134 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1135 if (attr & FC_DONT_FREE) return;
1136 pFormat += 2;
1137 if (attr & FC_SIMPLE_POINTER) desc = pFormat;
1138 else desc = pFormat + *(const SHORT*)pFormat;
1140 if (!Pointer) return;
1142 if (type == FC_FP) {
1143 int pointer_needs_freeing = NdrFullPointerFree(
1144 pStubMsg->FullPtrXlatTables, Pointer);
1145 if (!pointer_needs_freeing)
1146 return;
1149 if (attr & FC_POINTER_DEREF) {
1150 current_pointer = *(unsigned char**)Pointer;
1151 TRACE("deref => %p\n", current_pointer);
1154 m = NdrFreer[*desc & NDR_TABLE_MASK];
1155 if (m) m(pStubMsg, current_pointer, desc);
1157 /* this check stops us from trying to free buffer memory. we don't have to
1158 * worry about clients, since they won't call this function.
1159 * we don't have to check for the buffer being reallocated because
1160 * BufferStart and BufferEnd won't be reset when allocating memory for
1161 * sending the response. we don't have to check for the new buffer here as
1162 * it won't be used a type memory, only for buffer memory */
1163 if (Pointer >= pStubMsg->BufferStart && Pointer <= pStubMsg->BufferEnd)
1164 goto notfree;
1166 if (attr & FC_ALLOCED_ON_STACK) {
1167 TRACE("not freeing stack ptr %p\n", Pointer);
1168 return;
1170 TRACE("freeing %p\n", Pointer);
1171 NdrFree(pStubMsg, Pointer);
1172 return;
1173 notfree:
1174 TRACE("not freeing %p\n", Pointer);
1177 /***********************************************************************
1178 * EmbeddedPointerMarshall
1180 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1181 unsigned char *pMemory,
1182 PFORMAT_STRING pFormat)
1184 unsigned char *Mark = pStubMsg->BufferMark;
1185 unsigned rep, count, stride;
1186 unsigned i;
1187 unsigned char *saved_buffer = NULL;
1189 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1191 if (*pFormat != FC_PP) return NULL;
1192 pFormat += 2;
1194 if (pStubMsg->PointerBufferMark)
1196 saved_buffer = pStubMsg->Buffer;
1197 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1198 pStubMsg->PointerBufferMark = NULL;
1201 while (pFormat[0] != FC_END) {
1202 switch (pFormat[0]) {
1203 default:
1204 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1205 /* fallthrough */
1206 case FC_NO_REPEAT:
1207 rep = 1;
1208 stride = 0;
1209 count = 1;
1210 pFormat += 2;
1211 break;
1212 case FC_FIXED_REPEAT:
1213 rep = *(const WORD*)&pFormat[2];
1214 stride = *(const WORD*)&pFormat[4];
1215 count = *(const WORD*)&pFormat[8];
1216 pFormat += 10;
1217 break;
1218 case FC_VARIABLE_REPEAT:
1219 rep = (pFormat[1] == FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1220 stride = *(const WORD*)&pFormat[2];
1221 count = *(const WORD*)&pFormat[6];
1222 pFormat += 8;
1223 break;
1225 for (i = 0; i < rep; i++) {
1226 PFORMAT_STRING info = pFormat;
1227 unsigned char *membase = pMemory + (i * stride);
1228 unsigned char *bufbase = Mark + (i * stride);
1229 unsigned u;
1231 for (u=0; u<count; u++,info+=8) {
1232 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1233 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1234 unsigned char *saved_memory = pStubMsg->Memory;
1236 pStubMsg->Memory = membase;
1237 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1238 pStubMsg->Memory = saved_memory;
1241 pFormat += 8 * count;
1244 if (saved_buffer)
1246 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1247 pStubMsg->Buffer = saved_buffer;
1250 STD_OVERFLOW_CHECK(pStubMsg);
1252 return NULL;
1255 /* rpcrt4 does something bizarre with embedded pointers: instead of copying the
1256 * struct/array/union from the buffer to memory and then unmarshalling pointers
1257 * into it, it unmarshals pointers into the buffer itself and then copies it to
1258 * memory. However, it will still attempt to use a user-supplied pointer where
1259 * appropriate (i.e. one on stack). Therefore we need to pass both pointers to
1260 * this function and to PointerUnmarshall: the pointer (to the buffer) that we
1261 * will actually unmarshal into (pDstBuffer), and the pointer (to memory) that
1262 * we will attempt to use for storage if possible (pSrcMemoryPtrs). */
1263 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1264 unsigned char *pDstBuffer,
1265 unsigned char *pSrcMemoryPtrs,
1266 PFORMAT_STRING pFormat,
1267 unsigned char fMustAlloc)
1269 unsigned char *Mark = pStubMsg->BufferMark;
1270 unsigned rep, count, stride;
1271 unsigned i;
1272 unsigned char *saved_buffer = NULL;
1274 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1276 if (*pFormat != FC_PP) return NULL;
1277 pFormat += 2;
1279 if (pStubMsg->PointerBufferMark)
1281 saved_buffer = pStubMsg->Buffer;
1282 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1283 pStubMsg->PointerBufferMark = NULL;
1286 while (pFormat[0] != FC_END) {
1287 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1288 switch (pFormat[0]) {
1289 default:
1290 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1291 /* fallthrough */
1292 case FC_NO_REPEAT:
1293 rep = 1;
1294 stride = 0;
1295 count = 1;
1296 pFormat += 2;
1297 break;
1298 case FC_FIXED_REPEAT:
1299 rep = *(const WORD*)&pFormat[2];
1300 stride = *(const WORD*)&pFormat[4];
1301 count = *(const WORD*)&pFormat[8];
1302 pFormat += 10;
1303 break;
1304 case FC_VARIABLE_REPEAT:
1305 rep = (pFormat[1] == FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1306 stride = *(const WORD*)&pFormat[2];
1307 count = *(const WORD*)&pFormat[6];
1308 pFormat += 8;
1309 break;
1311 for (i = 0; i < rep; i++) {
1312 PFORMAT_STRING info = pFormat;
1313 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1314 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1315 unsigned char *bufbase = Mark + (i * stride);
1316 unsigned u;
1318 for (u=0; u<count; u++,info+=8) {
1319 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1320 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1321 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1322 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1325 pFormat += 8 * count;
1328 if (saved_buffer)
1330 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1331 pStubMsg->Buffer = saved_buffer;
1334 return NULL;
1337 /***********************************************************************
1338 * EmbeddedPointerBufferSize
1340 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1341 unsigned char *pMemory,
1342 PFORMAT_STRING pFormat)
1344 unsigned rep, count, stride;
1345 unsigned i;
1346 ULONG saved_buffer_length = 0;
1348 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1350 if (pStubMsg->IgnoreEmbeddedPointers) return;
1352 if (*pFormat != FC_PP) return;
1353 pFormat += 2;
1355 if (pStubMsg->PointerLength)
1357 saved_buffer_length = pStubMsg->BufferLength;
1358 pStubMsg->BufferLength = pStubMsg->PointerLength;
1359 pStubMsg->PointerLength = 0;
1362 while (pFormat[0] != FC_END) {
1363 switch (pFormat[0]) {
1364 default:
1365 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1366 /* fallthrough */
1367 case FC_NO_REPEAT:
1368 rep = 1;
1369 stride = 0;
1370 count = 1;
1371 pFormat += 2;
1372 break;
1373 case FC_FIXED_REPEAT:
1374 rep = *(const WORD*)&pFormat[2];
1375 stride = *(const WORD*)&pFormat[4];
1376 count = *(const WORD*)&pFormat[8];
1377 pFormat += 10;
1378 break;
1379 case FC_VARIABLE_REPEAT:
1380 rep = (pFormat[1] == FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1381 stride = *(const WORD*)&pFormat[2];
1382 count = *(const WORD*)&pFormat[6];
1383 pFormat += 8;
1384 break;
1386 for (i = 0; i < rep; i++) {
1387 PFORMAT_STRING info = pFormat;
1388 unsigned char *membase = pMemory + (i * stride);
1389 unsigned u;
1391 for (u=0; u<count; u++,info+=8) {
1392 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1393 unsigned char *saved_memory = pStubMsg->Memory;
1395 pStubMsg->Memory = membase;
1396 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1397 pStubMsg->Memory = saved_memory;
1400 pFormat += 8 * count;
1403 if (saved_buffer_length)
1405 pStubMsg->PointerLength = pStubMsg->BufferLength;
1406 pStubMsg->BufferLength = saved_buffer_length;
1410 /***********************************************************************
1411 * EmbeddedPointerMemorySize [internal]
1413 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1414 PFORMAT_STRING pFormat)
1416 unsigned char *Mark = pStubMsg->BufferMark;
1417 unsigned rep, count, stride;
1418 unsigned i;
1419 unsigned char *saved_buffer = NULL;
1421 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1423 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1425 if (pStubMsg->PointerBufferMark)
1427 saved_buffer = pStubMsg->Buffer;
1428 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1429 pStubMsg->PointerBufferMark = NULL;
1432 if (*pFormat != FC_PP) return 0;
1433 pFormat += 2;
1435 while (pFormat[0] != FC_END) {
1436 switch (pFormat[0]) {
1437 default:
1438 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1439 /* fallthrough */
1440 case FC_NO_REPEAT:
1441 rep = 1;
1442 stride = 0;
1443 count = 1;
1444 pFormat += 2;
1445 break;
1446 case FC_FIXED_REPEAT:
1447 rep = *(const WORD*)&pFormat[2];
1448 stride = *(const WORD*)&pFormat[4];
1449 count = *(const WORD*)&pFormat[8];
1450 pFormat += 10;
1451 break;
1452 case FC_VARIABLE_REPEAT:
1453 rep = (pFormat[1] == FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1454 stride = *(const WORD*)&pFormat[2];
1455 count = *(const WORD*)&pFormat[6];
1456 pFormat += 8;
1457 break;
1459 for (i = 0; i < rep; i++) {
1460 PFORMAT_STRING info = pFormat;
1461 unsigned char *bufbase = Mark + (i * stride);
1462 unsigned u;
1463 for (u=0; u<count; u++,info+=8) {
1464 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1465 PointerMemorySize(pStubMsg, bufptr, info+4);
1468 pFormat += 8 * count;
1471 if (saved_buffer)
1473 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1474 pStubMsg->Buffer = saved_buffer;
1477 return 0;
1480 /***********************************************************************
1481 * EmbeddedPointerFree [internal]
1483 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1484 unsigned char *pMemory,
1485 PFORMAT_STRING pFormat)
1487 unsigned rep, count, stride;
1488 unsigned i;
1490 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1491 if (*pFormat != FC_PP) return;
1492 pFormat += 2;
1494 while (pFormat[0] != FC_END) {
1495 switch (pFormat[0]) {
1496 default:
1497 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1498 /* fallthrough */
1499 case FC_NO_REPEAT:
1500 rep = 1;
1501 stride = 0;
1502 count = 1;
1503 pFormat += 2;
1504 break;
1505 case FC_FIXED_REPEAT:
1506 rep = *(const WORD*)&pFormat[2];
1507 stride = *(const WORD*)&pFormat[4];
1508 count = *(const WORD*)&pFormat[8];
1509 pFormat += 10;
1510 break;
1511 case FC_VARIABLE_REPEAT:
1512 rep = (pFormat[1] == FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1513 stride = *(const WORD*)&pFormat[2];
1514 count = *(const WORD*)&pFormat[6];
1515 pFormat += 8;
1516 break;
1518 for (i = 0; i < rep; i++) {
1519 PFORMAT_STRING info = pFormat;
1520 unsigned char *membase = pMemory + (i * stride);
1521 unsigned u;
1523 for (u=0; u<count; u++,info+=8) {
1524 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1525 unsigned char *saved_memory = pStubMsg->Memory;
1527 pStubMsg->Memory = membase;
1528 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1529 pStubMsg->Memory = saved_memory;
1532 pFormat += 8 * count;
1536 /***********************************************************************
1537 * NdrPointerMarshall [RPCRT4.@]
1539 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1540 unsigned char *pMemory,
1541 PFORMAT_STRING pFormat)
1543 unsigned char *Buffer;
1545 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1547 /* Increment the buffer here instead of in PointerMarshall,
1548 * as that is used by embedded pointers which already handle the incrementing
1549 * the buffer, and shouldn't write any additional pointer data to the wire */
1550 if (*pFormat != FC_RP)
1552 align_pointer_clear(&pStubMsg->Buffer, 4);
1553 Buffer = pStubMsg->Buffer;
1554 safe_buffer_increment(pStubMsg, 4);
1556 else
1557 Buffer = pStubMsg->Buffer;
1559 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1561 return NULL;
1564 /***********************************************************************
1565 * NdrPointerUnmarshall [RPCRT4.@]
1567 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1568 unsigned char **ppMemory,
1569 PFORMAT_STRING pFormat,
1570 unsigned char fMustAlloc)
1572 unsigned char *Buffer;
1574 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1576 if (*pFormat == FC_RP)
1578 Buffer = pStubMsg->Buffer;
1579 /* Do the NULL ref pointer check here because embedded pointers can be
1580 * NULL if the type the pointer is embedded in was allocated rather than
1581 * being passed in by the client */
1582 if (pStubMsg->IsClient && !*ppMemory)
1584 ERR("NULL ref pointer is not allowed\n");
1585 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1588 else
1590 /* Increment the buffer here instead of in PointerUnmarshall,
1591 * as that is used by embedded pointers which already handle the incrementing
1592 * the buffer, and shouldn't read any additional pointer data from the
1593 * buffer */
1594 align_pointer(&pStubMsg->Buffer, 4);
1595 Buffer = pStubMsg->Buffer;
1596 safe_buffer_increment(pStubMsg, 4);
1599 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1601 return NULL;
1604 /***********************************************************************
1605 * NdrPointerBufferSize [RPCRT4.@]
1607 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1608 unsigned char *pMemory,
1609 PFORMAT_STRING pFormat)
1611 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1613 /* Increment the buffer length here instead of in PointerBufferSize,
1614 * as that is used by embedded pointers which already handle the buffer
1615 * length, and shouldn't write anything more to the wire */
1616 if (*pFormat != FC_RP)
1618 align_length(&pStubMsg->BufferLength, 4);
1619 safe_buffer_length_increment(pStubMsg, 4);
1622 PointerBufferSize(pStubMsg, pMemory, pFormat);
1625 /***********************************************************************
1626 * NdrPointerMemorySize [RPCRT4.@]
1628 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1629 PFORMAT_STRING pFormat)
1631 unsigned char *Buffer = pStubMsg->Buffer;
1632 if (*pFormat != FC_RP)
1634 align_pointer(&pStubMsg->Buffer, 4);
1635 safe_buffer_increment(pStubMsg, 4);
1637 align_length(&pStubMsg->MemorySize, sizeof(void *));
1638 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1641 /***********************************************************************
1642 * NdrPointerFree [RPCRT4.@]
1644 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1645 unsigned char *pMemory,
1646 PFORMAT_STRING pFormat)
1648 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1649 PointerFree(pStubMsg, pMemory, pFormat);
1652 /***********************************************************************
1653 * NdrSimpleTypeMarshall [RPCRT4.@]
1655 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1656 unsigned char FormatChar )
1658 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1661 /***********************************************************************
1662 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1664 * Unmarshall a base type.
1666 * NOTES
1667 * Doesn't check that the buffer is long enough before copying, so the caller
1668 * should do this.
1670 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1671 unsigned char FormatChar )
1673 #define BASE_TYPE_UNMARSHALL(type) \
1674 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1675 TRACE("pMemory: %p\n", pMemory); \
1676 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1677 pStubMsg->Buffer += sizeof(type);
1679 switch(FormatChar)
1681 case FC_BYTE:
1682 case FC_CHAR:
1683 case FC_SMALL:
1684 case FC_USMALL:
1685 BASE_TYPE_UNMARSHALL(UCHAR);
1686 TRACE("value: 0x%02x\n", *pMemory);
1687 break;
1688 case FC_WCHAR:
1689 case FC_SHORT:
1690 case FC_USHORT:
1691 BASE_TYPE_UNMARSHALL(USHORT);
1692 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1693 break;
1694 case FC_LONG:
1695 case FC_ULONG:
1696 case FC_ERROR_STATUS_T:
1697 case FC_ENUM32:
1698 BASE_TYPE_UNMARSHALL(ULONG);
1699 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1700 break;
1701 case FC_FLOAT:
1702 BASE_TYPE_UNMARSHALL(float);
1703 TRACE("value: %f\n", *(float *)pMemory);
1704 break;
1705 case FC_DOUBLE:
1706 BASE_TYPE_UNMARSHALL(double);
1707 TRACE("value: %f\n", *(double *)pMemory);
1708 break;
1709 case FC_HYPER:
1710 BASE_TYPE_UNMARSHALL(ULONGLONG);
1711 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1712 break;
1713 case FC_ENUM16:
1714 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
1715 TRACE("pMemory: %p\n", pMemory);
1716 /* 16-bits on the wire, but int in memory */
1717 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1718 pStubMsg->Buffer += sizeof(USHORT);
1719 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1720 break;
1721 case FC_INT3264:
1722 align_pointer(&pStubMsg->Buffer, sizeof(INT));
1723 /* 32-bits on the wire, but int_ptr in memory */
1724 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer;
1725 pStubMsg->Buffer += sizeof(INT);
1726 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory);
1727 break;
1728 case FC_UINT3264:
1729 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
1730 /* 32-bits on the wire, but int_ptr in memory */
1731 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer;
1732 pStubMsg->Buffer += sizeof(UINT);
1733 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory);
1734 break;
1735 case FC_IGNORE:
1736 break;
1737 default:
1738 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1740 #undef BASE_TYPE_UNMARSHALL
1743 /***********************************************************************
1744 * NdrSimpleStructMarshall [RPCRT4.@]
1746 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1747 unsigned char *pMemory,
1748 PFORMAT_STRING pFormat)
1750 unsigned size = *(const WORD*)(pFormat+2);
1751 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1753 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
1755 pStubMsg->BufferMark = pStubMsg->Buffer;
1756 safe_copy_to_buffer(pStubMsg, pMemory, size);
1758 if (pFormat[0] != FC_STRUCT)
1759 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1761 return NULL;
1764 /***********************************************************************
1765 * NdrSimpleStructUnmarshall [RPCRT4.@]
1767 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1768 unsigned char **ppMemory,
1769 PFORMAT_STRING pFormat,
1770 unsigned char fMustAlloc)
1772 unsigned size = *(const WORD*)(pFormat+2);
1773 unsigned char *saved_buffer;
1774 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1776 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1778 if (fMustAlloc)
1779 *ppMemory = NdrAllocateZero(pStubMsg, size);
1780 else
1782 if (!pStubMsg->IsClient && !*ppMemory)
1783 /* for servers, we just point straight into the RPC buffer */
1784 *ppMemory = pStubMsg->Buffer;
1787 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1788 safe_buffer_increment(pStubMsg, size);
1789 if (pFormat[0] == FC_PSTRUCT)
1790 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1792 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1793 if (*ppMemory != saved_buffer)
1794 memcpy(*ppMemory, saved_buffer, size);
1796 return NULL;
1799 /***********************************************************************
1800 * NdrSimpleStructBufferSize [RPCRT4.@]
1802 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1803 unsigned char *pMemory,
1804 PFORMAT_STRING pFormat)
1806 unsigned size = *(const WORD*)(pFormat+2);
1807 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1809 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
1811 safe_buffer_length_increment(pStubMsg, size);
1812 if (pFormat[0] != FC_STRUCT)
1813 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1816 /***********************************************************************
1817 * NdrSimpleStructMemorySize [RPCRT4.@]
1819 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1820 PFORMAT_STRING pFormat)
1822 unsigned short size = *(const WORD *)(pFormat+2);
1824 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1826 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1827 pStubMsg->MemorySize += size;
1828 safe_buffer_increment(pStubMsg, size);
1830 if (pFormat[0] != FC_STRUCT)
1831 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1832 return pStubMsg->MemorySize;
1835 /***********************************************************************
1836 * NdrSimpleStructFree [RPCRT4.@]
1838 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1839 unsigned char *pMemory,
1840 PFORMAT_STRING pFormat)
1842 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1843 if (pFormat[0] != FC_STRUCT)
1844 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1847 /* Array helpers */
1849 static inline void array_compute_and_size_conformance(
1850 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1851 PFORMAT_STRING pFormat)
1853 DWORD count;
1855 switch (fc)
1857 case FC_CARRAY:
1858 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1859 SizeConformance(pStubMsg);
1860 break;
1861 case FC_CVARRAY:
1862 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1863 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1864 SizeConformance(pStubMsg);
1865 break;
1866 case FC_C_CSTRING:
1867 case FC_C_WSTRING:
1868 if (fc == FC_C_CSTRING)
1870 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1871 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1873 else
1875 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1876 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1879 if (pFormat[1] == FC_STRING_SIZED)
1880 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1881 else
1882 pStubMsg->MaxCount = pStubMsg->ActualCount;
1884 SizeConformance(pStubMsg);
1885 break;
1886 case FC_BOGUS_ARRAY:
1887 count = *(const WORD *)(pFormat + 2);
1888 pFormat += 4;
1889 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg);
1890 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count);
1891 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1892 break;
1893 default:
1894 ERR("unknown array format 0x%x\n", fc);
1895 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1899 static inline void array_buffer_size(
1900 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1901 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1903 DWORD i, size;
1904 DWORD esize;
1905 unsigned char alignment;
1907 switch (fc)
1909 case FC_CARRAY:
1910 esize = *(const WORD*)(pFormat+2);
1911 alignment = pFormat[1] + 1;
1913 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1915 align_length(&pStubMsg->BufferLength, alignment);
1917 size = safe_multiply(esize, pStubMsg->MaxCount);
1918 /* conformance value plus array */
1919 safe_buffer_length_increment(pStubMsg, size);
1921 if (fHasPointers)
1922 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1923 break;
1924 case FC_CVARRAY:
1925 esize = *(const WORD*)(pFormat+2);
1926 alignment = pFormat[1] + 1;
1928 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1929 pFormat = SkipVariance(pStubMsg, pFormat);
1931 SizeVariance(pStubMsg);
1933 align_length(&pStubMsg->BufferLength, alignment);
1935 size = safe_multiply(esize, pStubMsg->ActualCount);
1936 safe_buffer_length_increment(pStubMsg, size);
1938 if (fHasPointers)
1939 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1940 break;
1941 case FC_C_CSTRING:
1942 case FC_C_WSTRING:
1943 if (fc == FC_C_CSTRING)
1944 esize = 1;
1945 else
1946 esize = 2;
1948 SizeVariance(pStubMsg);
1950 size = safe_multiply(esize, pStubMsg->ActualCount);
1951 safe_buffer_length_increment(pStubMsg, size);
1952 break;
1953 case FC_BOGUS_ARRAY:
1954 alignment = pFormat[1] + 1;
1955 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1956 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg);
1957 pFormat = SkipVariance(pStubMsg, pFormat);
1959 align_length(&pStubMsg->BufferLength, alignment);
1961 size = pStubMsg->ActualCount;
1962 for (i = 0; i < size; i++)
1963 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1964 break;
1965 default:
1966 ERR("unknown array format 0x%x\n", fc);
1967 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1971 static inline void array_compute_and_write_conformance(
1972 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1973 PFORMAT_STRING pFormat)
1975 ULONG def;
1976 BOOL conformance_present;
1978 switch (fc)
1980 case FC_CARRAY:
1981 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1982 WriteConformance(pStubMsg);
1983 break;
1984 case FC_CVARRAY:
1985 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1986 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1987 WriteConformance(pStubMsg);
1988 break;
1989 case FC_C_CSTRING:
1990 case FC_C_WSTRING:
1991 if (fc == FC_C_CSTRING)
1993 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1994 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1996 else
1998 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1999 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
2001 if (pFormat[1] == FC_STRING_SIZED)
2002 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
2003 else
2004 pStubMsg->MaxCount = pStubMsg->ActualCount;
2005 pStubMsg->Offset = 0;
2006 WriteConformance(pStubMsg);
2007 break;
2008 case FC_BOGUS_ARRAY:
2009 def = *(const WORD *)(pFormat + 2);
2010 pFormat += 4;
2011 conformance_present = IsConformanceOrVariancePresent(pFormat);
2012 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2013 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2014 if (conformance_present) WriteConformance(pStubMsg);
2015 break;
2016 default:
2017 ERR("unknown array format 0x%x\n", fc);
2018 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2022 static inline void array_write_variance_and_marshall(
2023 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
2024 PFORMAT_STRING pFormat, unsigned char fHasPointers)
2026 DWORD i, size;
2027 DWORD esize;
2028 unsigned char alignment;
2030 switch (fc)
2032 case FC_CARRAY:
2033 esize = *(const WORD*)(pFormat+2);
2034 alignment = pFormat[1] + 1;
2036 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2038 align_pointer_clear(&pStubMsg->Buffer, alignment);
2040 size = safe_multiply(esize, pStubMsg->MaxCount);
2041 if (fHasPointers)
2042 pStubMsg->BufferMark = pStubMsg->Buffer;
2043 safe_copy_to_buffer(pStubMsg, pMemory, size);
2045 if (fHasPointers)
2046 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2047 break;
2048 case FC_CVARRAY:
2049 esize = *(const WORD*)(pFormat+2);
2050 alignment = pFormat[1] + 1;
2052 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2053 pFormat = SkipVariance(pStubMsg, pFormat);
2055 WriteVariance(pStubMsg);
2057 align_pointer_clear(&pStubMsg->Buffer, alignment);
2059 size = safe_multiply(esize, pStubMsg->ActualCount);
2061 if (fHasPointers)
2062 pStubMsg->BufferMark = pStubMsg->Buffer;
2063 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
2065 if (fHasPointers)
2066 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2067 break;
2068 case FC_C_CSTRING:
2069 case FC_C_WSTRING:
2070 if (fc == FC_C_CSTRING)
2071 esize = 1;
2072 else
2073 esize = 2;
2075 WriteVariance(pStubMsg);
2077 size = safe_multiply(esize, pStubMsg->ActualCount);
2078 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2079 break;
2080 case FC_BOGUS_ARRAY:
2081 alignment = pFormat[1] + 1;
2082 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2083 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg);
2084 pFormat = SkipVariance(pStubMsg, pFormat);
2086 align_pointer_clear(&pStubMsg->Buffer, alignment);
2088 size = pStubMsg->ActualCount;
2089 for (i = 0; i < size; i++)
2090 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2091 break;
2092 default:
2093 ERR("unknown array format 0x%x\n", fc);
2094 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2098 static inline ULONG array_read_conformance(
2099 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
2101 DWORD def, esize;
2103 switch (fc)
2105 case FC_CARRAY:
2106 esize = *(const WORD*)(pFormat+2);
2107 pFormat = ReadConformance(pStubMsg, pFormat+4);
2108 return safe_multiply(esize, pStubMsg->MaxCount);
2109 case FC_CVARRAY:
2110 esize = *(const WORD*)(pFormat+2);
2111 pFormat = ReadConformance(pStubMsg, pFormat+4);
2112 return safe_multiply(esize, pStubMsg->MaxCount);
2113 case FC_C_CSTRING:
2114 case FC_C_WSTRING:
2115 if (fc == FC_C_CSTRING)
2116 esize = 1;
2117 else
2118 esize = 2;
2120 if (pFormat[1] == FC_STRING_SIZED)
2121 ReadConformance(pStubMsg, pFormat + 2);
2122 else
2123 ReadConformance(pStubMsg, NULL);
2124 return safe_multiply(esize, pStubMsg->MaxCount);
2125 case FC_BOGUS_ARRAY:
2126 def = *(const WORD *)(pFormat + 2);
2127 pFormat += 4;
2128 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2129 else
2131 pStubMsg->MaxCount = def;
2132 pFormat = SkipConformance( pStubMsg, pFormat );
2134 pFormat = SkipVariance( pStubMsg, pFormat );
2136 esize = ComplexStructSize(pStubMsg, pFormat);
2137 return safe_multiply(pStubMsg->MaxCount, esize);
2138 default:
2139 ERR("unknown array format 0x%x\n", fc);
2140 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2144 static inline ULONG array_read_variance_and_unmarshall(
2145 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2146 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2147 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2149 ULONG bufsize, memsize;
2150 WORD esize;
2151 unsigned char alignment;
2152 unsigned char *saved_buffer, *pMemory;
2153 ULONG i, offset, count;
2155 switch (fc)
2157 case FC_CARRAY:
2158 esize = *(const WORD*)(pFormat+2);
2159 alignment = pFormat[1] + 1;
2161 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2163 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2165 align_pointer(&pStubMsg->Buffer, alignment);
2167 if (fUnmarshall)
2169 if (fMustAlloc)
2170 *ppMemory = NdrAllocateZero(pStubMsg, memsize);
2171 else
2173 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2174 /* for servers, we just point straight into the RPC buffer */
2175 *ppMemory = pStubMsg->Buffer;
2178 saved_buffer = pStubMsg->Buffer;
2179 safe_buffer_increment(pStubMsg, bufsize);
2181 pStubMsg->BufferMark = saved_buffer;
2182 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2184 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2185 if (*ppMemory != saved_buffer)
2186 memcpy(*ppMemory, saved_buffer, bufsize);
2188 return bufsize;
2189 case FC_CVARRAY:
2190 esize = *(const WORD*)(pFormat+2);
2191 alignment = pFormat[1] + 1;
2193 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2195 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2197 align_pointer(&pStubMsg->Buffer, alignment);
2199 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2200 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2202 if (fUnmarshall)
2204 offset = pStubMsg->Offset;
2206 if (!fMustAlloc && !*ppMemory)
2207 fMustAlloc = TRUE;
2208 if (fMustAlloc)
2209 *ppMemory = NdrAllocateZero(pStubMsg, memsize);
2210 saved_buffer = pStubMsg->Buffer;
2211 safe_buffer_increment(pStubMsg, bufsize);
2213 pStubMsg->BufferMark = saved_buffer;
2214 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2215 fMustAlloc);
2217 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2219 return bufsize;
2220 case FC_C_CSTRING:
2221 case FC_C_WSTRING:
2222 if (fc == FC_C_CSTRING)
2223 esize = 1;
2224 else
2225 esize = 2;
2227 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2229 if (pFormat[1] != FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2231 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2232 pStubMsg->ActualCount, pStubMsg->MaxCount);
2233 RpcRaiseException(RPC_S_INVALID_BOUND);
2235 if (pStubMsg->Offset)
2237 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2238 RpcRaiseException(RPC_S_INVALID_BOUND);
2241 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2242 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2244 validate_string_data(pStubMsg, bufsize, esize);
2246 if (fUnmarshall)
2248 if (fMustAlloc)
2249 *ppMemory = NdrAllocate(pStubMsg, memsize);
2250 else
2252 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2253 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2254 /* if the data in the RPC buffer is big enough, we just point
2255 * straight into it */
2256 *ppMemory = pStubMsg->Buffer;
2257 else if (!*ppMemory)
2258 *ppMemory = NdrAllocate(pStubMsg, memsize);
2261 if (*ppMemory == pStubMsg->Buffer)
2262 safe_buffer_increment(pStubMsg, bufsize);
2263 else
2264 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2266 if (*pFormat == FC_C_CSTRING)
2267 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2268 else
2269 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2271 return bufsize;
2273 case FC_BOGUS_ARRAY:
2274 alignment = pFormat[1] + 1;
2275 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2276 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2278 esize = ComplexStructSize(pStubMsg, pFormat);
2279 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2281 assert( fUnmarshall );
2283 if (!fMustAlloc && !*ppMemory)
2284 fMustAlloc = TRUE;
2285 if (fMustAlloc)
2286 *ppMemory = NdrAllocateZero(pStubMsg, memsize);
2288 align_pointer(&pStubMsg->Buffer, alignment);
2289 saved_buffer = pStubMsg->Buffer;
2291 pMemory = *ppMemory;
2292 count = pStubMsg->ActualCount;
2293 for (i = 0; i < count; i++)
2294 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2295 return pStubMsg->Buffer - saved_buffer;
2297 default:
2298 ERR("unknown array format 0x%x\n", fc);
2299 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2303 static inline void array_memory_size(
2304 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2305 unsigned char fHasPointers)
2307 ULONG i, count, SavedMemorySize;
2308 ULONG bufsize, memsize;
2309 DWORD esize;
2310 unsigned char alignment;
2312 switch (fc)
2314 case FC_CARRAY:
2315 esize = *(const WORD*)(pFormat+2);
2316 alignment = pFormat[1] + 1;
2318 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2320 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2321 pStubMsg->MemorySize += memsize;
2323 align_pointer(&pStubMsg->Buffer, alignment);
2324 if (fHasPointers)
2325 pStubMsg->BufferMark = pStubMsg->Buffer;
2326 safe_buffer_increment(pStubMsg, bufsize);
2328 if (fHasPointers)
2329 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2330 break;
2331 case FC_CVARRAY:
2332 esize = *(const WORD*)(pFormat+2);
2333 alignment = pFormat[1] + 1;
2335 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2337 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2339 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2340 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2341 pStubMsg->MemorySize += memsize;
2343 align_pointer(&pStubMsg->Buffer, alignment);
2344 if (fHasPointers)
2345 pStubMsg->BufferMark = pStubMsg->Buffer;
2346 safe_buffer_increment(pStubMsg, bufsize);
2348 if (fHasPointers)
2349 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2350 break;
2351 case FC_C_CSTRING:
2352 case FC_C_WSTRING:
2353 if (fc == FC_C_CSTRING)
2354 esize = 1;
2355 else
2356 esize = 2;
2358 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2360 if (pFormat[1] != FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2362 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2363 pStubMsg->ActualCount, pStubMsg->MaxCount);
2364 RpcRaiseException(RPC_S_INVALID_BOUND);
2366 if (pStubMsg->Offset)
2368 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2369 RpcRaiseException(RPC_S_INVALID_BOUND);
2372 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2373 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2375 validate_string_data(pStubMsg, bufsize, esize);
2377 safe_buffer_increment(pStubMsg, bufsize);
2378 pStubMsg->MemorySize += memsize;
2379 break;
2380 case FC_BOGUS_ARRAY:
2381 alignment = pFormat[1] + 1;
2382 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2383 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2385 align_pointer(&pStubMsg->Buffer, alignment);
2387 SavedMemorySize = pStubMsg->MemorySize;
2389 esize = ComplexStructSize(pStubMsg, pFormat);
2390 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2392 count = pStubMsg->ActualCount;
2393 for (i = 0; i < count; i++)
2394 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2396 pStubMsg->MemorySize = SavedMemorySize + memsize;
2397 break;
2398 default:
2399 ERR("unknown array format 0x%x\n", fc);
2400 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2404 static inline void array_free(
2405 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2406 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2408 DWORD i, count;
2410 switch (fc)
2412 case FC_CARRAY:
2413 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2414 if (fHasPointers)
2415 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2416 break;
2417 case FC_CVARRAY:
2418 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2419 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2420 if (fHasPointers)
2421 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2422 break;
2423 case FC_C_CSTRING:
2424 case FC_C_WSTRING:
2425 /* No embedded pointers so nothing to do */
2426 break;
2427 case FC_BOGUS_ARRAY:
2428 count = *(const WORD *)(pFormat + 2);
2429 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2430 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2432 count = pStubMsg->ActualCount;
2433 for (i = 0; i < count; i++)
2434 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2435 break;
2436 default:
2437 ERR("unknown array format 0x%x\n", fc);
2438 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2443 * NdrConformantString:
2445 * What MS calls a ConformantString is, in DCE terminology,
2446 * a Varying-Conformant String.
2448 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2449 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2450 * into unmarshalled string)
2451 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2453 * data: CHARTYPE[maxlen]
2455 * ], where CHARTYPE is the appropriate character type (specified externally)
2459 /***********************************************************************
2460 * NdrConformantStringMarshall [RPCRT4.@]
2462 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2463 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2465 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2467 if (pFormat[0] != FC_C_CSTRING && pFormat[0] != FC_C_WSTRING) {
2468 ERR("Unhandled string type: %#x\n", pFormat[0]);
2469 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2472 /* allow compiler to optimise inline function by passing constant into
2473 * these functions */
2474 if (pFormat[0] == FC_C_CSTRING) {
2475 array_compute_and_write_conformance(FC_C_CSTRING, pStubMsg, pszMessage,
2476 pFormat);
2477 array_write_variance_and_marshall(FC_C_CSTRING, pStubMsg, pszMessage,
2478 pFormat, TRUE /* fHasPointers */);
2479 } else {
2480 array_compute_and_write_conformance(FC_C_WSTRING, pStubMsg, pszMessage,
2481 pFormat);
2482 array_write_variance_and_marshall(FC_C_WSTRING, pStubMsg, pszMessage,
2483 pFormat, TRUE /* fHasPointers */);
2486 return NULL;
2489 /***********************************************************************
2490 * NdrConformantStringBufferSize [RPCRT4.@]
2492 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2493 unsigned char* pMemory, PFORMAT_STRING pFormat)
2495 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2497 if (pFormat[0] != FC_C_CSTRING && pFormat[0] != FC_C_WSTRING) {
2498 ERR("Unhandled string type: %#x\n", pFormat[0]);
2499 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2502 /* allow compiler to optimise inline function by passing constant into
2503 * these functions */
2504 if (pFormat[0] == FC_C_CSTRING) {
2505 array_compute_and_size_conformance(FC_C_CSTRING, pStubMsg, pMemory,
2506 pFormat);
2507 array_buffer_size(FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2508 TRUE /* fHasPointers */);
2509 } else {
2510 array_compute_and_size_conformance(FC_C_WSTRING, pStubMsg, pMemory,
2511 pFormat);
2512 array_buffer_size(FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2513 TRUE /* fHasPointers */);
2517 /************************************************************************
2518 * NdrConformantStringMemorySize [RPCRT4.@]
2520 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2521 PFORMAT_STRING pFormat )
2523 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2525 if (pFormat[0] != FC_C_CSTRING && pFormat[0] != FC_C_WSTRING) {
2526 ERR("Unhandled string type: %#x\n", pFormat[0]);
2527 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2530 /* allow compiler to optimise inline function by passing constant into
2531 * these functions */
2532 if (pFormat[0] == FC_C_CSTRING) {
2533 array_read_conformance(FC_C_CSTRING, pStubMsg, pFormat);
2534 array_memory_size(FC_C_CSTRING, pStubMsg, pFormat,
2535 TRUE /* fHasPointers */);
2536 } else {
2537 array_read_conformance(FC_C_WSTRING, pStubMsg, pFormat);
2538 array_memory_size(FC_C_WSTRING, pStubMsg, pFormat,
2539 TRUE /* fHasPointers */);
2542 return pStubMsg->MemorySize;
2545 /************************************************************************
2546 * NdrConformantStringUnmarshall [RPCRT4.@]
2548 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2549 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2551 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2552 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2554 if (pFormat[0] != FC_C_CSTRING && pFormat[0] != FC_C_WSTRING) {
2555 ERR("Unhandled string type: %#x\n", *pFormat);
2556 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2559 /* allow compiler to optimise inline function by passing constant into
2560 * these functions */
2561 if (pFormat[0] == FC_C_CSTRING) {
2562 array_read_conformance(FC_C_CSTRING, pStubMsg, pFormat);
2563 array_read_variance_and_unmarshall(FC_C_CSTRING, pStubMsg, ppMemory,
2564 pFormat, fMustAlloc,
2565 TRUE /* fUseBufferMemoryServer */,
2566 TRUE /* fUnmarshall */);
2567 } else {
2568 array_read_conformance(FC_C_WSTRING, pStubMsg, pFormat);
2569 array_read_variance_and_unmarshall(FC_C_WSTRING, pStubMsg, ppMemory,
2570 pFormat, fMustAlloc,
2571 TRUE /* fUseBufferMemoryServer */,
2572 TRUE /* fUnmarshall */);
2575 return NULL;
2578 /***********************************************************************
2579 * NdrNonConformantStringMarshall [RPCRT4.@]
2581 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2582 unsigned char *pMemory,
2583 PFORMAT_STRING pFormat)
2585 ULONG esize, size, maxsize;
2587 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2589 maxsize = *(const USHORT *)&pFormat[2];
2591 if (*pFormat == FC_CSTRING)
2593 ULONG i = 0;
2594 const char *str = (const char *)pMemory;
2595 while (i < maxsize && str[i]) i++;
2596 TRACE("string=%s\n", debugstr_an(str, i));
2597 pStubMsg->ActualCount = i + 1;
2598 esize = 1;
2600 else if (*pFormat == FC_WSTRING)
2602 ULONG i = 0;
2603 const WCHAR *str = (const WCHAR *)pMemory;
2604 while (i < maxsize && str[i]) i++;
2605 TRACE("string=%s\n", debugstr_wn(str, i));
2606 pStubMsg->ActualCount = i + 1;
2607 esize = 2;
2609 else
2611 ERR("Unhandled string type: %#x\n", *pFormat);
2612 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2615 pStubMsg->Offset = 0;
2616 WriteVariance(pStubMsg);
2618 size = safe_multiply(esize, pStubMsg->ActualCount);
2619 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2621 return NULL;
2624 /***********************************************************************
2625 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2627 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2628 unsigned char **ppMemory,
2629 PFORMAT_STRING pFormat,
2630 unsigned char fMustAlloc)
2632 ULONG bufsize, memsize, esize, maxsize;
2634 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2635 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2637 maxsize = *(const USHORT *)&pFormat[2];
2639 ReadVariance(pStubMsg, NULL, maxsize);
2640 if (pStubMsg->Offset)
2642 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2643 RpcRaiseException(RPC_S_INVALID_BOUND);
2646 if (*pFormat == FC_CSTRING) esize = 1;
2647 else if (*pFormat == FC_WSTRING) esize = 2;
2648 else
2650 ERR("Unhandled string type: %#x\n", *pFormat);
2651 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2654 memsize = esize * maxsize;
2655 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2657 validate_string_data(pStubMsg, bufsize, esize);
2659 if (!fMustAlloc && !*ppMemory)
2660 fMustAlloc = TRUE;
2661 if (fMustAlloc)
2662 *ppMemory = NdrAllocate(pStubMsg, memsize);
2664 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2666 if (*pFormat == FC_CSTRING) {
2667 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2669 else if (*pFormat == FC_WSTRING) {
2670 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2673 return NULL;
2676 /***********************************************************************
2677 * NdrNonConformantStringBufferSize [RPCRT4.@]
2679 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2680 unsigned char *pMemory,
2681 PFORMAT_STRING pFormat)
2683 ULONG esize, maxsize;
2685 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2687 maxsize = *(const USHORT *)&pFormat[2];
2689 SizeVariance(pStubMsg);
2691 if (*pFormat == FC_CSTRING)
2693 ULONG i = 0;
2694 const char *str = (const char *)pMemory;
2695 while (i < maxsize && str[i]) i++;
2696 TRACE("string=%s\n", debugstr_an(str, i));
2697 pStubMsg->ActualCount = i + 1;
2698 esize = 1;
2700 else if (*pFormat == FC_WSTRING)
2702 ULONG i = 0;
2703 const WCHAR *str = (const WCHAR *)pMemory;
2704 while (i < maxsize && str[i]) i++;
2705 TRACE("string=%s\n", debugstr_wn(str, i));
2706 pStubMsg->ActualCount = i + 1;
2707 esize = 2;
2709 else
2711 ERR("Unhandled string type: %#x\n", *pFormat);
2712 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2715 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2718 /***********************************************************************
2719 * NdrNonConformantStringMemorySize [RPCRT4.@]
2721 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2722 PFORMAT_STRING pFormat)
2724 ULONG bufsize, memsize, esize, maxsize;
2726 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2728 maxsize = *(const USHORT *)&pFormat[2];
2730 ReadVariance(pStubMsg, NULL, maxsize);
2732 if (pStubMsg->Offset)
2734 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2735 RpcRaiseException(RPC_S_INVALID_BOUND);
2738 if (*pFormat == FC_CSTRING) esize = 1;
2739 else if (*pFormat == FC_WSTRING) esize = 2;
2740 else
2742 ERR("Unhandled string type: %#x\n", *pFormat);
2743 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2746 memsize = esize * maxsize;
2747 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2749 validate_string_data(pStubMsg, bufsize, esize);
2751 safe_buffer_increment(pStubMsg, bufsize);
2752 pStubMsg->MemorySize += memsize;
2754 return pStubMsg->MemorySize;
2757 /* Complex types */
2759 #include "pshpack1.h"
2760 typedef struct
2762 unsigned char type;
2763 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2764 ULONG low_value;
2765 ULONG high_value;
2766 } NDR_RANGE;
2767 #include "poppack.h"
2769 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2770 PFORMAT_STRING pFormat)
2772 switch (*pFormat) {
2773 case FC_STRUCT:
2774 case FC_PSTRUCT:
2775 case FC_CSTRUCT:
2776 case FC_BOGUS_STRUCT:
2777 case FC_SMFARRAY:
2778 case FC_SMVARRAY:
2779 case FC_CSTRING:
2780 return *(const WORD*)&pFormat[2];
2781 case FC_LGFARRAY:
2782 case FC_LGVARRAY:
2783 return *(const ULONG*)&pFormat[2];
2784 case FC_USER_MARSHAL:
2785 return *(const WORD*)&pFormat[4];
2786 case FC_RANGE: {
2787 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2788 case FC_BYTE:
2789 case FC_CHAR:
2790 case FC_SMALL:
2791 case FC_USMALL:
2792 return sizeof(UCHAR);
2793 case FC_WCHAR:
2794 case FC_SHORT:
2795 case FC_USHORT:
2796 return sizeof(USHORT);
2797 case FC_LONG:
2798 case FC_ULONG:
2799 case FC_ENUM32:
2800 return sizeof(ULONG);
2801 case FC_FLOAT:
2802 return sizeof(float);
2803 case FC_DOUBLE:
2804 return sizeof(double);
2805 case FC_HYPER:
2806 return sizeof(ULONGLONG);
2807 case FC_ENUM16:
2808 return sizeof(UINT);
2809 default:
2810 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2811 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2814 case FC_NON_ENCAPSULATED_UNION:
2815 pFormat += 2;
2816 pFormat = SkipConformance(pStubMsg, pFormat);
2817 pFormat += *(const SHORT*)pFormat;
2818 return *(const SHORT*)pFormat;
2819 case FC_IP:
2820 return sizeof(void *);
2821 case FC_WSTRING:
2822 return *(const WORD*)&pFormat[2] * 2;
2823 default:
2824 FIXME("unhandled embedded type %02x\n", *pFormat);
2826 return 0;
2830 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2831 PFORMAT_STRING pFormat)
2833 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2835 if (!m)
2837 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2838 return 0;
2841 return m(pStubMsg, pFormat);
2845 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2846 unsigned char *pMemory,
2847 PFORMAT_STRING pFormat,
2848 PFORMAT_STRING pPointer)
2850 unsigned char *mem_base = pMemory;
2851 PFORMAT_STRING desc;
2852 NDR_MARSHALL m;
2853 ULONG size;
2855 while (*pFormat != FC_END) {
2856 switch (*pFormat) {
2857 case FC_BYTE:
2858 case FC_CHAR:
2859 case FC_SMALL:
2860 case FC_USMALL:
2861 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2862 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2863 pMemory += 1;
2864 break;
2865 case FC_WCHAR:
2866 case FC_SHORT:
2867 case FC_USHORT:
2868 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2869 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2870 pMemory += 2;
2871 break;
2872 case FC_ENUM16:
2874 USHORT val = *(DWORD *)pMemory;
2875 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2876 if (32767 < *(DWORD*)pMemory)
2877 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2878 safe_copy_to_buffer(pStubMsg, &val, 2);
2879 pMemory += 4;
2880 break;
2882 case FC_LONG:
2883 case FC_ULONG:
2884 case FC_ENUM32:
2885 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2886 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2887 pMemory += 4;
2888 break;
2889 case FC_INT3264:
2890 case FC_UINT3264:
2892 UINT val = *(UINT_PTR *)pMemory;
2893 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2894 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2895 pMemory += sizeof(UINT_PTR);
2896 break;
2898 case FC_FLOAT:
2899 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2900 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2901 pMemory += sizeof(float);
2902 break;
2903 case FC_HYPER:
2904 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2905 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2906 pMemory += 8;
2907 break;
2908 case FC_DOUBLE:
2909 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2910 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2911 pMemory += sizeof(double);
2912 break;
2913 case FC_RP:
2914 case FC_UP:
2915 case FC_OP:
2916 case FC_FP:
2917 case FC_POINTER:
2919 unsigned char *saved_buffer;
2920 BOOL pointer_buffer_mark_set = FALSE;
2921 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2922 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2923 if (*pFormat != FC_POINTER)
2924 pPointer = pFormat;
2925 if (*pPointer != FC_RP)
2926 align_pointer_clear(&pStubMsg->Buffer, 4);
2927 saved_buffer = pStubMsg->Buffer;
2928 if (pStubMsg->PointerBufferMark)
2930 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2931 pStubMsg->PointerBufferMark = NULL;
2932 pointer_buffer_mark_set = TRUE;
2934 else if (*pPointer != FC_RP)
2935 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2936 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2937 if (pointer_buffer_mark_set)
2939 STD_OVERFLOW_CHECK(pStubMsg);
2940 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2941 pStubMsg->Buffer = saved_buffer;
2942 if (*pPointer != FC_RP)
2943 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2945 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2946 if (*pFormat == FC_POINTER)
2947 pPointer += 4;
2948 else
2949 pFormat += 4;
2950 pMemory += sizeof(void *);
2951 break;
2953 case FC_ALIGNM2:
2954 align_pointer_offset(&pMemory, mem_base, 2);
2955 break;
2956 case FC_ALIGNM4:
2957 align_pointer_offset(&pMemory, mem_base, 4);
2958 break;
2959 case FC_ALIGNM8:
2960 align_pointer_offset(&pMemory, mem_base, 8);
2961 break;
2962 case FC_STRUCTPAD1:
2963 case FC_STRUCTPAD2:
2964 case FC_STRUCTPAD3:
2965 case FC_STRUCTPAD4:
2966 case FC_STRUCTPAD5:
2967 case FC_STRUCTPAD6:
2968 case FC_STRUCTPAD7:
2969 pMemory += *pFormat - FC_STRUCTPAD1 + 1;
2970 break;
2971 case FC_EMBEDDED_COMPLEX:
2972 pMemory += pFormat[1];
2973 pFormat += 2;
2974 desc = pFormat + *(const SHORT*)pFormat;
2975 size = EmbeddedComplexSize(pStubMsg, desc);
2976 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2977 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2978 if (m)
2980 /* for some reason interface pointers aren't generated as
2981 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
2982 * they still need the dereferencing treatment that pointers are
2983 * given */
2984 if (*desc == FC_IP)
2985 m(pStubMsg, *(unsigned char **)pMemory, desc);
2986 else
2987 m(pStubMsg, pMemory, desc);
2989 else FIXME("no marshaller for embedded type %02x\n", *desc);
2990 pMemory += size;
2991 pFormat += 2;
2992 continue;
2993 case FC_PAD:
2994 break;
2995 default:
2996 FIXME("unhandled format 0x%02x\n", *pFormat);
2998 pFormat++;
3001 return pMemory;
3004 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3005 unsigned char *pMemory,
3006 PFORMAT_STRING pFormat,
3007 PFORMAT_STRING pPointer,
3008 unsigned char fMustAlloc)
3010 unsigned char *mem_base = pMemory;
3011 PFORMAT_STRING desc;
3012 NDR_UNMARSHALL m;
3013 ULONG size;
3015 while (*pFormat != FC_END) {
3016 switch (*pFormat) {
3017 case FC_BYTE:
3018 case FC_CHAR:
3019 case FC_SMALL:
3020 case FC_USMALL:
3021 safe_copy_from_buffer(pStubMsg, pMemory, 1);
3022 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
3023 pMemory += 1;
3024 break;
3025 case FC_WCHAR:
3026 case FC_SHORT:
3027 case FC_USHORT:
3028 safe_copy_from_buffer(pStubMsg, pMemory, 2);
3029 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
3030 pMemory += 2;
3031 break;
3032 case FC_ENUM16:
3034 WORD val;
3035 safe_copy_from_buffer(pStubMsg, &val, 2);
3036 *(DWORD*)pMemory = val;
3037 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
3038 if (32767 < *(DWORD*)pMemory)
3039 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3040 pMemory += 4;
3041 break;
3043 case FC_LONG:
3044 case FC_ULONG:
3045 case FC_ENUM32:
3046 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3047 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3048 pMemory += 4;
3049 break;
3050 case FC_INT3264:
3052 INT val;
3053 safe_copy_from_buffer(pStubMsg, &val, 4);
3054 *(INT_PTR *)pMemory = val;
3055 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3056 pMemory += sizeof(INT_PTR);
3057 break;
3059 case FC_UINT3264:
3061 UINT val;
3062 safe_copy_from_buffer(pStubMsg, &val, 4);
3063 *(UINT_PTR *)pMemory = val;
3064 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3065 pMemory += sizeof(UINT_PTR);
3066 break;
3068 case FC_FLOAT:
3069 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3070 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3071 pMemory += sizeof(float);
3072 break;
3073 case FC_HYPER:
3074 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3075 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3076 pMemory += 8;
3077 break;
3078 case FC_DOUBLE:
3079 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3080 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3081 pMemory += sizeof(double);
3082 break;
3083 case FC_RP:
3084 case FC_UP:
3085 case FC_OP:
3086 case FC_FP:
3087 case FC_POINTER:
3089 unsigned char *saved_buffer;
3090 BOOL pointer_buffer_mark_set = FALSE;
3091 TRACE("pointer => %p\n", pMemory);
3092 if (*pFormat != FC_POINTER)
3093 pPointer = pFormat;
3094 if (*pPointer != FC_RP)
3095 align_pointer(&pStubMsg->Buffer, 4);
3096 saved_buffer = pStubMsg->Buffer;
3097 if (pStubMsg->PointerBufferMark)
3099 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3100 pStubMsg->PointerBufferMark = NULL;
3101 pointer_buffer_mark_set = TRUE;
3103 else if (*pPointer != FC_RP)
3104 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3106 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3107 if (pointer_buffer_mark_set)
3109 STD_OVERFLOW_CHECK(pStubMsg);
3110 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3111 pStubMsg->Buffer = saved_buffer;
3112 if (*pPointer != FC_RP)
3113 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3115 if (*pFormat == FC_POINTER)
3116 pPointer += 4;
3117 else
3118 pFormat += 4;
3119 pMemory += sizeof(void *);
3120 break;
3122 case FC_ALIGNM2:
3123 align_pointer_offset_clear(&pMemory, mem_base, 2);
3124 break;
3125 case FC_ALIGNM4:
3126 align_pointer_offset_clear(&pMemory, mem_base, 4);
3127 break;
3128 case FC_ALIGNM8:
3129 align_pointer_offset_clear(&pMemory, mem_base, 8);
3130 break;
3131 case FC_STRUCTPAD1:
3132 case FC_STRUCTPAD2:
3133 case FC_STRUCTPAD3:
3134 case FC_STRUCTPAD4:
3135 case FC_STRUCTPAD5:
3136 case FC_STRUCTPAD6:
3137 case FC_STRUCTPAD7:
3138 memset(pMemory, 0, *pFormat - FC_STRUCTPAD1 + 1);
3139 pMemory += *pFormat - FC_STRUCTPAD1 + 1;
3140 break;
3141 case FC_EMBEDDED_COMPLEX:
3142 pMemory += pFormat[1];
3143 pFormat += 2;
3144 desc = pFormat + *(const SHORT*)pFormat;
3145 size = EmbeddedComplexSize(pStubMsg, desc);
3146 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3147 if (fMustAlloc)
3148 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3149 * since the type is part of the memory block that is encompassed by
3150 * the whole complex type. Memory is forced to allocate when pointers
3151 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3152 * clearing the memory we pass in to the unmarshaller */
3153 memset(pMemory, 0, size);
3154 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3155 if (m)
3157 /* for some reason interface pointers aren't generated as
3158 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3159 * they still need the dereferencing treatment that pointers are
3160 * given */
3161 if (*desc == FC_IP)
3162 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3163 else
3164 m(pStubMsg, &pMemory, desc, FALSE);
3166 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3167 pMemory += size;
3168 pFormat += 2;
3169 continue;
3170 case FC_PAD:
3171 break;
3172 default:
3173 FIXME("unhandled format %d\n", *pFormat);
3175 pFormat++;
3178 return pMemory;
3181 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3182 unsigned char *pMemory,
3183 PFORMAT_STRING pFormat,
3184 PFORMAT_STRING pPointer)
3186 unsigned char *mem_base = pMemory;
3187 PFORMAT_STRING desc;
3188 NDR_BUFFERSIZE m;
3189 ULONG size;
3191 while (*pFormat != FC_END) {
3192 switch (*pFormat) {
3193 case FC_BYTE:
3194 case FC_CHAR:
3195 case FC_SMALL:
3196 case FC_USMALL:
3197 safe_buffer_length_increment(pStubMsg, 1);
3198 pMemory += 1;
3199 break;
3200 case FC_WCHAR:
3201 case FC_SHORT:
3202 case FC_USHORT:
3203 safe_buffer_length_increment(pStubMsg, 2);
3204 pMemory += 2;
3205 break;
3206 case FC_ENUM16:
3207 safe_buffer_length_increment(pStubMsg, 2);
3208 pMemory += 4;
3209 break;
3210 case FC_LONG:
3211 case FC_ULONG:
3212 case FC_ENUM32:
3213 case FC_FLOAT:
3214 safe_buffer_length_increment(pStubMsg, 4);
3215 pMemory += 4;
3216 break;
3217 case FC_INT3264:
3218 case FC_UINT3264:
3219 safe_buffer_length_increment(pStubMsg, 4);
3220 pMemory += sizeof(INT_PTR);
3221 break;
3222 case FC_HYPER:
3223 case FC_DOUBLE:
3224 safe_buffer_length_increment(pStubMsg, 8);
3225 pMemory += 8;
3226 break;
3227 case FC_RP:
3228 case FC_UP:
3229 case FC_OP:
3230 case FC_FP:
3231 case FC_POINTER:
3232 if (*pFormat != FC_POINTER)
3233 pPointer = pFormat;
3234 if (!pStubMsg->IgnoreEmbeddedPointers)
3236 int saved_buffer_length = pStubMsg->BufferLength;
3237 pStubMsg->BufferLength = pStubMsg->PointerLength;
3238 pStubMsg->PointerLength = 0;
3239 if(!pStubMsg->BufferLength)
3240 ERR("BufferLength == 0??\n");
3241 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3242 pStubMsg->PointerLength = pStubMsg->BufferLength;
3243 pStubMsg->BufferLength = saved_buffer_length;
3245 if (*pPointer != FC_RP)
3247 align_length(&pStubMsg->BufferLength, 4);
3248 safe_buffer_length_increment(pStubMsg, 4);
3250 if (*pFormat == FC_POINTER)
3251 pPointer += 4;
3252 else
3253 pFormat += 4;
3254 pMemory += sizeof(void*);
3255 break;
3256 case FC_ALIGNM2:
3257 align_pointer_offset(&pMemory, mem_base, 2);
3258 break;
3259 case FC_ALIGNM4:
3260 align_pointer_offset(&pMemory, mem_base, 4);
3261 break;
3262 case FC_ALIGNM8:
3263 align_pointer_offset(&pMemory, mem_base, 8);
3264 break;
3265 case FC_STRUCTPAD1:
3266 case FC_STRUCTPAD2:
3267 case FC_STRUCTPAD3:
3268 case FC_STRUCTPAD4:
3269 case FC_STRUCTPAD5:
3270 case FC_STRUCTPAD6:
3271 case FC_STRUCTPAD7:
3272 pMemory += *pFormat - FC_STRUCTPAD1 + 1;
3273 break;
3274 case FC_EMBEDDED_COMPLEX:
3275 pMemory += pFormat[1];
3276 pFormat += 2;
3277 desc = pFormat + *(const SHORT*)pFormat;
3278 size = EmbeddedComplexSize(pStubMsg, desc);
3279 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3280 if (m)
3282 /* for some reason interface pointers aren't generated as
3283 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3284 * they still need the dereferencing treatment that pointers are
3285 * given */
3286 if (*desc == FC_IP)
3287 m(pStubMsg, *(unsigned char **)pMemory, desc);
3288 else
3289 m(pStubMsg, pMemory, desc);
3291 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3292 pMemory += size;
3293 pFormat += 2;
3294 continue;
3295 case FC_PAD:
3296 break;
3297 default:
3298 FIXME("unhandled format 0x%02x\n", *pFormat);
3300 pFormat++;
3303 return pMemory;
3306 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3307 unsigned char *pMemory,
3308 PFORMAT_STRING pFormat,
3309 PFORMAT_STRING pPointer)
3311 unsigned char *mem_base = pMemory;
3312 PFORMAT_STRING desc;
3313 NDR_FREE m;
3314 ULONG size;
3316 while (*pFormat != FC_END) {
3317 switch (*pFormat) {
3318 case FC_BYTE:
3319 case FC_CHAR:
3320 case FC_SMALL:
3321 case FC_USMALL:
3322 pMemory += 1;
3323 break;
3324 case FC_WCHAR:
3325 case FC_SHORT:
3326 case FC_USHORT:
3327 pMemory += 2;
3328 break;
3329 case FC_LONG:
3330 case FC_ULONG:
3331 case FC_ENUM16:
3332 case FC_ENUM32:
3333 case FC_FLOAT:
3334 pMemory += 4;
3335 break;
3336 case FC_INT3264:
3337 case FC_UINT3264:
3338 pMemory += sizeof(INT_PTR);
3339 break;
3340 case FC_HYPER:
3341 case FC_DOUBLE:
3342 pMemory += 8;
3343 break;
3344 case FC_RP:
3345 case FC_UP:
3346 case FC_OP:
3347 case FC_FP:
3348 case FC_POINTER:
3349 if (*pFormat != FC_POINTER)
3350 pPointer = pFormat;
3351 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3352 if (*pFormat == FC_POINTER)
3353 pPointer += 4;
3354 else
3355 pFormat += 4;
3356 pMemory += sizeof(void *);
3357 break;
3358 case FC_ALIGNM2:
3359 align_pointer_offset(&pMemory, mem_base, 2);
3360 break;
3361 case FC_ALIGNM4:
3362 align_pointer_offset(&pMemory, mem_base, 4);
3363 break;
3364 case FC_ALIGNM8:
3365 align_pointer_offset(&pMemory, mem_base, 8);
3366 break;
3367 case FC_STRUCTPAD1:
3368 case FC_STRUCTPAD2:
3369 case FC_STRUCTPAD3:
3370 case FC_STRUCTPAD4:
3371 case FC_STRUCTPAD5:
3372 case FC_STRUCTPAD6:
3373 case FC_STRUCTPAD7:
3374 pMemory += *pFormat - FC_STRUCTPAD1 + 1;
3375 break;
3376 case FC_EMBEDDED_COMPLEX:
3377 pMemory += pFormat[1];
3378 pFormat += 2;
3379 desc = pFormat + *(const SHORT*)pFormat;
3380 size = EmbeddedComplexSize(pStubMsg, desc);
3381 m = NdrFreer[*desc & NDR_TABLE_MASK];
3382 if (m)
3384 /* for some reason interface pointers aren't generated as
3385 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3386 * they still need the dereferencing treatment that pointers are
3387 * given */
3388 if (*desc == FC_IP)
3389 m(pStubMsg, *(unsigned char **)pMemory, desc);
3390 else
3391 m(pStubMsg, pMemory, desc);
3393 pMemory += size;
3394 pFormat += 2;
3395 continue;
3396 case FC_PAD:
3397 break;
3398 default:
3399 FIXME("unhandled format 0x%02x\n", *pFormat);
3401 pFormat++;
3404 return pMemory;
3407 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3408 PFORMAT_STRING pFormat,
3409 PFORMAT_STRING pPointer)
3411 PFORMAT_STRING desc;
3412 ULONG size = 0;
3414 while (*pFormat != FC_END) {
3415 switch (*pFormat) {
3416 case FC_BYTE:
3417 case FC_CHAR:
3418 case FC_SMALL:
3419 case FC_USMALL:
3420 size += 1;
3421 safe_buffer_increment(pStubMsg, 1);
3422 break;
3423 case FC_WCHAR:
3424 case FC_SHORT:
3425 case FC_USHORT:
3426 size += 2;
3427 safe_buffer_increment(pStubMsg, 2);
3428 break;
3429 case FC_ENUM16:
3430 size += 4;
3431 safe_buffer_increment(pStubMsg, 2);
3432 break;
3433 case FC_LONG:
3434 case FC_ULONG:
3435 case FC_ENUM32:
3436 case FC_FLOAT:
3437 size += 4;
3438 safe_buffer_increment(pStubMsg, 4);
3439 break;
3440 case FC_INT3264:
3441 case FC_UINT3264:
3442 size += sizeof(INT_PTR);
3443 safe_buffer_increment(pStubMsg, 4);
3444 break;
3445 case FC_HYPER:
3446 case FC_DOUBLE:
3447 size += 8;
3448 safe_buffer_increment(pStubMsg, 8);
3449 break;
3450 case FC_RP:
3451 case FC_UP:
3452 case FC_OP:
3453 case FC_FP:
3454 case FC_POINTER:
3456 unsigned char *saved_buffer;
3457 BOOL pointer_buffer_mark_set = FALSE;
3458 if (*pFormat != FC_POINTER)
3459 pPointer = pFormat;
3460 if (*pPointer != FC_RP)
3461 align_pointer(&pStubMsg->Buffer, 4);
3462 saved_buffer = pStubMsg->Buffer;
3463 if (pStubMsg->PointerBufferMark)
3465 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3466 pStubMsg->PointerBufferMark = NULL;
3467 pointer_buffer_mark_set = TRUE;
3469 else if (*pPointer != FC_RP)
3470 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3472 if (!pStubMsg->IgnoreEmbeddedPointers)
3473 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3474 if (pointer_buffer_mark_set)
3476 STD_OVERFLOW_CHECK(pStubMsg);
3477 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3478 pStubMsg->Buffer = saved_buffer;
3479 if (*pPointer != FC_RP)
3480 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3482 if (*pFormat == FC_POINTER)
3483 pPointer += 4;
3484 else
3485 pFormat += 4;
3486 size += sizeof(void *);
3487 break;
3489 case FC_ALIGNM2:
3490 align_length(&size, 2);
3491 break;
3492 case FC_ALIGNM4:
3493 align_length(&size, 4);
3494 break;
3495 case FC_ALIGNM8:
3496 align_length(&size, 8);
3497 break;
3498 case FC_STRUCTPAD1:
3499 case FC_STRUCTPAD2:
3500 case FC_STRUCTPAD3:
3501 case FC_STRUCTPAD4:
3502 case FC_STRUCTPAD5:
3503 case FC_STRUCTPAD6:
3504 case FC_STRUCTPAD7:
3505 size += *pFormat - FC_STRUCTPAD1 + 1;
3506 break;
3507 case FC_EMBEDDED_COMPLEX:
3508 size += pFormat[1];
3509 pFormat += 2;
3510 desc = pFormat + *(const SHORT*)pFormat;
3511 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3512 pFormat += 2;
3513 continue;
3514 case FC_PAD:
3515 break;
3516 default:
3517 FIXME("unhandled format 0x%02x\n", *pFormat);
3519 pFormat++;
3522 return size;
3525 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3527 PFORMAT_STRING desc;
3528 ULONG size = 0;
3530 while (*pFormat != FC_END) {
3531 switch (*pFormat) {
3532 case FC_BYTE:
3533 case FC_CHAR:
3534 case FC_SMALL:
3535 case FC_USMALL:
3536 size += 1;
3537 break;
3538 case FC_WCHAR:
3539 case FC_SHORT:
3540 case FC_USHORT:
3541 size += 2;
3542 break;
3543 case FC_LONG:
3544 case FC_ULONG:
3545 case FC_ENUM16:
3546 case FC_ENUM32:
3547 case FC_FLOAT:
3548 size += 4;
3549 break;
3550 case FC_INT3264:
3551 case FC_UINT3264:
3552 size += sizeof(INT_PTR);
3553 break;
3554 case FC_HYPER:
3555 case FC_DOUBLE:
3556 size += 8;
3557 break;
3558 case FC_RP:
3559 case FC_UP:
3560 case FC_OP:
3561 case FC_FP:
3562 case FC_POINTER:
3563 size += sizeof(void *);
3564 if (*pFormat != FC_POINTER)
3565 pFormat += 4;
3566 break;
3567 case FC_ALIGNM2:
3568 align_length(&size, 2);
3569 break;
3570 case FC_ALIGNM4:
3571 align_length(&size, 4);
3572 break;
3573 case FC_ALIGNM8:
3574 align_length(&size, 8);
3575 break;
3576 case FC_STRUCTPAD1:
3577 case FC_STRUCTPAD2:
3578 case FC_STRUCTPAD3:
3579 case FC_STRUCTPAD4:
3580 case FC_STRUCTPAD5:
3581 case FC_STRUCTPAD6:
3582 case FC_STRUCTPAD7:
3583 size += *pFormat - FC_STRUCTPAD1 + 1;
3584 break;
3585 case FC_EMBEDDED_COMPLEX:
3586 size += pFormat[1];
3587 pFormat += 2;
3588 desc = pFormat + *(const SHORT*)pFormat;
3589 size += EmbeddedComplexSize(pStubMsg, desc);
3590 pFormat += 2;
3591 continue;
3592 case FC_PAD:
3593 break;
3594 default:
3595 FIXME("unhandled format 0x%02x\n", *pFormat);
3597 pFormat++;
3600 return size;
3603 /***********************************************************************
3604 * NdrComplexStructMarshall [RPCRT4.@]
3606 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3607 unsigned char *pMemory,
3608 PFORMAT_STRING pFormat)
3610 PFORMAT_STRING conf_array = NULL;
3611 PFORMAT_STRING pointer_desc = NULL;
3612 unsigned char *OldMemory = pStubMsg->Memory;
3613 BOOL pointer_buffer_mark_set = FALSE;
3614 ULONG count = 0;
3615 ULONG max_count = 0;
3616 ULONG offset = 0;
3618 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3620 if (!pStubMsg->PointerBufferMark)
3622 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3623 /* save buffer length */
3624 ULONG saved_buffer_length = pStubMsg->BufferLength;
3626 /* get the buffer pointer after complex array data, but before
3627 * pointer data */
3628 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3629 pStubMsg->IgnoreEmbeddedPointers = 1;
3630 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3631 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3633 /* save it for use by embedded pointer code later */
3634 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3635 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3636 pointer_buffer_mark_set = TRUE;
3638 /* restore the original buffer length */
3639 pStubMsg->BufferLength = saved_buffer_length;
3642 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3644 pFormat += 4;
3645 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3646 pFormat += 2;
3647 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3648 pFormat += 2;
3650 pStubMsg->Memory = pMemory;
3652 if (conf_array)
3654 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3655 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3656 pMemory + struct_size, conf_array);
3657 /* these could be changed in ComplexMarshall so save them for later */
3658 max_count = pStubMsg->MaxCount;
3659 count = pStubMsg->ActualCount;
3660 offset = pStubMsg->Offset;
3663 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3665 if (conf_array)
3667 pStubMsg->MaxCount = max_count;
3668 pStubMsg->ActualCount = count;
3669 pStubMsg->Offset = offset;
3670 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3671 conf_array, TRUE /* fHasPointers */);
3674 pStubMsg->Memory = OldMemory;
3676 if (pointer_buffer_mark_set)
3678 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3679 pStubMsg->PointerBufferMark = NULL;
3682 STD_OVERFLOW_CHECK(pStubMsg);
3684 return NULL;
3687 /***********************************************************************
3688 * NdrComplexStructUnmarshall [RPCRT4.@]
3690 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3691 unsigned char **ppMemory,
3692 PFORMAT_STRING pFormat,
3693 unsigned char fMustAlloc)
3695 unsigned size = *(const WORD*)(pFormat+2);
3696 PFORMAT_STRING conf_array = NULL;
3697 PFORMAT_STRING pointer_desc = NULL;
3698 unsigned char *pMemory;
3699 BOOL pointer_buffer_mark_set = FALSE;
3700 ULONG count = 0;
3701 ULONG max_count = 0;
3702 ULONG offset = 0;
3703 ULONG array_size = 0;
3705 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3707 if (!pStubMsg->PointerBufferMark)
3709 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3710 /* save buffer pointer */
3711 unsigned char *saved_buffer = pStubMsg->Buffer;
3713 /* get the buffer pointer after complex array data, but before
3714 * pointer data */
3715 pStubMsg->IgnoreEmbeddedPointers = 1;
3716 NdrComplexStructMemorySize(pStubMsg, pFormat);
3717 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3719 /* save it for use by embedded pointer code later */
3720 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3721 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3722 pointer_buffer_mark_set = TRUE;
3724 /* restore the original buffer */
3725 pStubMsg->Buffer = saved_buffer;
3728 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3730 pFormat += 4;
3731 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3732 pFormat += 2;
3733 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3734 pFormat += 2;
3736 if (conf_array)
3738 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3739 size += array_size;
3741 /* these could be changed in ComplexMarshall so save them for later */
3742 max_count = pStubMsg->MaxCount;
3743 count = pStubMsg->ActualCount;
3744 offset = pStubMsg->Offset;
3747 if (!fMustAlloc && !*ppMemory)
3748 fMustAlloc = TRUE;
3749 if (fMustAlloc)
3750 *ppMemory = NdrAllocateZero(pStubMsg, size);
3752 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3754 if (conf_array)
3756 pStubMsg->MaxCount = max_count;
3757 pStubMsg->ActualCount = count;
3758 pStubMsg->Offset = offset;
3759 if (fMustAlloc)
3760 memset(pMemory, 0, array_size);
3761 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3762 conf_array, FALSE,
3763 FALSE /* fUseBufferMemoryServer */,
3764 TRUE /* fUnmarshall */);
3767 if (pointer_buffer_mark_set)
3769 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3770 pStubMsg->PointerBufferMark = NULL;
3773 return NULL;
3776 /***********************************************************************
3777 * NdrComplexStructBufferSize [RPCRT4.@]
3779 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3780 unsigned char *pMemory,
3781 PFORMAT_STRING pFormat)
3783 PFORMAT_STRING conf_array = NULL;
3784 PFORMAT_STRING pointer_desc = NULL;
3785 unsigned char *OldMemory = pStubMsg->Memory;
3786 int pointer_length_set = 0;
3787 ULONG count = 0;
3788 ULONG max_count = 0;
3789 ULONG offset = 0;
3791 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3793 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3795 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3797 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3798 ULONG saved_buffer_length = pStubMsg->BufferLength;
3800 /* get the buffer length after complex struct data, but before
3801 * pointer data */
3802 pStubMsg->IgnoreEmbeddedPointers = 1;
3803 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3804 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3806 /* save it for use by embedded pointer code later */
3807 pStubMsg->PointerLength = pStubMsg->BufferLength;
3808 pointer_length_set = 1;
3809 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3811 /* restore the original buffer length */
3812 pStubMsg->BufferLength = saved_buffer_length;
3815 pFormat += 4;
3816 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3817 pFormat += 2;
3818 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3819 pFormat += 2;
3821 pStubMsg->Memory = pMemory;
3823 if (conf_array)
3825 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3826 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3827 conf_array);
3829 /* these could be changed in ComplexMarshall so save them for later */
3830 max_count = pStubMsg->MaxCount;
3831 count = pStubMsg->ActualCount;
3832 offset = pStubMsg->Offset;
3835 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3837 if (conf_array)
3839 pStubMsg->MaxCount = max_count;
3840 pStubMsg->ActualCount = count;
3841 pStubMsg->Offset = offset;
3842 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3843 TRUE /* fHasPointers */);
3846 pStubMsg->Memory = OldMemory;
3848 if(pointer_length_set)
3850 pStubMsg->BufferLength = pStubMsg->PointerLength;
3851 pStubMsg->PointerLength = 0;
3856 /***********************************************************************
3857 * NdrComplexStructMemorySize [RPCRT4.@]
3859 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3860 PFORMAT_STRING pFormat)
3862 unsigned size = *(const WORD*)(pFormat+2);
3863 PFORMAT_STRING conf_array = NULL;
3864 PFORMAT_STRING pointer_desc = NULL;
3865 ULONG count = 0;
3866 ULONG max_count = 0;
3867 ULONG offset = 0;
3869 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3871 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3873 pFormat += 4;
3874 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3875 pFormat += 2;
3876 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3877 pFormat += 2;
3879 if (conf_array)
3881 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3883 /* these could be changed in ComplexStructMemorySize so save them for
3884 * later */
3885 max_count = pStubMsg->MaxCount;
3886 count = pStubMsg->ActualCount;
3887 offset = pStubMsg->Offset;
3890 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3892 if (conf_array)
3894 pStubMsg->MaxCount = max_count;
3895 pStubMsg->ActualCount = count;
3896 pStubMsg->Offset = offset;
3897 array_memory_size(conf_array[0], pStubMsg, conf_array,
3898 TRUE /* fHasPointers */);
3901 return size;
3904 /***********************************************************************
3905 * NdrComplexStructFree [RPCRT4.@]
3907 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3908 unsigned char *pMemory,
3909 PFORMAT_STRING pFormat)
3911 PFORMAT_STRING conf_array = NULL;
3912 PFORMAT_STRING pointer_desc = NULL;
3913 unsigned char *OldMemory = pStubMsg->Memory;
3915 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3917 pFormat += 4;
3918 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3919 pFormat += 2;
3920 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3921 pFormat += 2;
3923 pStubMsg->Memory = pMemory;
3925 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3927 if (conf_array)
3928 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3929 TRUE /* fHasPointers */);
3931 pStubMsg->Memory = OldMemory;
3934 /***********************************************************************
3935 * NdrConformantArrayMarshall [RPCRT4.@]
3937 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3938 unsigned char *pMemory,
3939 PFORMAT_STRING pFormat)
3941 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3942 if (pFormat[0] != FC_CARRAY)
3944 ERR("invalid format = 0x%x\n", pFormat[0]);
3945 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3948 array_compute_and_write_conformance(FC_CARRAY, pStubMsg, pMemory,
3949 pFormat);
3950 array_write_variance_and_marshall(FC_CARRAY, pStubMsg, pMemory, pFormat,
3951 TRUE /* fHasPointers */);
3953 return NULL;
3956 /***********************************************************************
3957 * NdrConformantArrayUnmarshall [RPCRT4.@]
3959 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3960 unsigned char **ppMemory,
3961 PFORMAT_STRING pFormat,
3962 unsigned char fMustAlloc)
3964 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3965 if (pFormat[0] != FC_CARRAY)
3967 ERR("invalid format = 0x%x\n", pFormat[0]);
3968 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3971 array_read_conformance(FC_CARRAY, pStubMsg, pFormat);
3972 array_read_variance_and_unmarshall(FC_CARRAY, pStubMsg, ppMemory, pFormat,
3973 fMustAlloc,
3974 TRUE /* fUseBufferMemoryServer */,
3975 TRUE /* fUnmarshall */);
3977 return NULL;
3980 /***********************************************************************
3981 * NdrConformantArrayBufferSize [RPCRT4.@]
3983 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3984 unsigned char *pMemory,
3985 PFORMAT_STRING pFormat)
3987 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3988 if (pFormat[0] != FC_CARRAY)
3990 ERR("invalid format = 0x%x\n", pFormat[0]);
3991 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3994 array_compute_and_size_conformance(FC_CARRAY, pStubMsg, pMemory, pFormat);
3995 array_buffer_size(FC_CARRAY, pStubMsg, pMemory, pFormat,
3996 TRUE /* fHasPointers */);
3999 /***********************************************************************
4000 * NdrConformantArrayMemorySize [RPCRT4.@]
4002 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4003 PFORMAT_STRING pFormat)
4005 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4006 if (pFormat[0] != FC_CARRAY)
4008 ERR("invalid format = 0x%x\n", pFormat[0]);
4009 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4012 array_read_conformance(FC_CARRAY, pStubMsg, pFormat);
4013 array_memory_size(FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4015 return pStubMsg->MemorySize;
4018 /***********************************************************************
4019 * NdrConformantArrayFree [RPCRT4.@]
4021 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4022 unsigned char *pMemory,
4023 PFORMAT_STRING pFormat)
4025 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4026 if (pFormat[0] != FC_CARRAY)
4028 ERR("invalid format = 0x%x\n", pFormat[0]);
4029 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4032 array_free(FC_CARRAY, pStubMsg, pMemory, pFormat,
4033 TRUE /* fHasPointers */);
4037 /***********************************************************************
4038 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4040 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
4041 unsigned char* pMemory,
4042 PFORMAT_STRING pFormat )
4044 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4046 if (pFormat[0] != FC_CVARRAY)
4048 ERR("invalid format type %x\n", pFormat[0]);
4049 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4050 return NULL;
4053 array_compute_and_write_conformance(FC_CVARRAY, pStubMsg, pMemory,
4054 pFormat);
4055 array_write_variance_and_marshall(FC_CVARRAY, pStubMsg, pMemory,
4056 pFormat, TRUE /* fHasPointers */);
4058 return NULL;
4062 /***********************************************************************
4063 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4065 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4066 unsigned char** ppMemory,
4067 PFORMAT_STRING pFormat,
4068 unsigned char fMustAlloc )
4070 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4072 if (pFormat[0] != FC_CVARRAY)
4074 ERR("invalid format type %x\n", pFormat[0]);
4075 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4076 return NULL;
4079 array_read_conformance(FC_CVARRAY, pStubMsg, pFormat);
4080 array_read_variance_and_unmarshall(FC_CVARRAY, pStubMsg, ppMemory,
4081 pFormat, fMustAlloc,
4082 TRUE /* fUseBufferMemoryServer */,
4083 TRUE /* fUnmarshall */);
4085 return NULL;
4089 /***********************************************************************
4090 * NdrConformantVaryingArrayFree [RPCRT4.@]
4092 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4093 unsigned char* pMemory,
4094 PFORMAT_STRING pFormat )
4096 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4098 if (pFormat[0] != FC_CVARRAY)
4100 ERR("invalid format type %x\n", pFormat[0]);
4101 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4102 return;
4105 array_free(FC_CVARRAY, pStubMsg, pMemory, pFormat,
4106 TRUE /* fHasPointers */);
4110 /***********************************************************************
4111 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4113 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4114 unsigned char* pMemory, PFORMAT_STRING pFormat )
4116 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4118 if (pFormat[0] != FC_CVARRAY)
4120 ERR("invalid format type %x\n", pFormat[0]);
4121 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4122 return;
4125 array_compute_and_size_conformance(FC_CVARRAY, pStubMsg, pMemory,
4126 pFormat);
4127 array_buffer_size(FC_CVARRAY, pStubMsg, pMemory, pFormat,
4128 TRUE /* fHasPointers */);
4132 /***********************************************************************
4133 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4135 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4136 PFORMAT_STRING pFormat )
4138 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4140 if (pFormat[0] != FC_CVARRAY)
4142 ERR("invalid format type %x\n", pFormat[0]);
4143 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4144 return pStubMsg->MemorySize;
4147 array_read_conformance(FC_CVARRAY, pStubMsg, pFormat);
4148 array_memory_size(FC_CVARRAY, pStubMsg, pFormat,
4149 TRUE /* fHasPointers */);
4151 return pStubMsg->MemorySize;
4155 /***********************************************************************
4156 * NdrComplexArrayMarshall [RPCRT4.@]
4158 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4159 unsigned char *pMemory,
4160 PFORMAT_STRING pFormat)
4162 BOOL pointer_buffer_mark_set = FALSE;
4164 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4166 if (pFormat[0] != FC_BOGUS_ARRAY)
4168 ERR("invalid format type %x\n", pFormat[0]);
4169 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4170 return NULL;
4173 if (!pStubMsg->PointerBufferMark)
4175 /* save buffer fields that may be changed by buffer sizer functions
4176 * and that may be needed later on */
4177 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4178 ULONG saved_buffer_length = pStubMsg->BufferLength;
4179 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4180 ULONG saved_offset = pStubMsg->Offset;
4181 ULONG saved_actual_count = pStubMsg->ActualCount;
4183 /* get the buffer pointer after complex array data, but before
4184 * pointer data */
4185 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4186 pStubMsg->IgnoreEmbeddedPointers = 1;
4187 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4188 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4190 /* save it for use by embedded pointer code later */
4191 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4192 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4193 pointer_buffer_mark_set = TRUE;
4195 /* restore fields */
4196 pStubMsg->ActualCount = saved_actual_count;
4197 pStubMsg->Offset = saved_offset;
4198 pStubMsg->MaxCount = saved_max_count;
4199 pStubMsg->BufferLength = saved_buffer_length;
4202 array_compute_and_write_conformance(FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4203 array_write_variance_and_marshall(FC_BOGUS_ARRAY, pStubMsg,
4204 pMemory, pFormat, TRUE /* fHasPointers */);
4206 STD_OVERFLOW_CHECK(pStubMsg);
4208 if (pointer_buffer_mark_set)
4210 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4211 pStubMsg->PointerBufferMark = NULL;
4214 return NULL;
4217 /***********************************************************************
4218 * NdrComplexArrayUnmarshall [RPCRT4.@]
4220 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4221 unsigned char **ppMemory,
4222 PFORMAT_STRING pFormat,
4223 unsigned char fMustAlloc)
4225 unsigned char *saved_buffer;
4226 BOOL pointer_buffer_mark_set = FALSE;
4227 int saved_ignore_embedded;
4229 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4231 if (pFormat[0] != FC_BOGUS_ARRAY)
4233 ERR("invalid format type %x\n", pFormat[0]);
4234 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4235 return NULL;
4238 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4239 /* save buffer pointer */
4240 saved_buffer = pStubMsg->Buffer;
4241 /* get the buffer pointer after complex array data, but before
4242 * pointer data */
4243 pStubMsg->IgnoreEmbeddedPointers = 1;
4244 pStubMsg->MemorySize = 0;
4245 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4246 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4248 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4249 if (!pStubMsg->PointerBufferMark)
4251 /* save it for use by embedded pointer code later */
4252 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4253 pointer_buffer_mark_set = TRUE;
4255 /* restore the original buffer */
4256 pStubMsg->Buffer = saved_buffer;
4258 array_read_conformance(FC_BOGUS_ARRAY, pStubMsg, pFormat);
4259 array_read_variance_and_unmarshall(FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4260 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4262 if (pointer_buffer_mark_set)
4264 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4265 pStubMsg->PointerBufferMark = NULL;
4268 return NULL;
4271 /***********************************************************************
4272 * NdrComplexArrayBufferSize [RPCRT4.@]
4274 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4275 unsigned char *pMemory,
4276 PFORMAT_STRING pFormat)
4278 int pointer_length_set = 0;
4280 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4282 if (pFormat[0] != FC_BOGUS_ARRAY)
4284 ERR("invalid format type %x\n", pFormat[0]);
4285 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4286 return;
4289 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4291 /* save buffer fields that may be changed by buffer sizer functions
4292 * and that may be needed later on */
4293 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4294 ULONG saved_buffer_length = pStubMsg->BufferLength;
4295 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4296 ULONG saved_offset = pStubMsg->Offset;
4297 ULONG saved_actual_count = pStubMsg->ActualCount;
4299 /* get the buffer pointer after complex array data, but before
4300 * pointer data */
4301 pStubMsg->IgnoreEmbeddedPointers = 1;
4302 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4303 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4305 /* save it for use by embedded pointer code later */
4306 pStubMsg->PointerLength = pStubMsg->BufferLength;
4307 pointer_length_set = 1;
4309 /* restore fields */
4310 pStubMsg->ActualCount = saved_actual_count;
4311 pStubMsg->Offset = saved_offset;
4312 pStubMsg->MaxCount = saved_max_count;
4313 pStubMsg->BufferLength = saved_buffer_length;
4316 array_compute_and_size_conformance(FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4317 array_buffer_size(FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4319 if(pointer_length_set)
4321 pStubMsg->BufferLength = pStubMsg->PointerLength;
4322 pStubMsg->PointerLength = 0;
4326 /***********************************************************************
4327 * NdrComplexArrayMemorySize [RPCRT4.@]
4329 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4330 PFORMAT_STRING pFormat)
4332 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4334 if (pFormat[0] != FC_BOGUS_ARRAY)
4336 ERR("invalid format type %x\n", pFormat[0]);
4337 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4338 return 0;
4341 array_read_conformance(FC_BOGUS_ARRAY, pStubMsg, pFormat);
4342 array_memory_size(FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4343 return pStubMsg->MemorySize;
4346 /***********************************************************************
4347 * NdrComplexArrayFree [RPCRT4.@]
4349 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4350 unsigned char *pMemory,
4351 PFORMAT_STRING pFormat)
4353 ULONG i, count, def;
4355 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4357 if (pFormat[0] != FC_BOGUS_ARRAY)
4359 ERR("invalid format type %x\n", pFormat[0]);
4360 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4361 return;
4364 def = *(const WORD*)&pFormat[2];
4365 pFormat += 4;
4367 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4368 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4370 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4371 TRACE("variance = %d\n", pStubMsg->ActualCount);
4373 count = pStubMsg->ActualCount;
4374 for (i = 0; i < count; i++)
4375 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4378 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4379 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4380 USER_MARSHAL_CB *umcb)
4382 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4383 pStubMsg->RpcMsg->DataRepresentation);
4384 umcb->pStubMsg = pStubMsg;
4385 umcb->pReserve = NULL;
4386 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4387 umcb->CBType = cbtype;
4388 umcb->pFormat = pFormat;
4389 umcb->pTypeFormat = NULL /* FIXME */;
4392 #define USER_MARSHAL_PTR_PREFIX \
4393 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4394 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4396 /***********************************************************************
4397 * NdrUserMarshalMarshall [RPCRT4.@]
4399 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4400 unsigned char *pMemory,
4401 PFORMAT_STRING pFormat)
4403 unsigned flags = pFormat[1];
4404 unsigned index = *(const WORD*)&pFormat[2];
4405 unsigned char *saved_buffer = NULL;
4406 USER_MARSHAL_CB umcb;
4408 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4409 TRACE("index=%d\n", index);
4411 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4413 if (flags & USER_MARSHAL_POINTER)
4415 align_pointer_clear(&pStubMsg->Buffer, 4);
4416 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4417 pStubMsg->Buffer += 4;
4418 if (pStubMsg->PointerBufferMark)
4420 saved_buffer = pStubMsg->Buffer;
4421 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4422 pStubMsg->PointerBufferMark = NULL;
4424 align_pointer_clear(&pStubMsg->Buffer, 8);
4426 else
4427 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4429 pStubMsg->Buffer =
4430 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4431 &umcb.Flags, pStubMsg->Buffer, pMemory);
4433 if (saved_buffer)
4435 STD_OVERFLOW_CHECK(pStubMsg);
4436 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4437 pStubMsg->Buffer = saved_buffer;
4440 STD_OVERFLOW_CHECK(pStubMsg);
4442 return NULL;
4445 /***********************************************************************
4446 * NdrUserMarshalUnmarshall [RPCRT4.@]
4448 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4449 unsigned char **ppMemory,
4450 PFORMAT_STRING pFormat,
4451 unsigned char fMustAlloc)
4453 unsigned flags = pFormat[1];
4454 unsigned index = *(const WORD*)&pFormat[2];
4455 DWORD memsize = *(const WORD*)&pFormat[4];
4456 unsigned char *saved_buffer = NULL;
4457 USER_MARSHAL_CB umcb;
4459 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4460 TRACE("index=%d\n", index);
4462 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4464 if (flags & USER_MARSHAL_POINTER)
4466 align_pointer(&pStubMsg->Buffer, 4);
4467 /* skip pointer prefix */
4468 pStubMsg->Buffer += 4;
4469 if (pStubMsg->PointerBufferMark)
4471 saved_buffer = pStubMsg->Buffer;
4472 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4473 pStubMsg->PointerBufferMark = NULL;
4475 align_pointer(&pStubMsg->Buffer, 8);
4477 else
4478 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4480 if (!fMustAlloc && !*ppMemory)
4481 fMustAlloc = TRUE;
4482 if (fMustAlloc)
4484 *ppMemory = NdrAllocate(pStubMsg, memsize);
4485 memset(*ppMemory, 0, memsize);
4488 pStubMsg->Buffer =
4489 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4490 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4492 if (saved_buffer)
4494 STD_OVERFLOW_CHECK(pStubMsg);
4495 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4496 pStubMsg->Buffer = saved_buffer;
4499 return NULL;
4502 /***********************************************************************
4503 * NdrUserMarshalBufferSize [RPCRT4.@]
4505 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4506 unsigned char *pMemory,
4507 PFORMAT_STRING pFormat)
4509 unsigned flags = pFormat[1];
4510 unsigned index = *(const WORD*)&pFormat[2];
4511 DWORD bufsize = *(const WORD*)&pFormat[6];
4512 USER_MARSHAL_CB umcb;
4513 ULONG saved_buffer_length = 0;
4515 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4516 TRACE("index=%d\n", index);
4518 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4520 if (flags & USER_MARSHAL_POINTER)
4522 align_length(&pStubMsg->BufferLength, 4);
4523 /* skip pointer prefix */
4524 safe_buffer_length_increment(pStubMsg, 4);
4525 if (pStubMsg->IgnoreEmbeddedPointers)
4526 return;
4527 if (pStubMsg->PointerLength)
4529 saved_buffer_length = pStubMsg->BufferLength;
4530 pStubMsg->BufferLength = pStubMsg->PointerLength;
4531 pStubMsg->PointerLength = 0;
4533 align_length(&pStubMsg->BufferLength, 8);
4535 else
4536 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4538 if (bufsize) {
4539 TRACE("size=%d\n", bufsize);
4540 safe_buffer_length_increment(pStubMsg, bufsize);
4542 else
4543 pStubMsg->BufferLength =
4544 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4545 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4547 if (saved_buffer_length)
4549 pStubMsg->PointerLength = pStubMsg->BufferLength;
4550 pStubMsg->BufferLength = saved_buffer_length;
4555 /***********************************************************************
4556 * NdrUserMarshalMemorySize [RPCRT4.@]
4558 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4559 PFORMAT_STRING pFormat)
4561 unsigned flags = pFormat[1];
4562 unsigned index = *(const WORD*)&pFormat[2];
4563 DWORD memsize = *(const WORD*)&pFormat[4];
4564 DWORD bufsize = *(const WORD*)&pFormat[6];
4566 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4567 TRACE("index=%d\n", index);
4569 pStubMsg->MemorySize += memsize;
4571 if (flags & USER_MARSHAL_POINTER)
4573 align_pointer(&pStubMsg->Buffer, 4);
4574 /* skip pointer prefix */
4575 pStubMsg->Buffer += 4;
4576 if (pStubMsg->IgnoreEmbeddedPointers)
4577 return pStubMsg->MemorySize;
4578 align_pointer(&pStubMsg->Buffer, 8);
4580 else
4581 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4583 if (!bufsize)
4584 FIXME("not implemented for varying buffer size\n");
4586 pStubMsg->Buffer += bufsize;
4588 return pStubMsg->MemorySize;
4591 /***********************************************************************
4592 * NdrUserMarshalFree [RPCRT4.@]
4594 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4595 unsigned char *pMemory,
4596 PFORMAT_STRING pFormat)
4598 /* unsigned flags = pFormat[1]; */
4599 unsigned index = *(const WORD*)&pFormat[2];
4600 USER_MARSHAL_CB umcb;
4602 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4603 TRACE("index=%d\n", index);
4605 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4607 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4608 &umcb.Flags, pMemory);
4611 /***********************************************************************
4612 * NdrGetUserMarshalInfo [RPCRT4.@]
4614 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4616 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4618 TRACE("(%p,%u,%p)\n", flags, level, umi);
4620 if (level != 1)
4621 return RPC_S_INVALID_ARG;
4623 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4624 umi->InformationLevel = level;
4626 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4627 return RPC_S_INVALID_ARG;
4629 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4630 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4631 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4633 switch (umcb->CBType)
4635 case USER_MARSHAL_CB_MARSHALL:
4636 case USER_MARSHAL_CB_UNMARSHALL:
4638 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4639 unsigned char *buffer_start = msg->Buffer;
4640 unsigned char *buffer_end =
4641 (unsigned char *)msg->Buffer + msg->BufferLength;
4643 if (umcb->pStubMsg->Buffer < buffer_start ||
4644 umcb->pStubMsg->Buffer > buffer_end)
4645 return RPC_X_INVALID_BUFFER;
4647 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4648 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4649 break;
4651 case USER_MARSHAL_CB_BUFFER_SIZE:
4652 case USER_MARSHAL_CB_FREE:
4653 break;
4654 default:
4655 WARN("unrecognised CBType %d\n", umcb->CBType);
4658 return RPC_S_OK;
4661 /***********************************************************************
4662 * NdrClearOutParameters [RPCRT4.@]
4664 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4665 PFORMAT_STRING pFormat,
4666 void *ArgAddr)
4668 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4671 /***********************************************************************
4672 * NdrConvert [RPCRT4.@]
4674 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4676 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4677 /* FIXME: since this stub doesn't do any converting, the proper behavior
4678 is to raise an exception */
4681 /***********************************************************************
4682 * NdrConvert2 [RPCRT4.@]
4684 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4686 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4687 pStubMsg, pFormat, NumberParams);
4688 /* FIXME: since this stub doesn't do any converting, the proper behavior
4689 is to raise an exception */
4692 #include "pshpack1.h"
4693 typedef struct _NDR_CSTRUCT_FORMAT
4695 unsigned char type;
4696 unsigned char alignment;
4697 unsigned short memory_size;
4698 short offset_to_array_description;
4699 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4700 #include "poppack.h"
4702 /***********************************************************************
4703 * NdrConformantStructMarshall [RPCRT4.@]
4705 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4706 unsigned char *pMemory,
4707 PFORMAT_STRING pFormat)
4709 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4710 PFORMAT_STRING pCArrayFormat;
4711 ULONG esize, bufsize;
4713 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4715 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4716 if ((pCStructFormat->type != FC_CPSTRUCT) && (pCStructFormat->type != FC_CSTRUCT))
4718 ERR("invalid format type %x\n", pCStructFormat->type);
4719 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4720 return NULL;
4723 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4724 pCStructFormat->offset_to_array_description;
4725 if (*pCArrayFormat != FC_CARRAY)
4727 ERR("invalid array format type %x\n", pCStructFormat->type);
4728 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4729 return NULL;
4731 esize = *(const WORD*)(pCArrayFormat+2);
4733 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4734 pCArrayFormat + 4, 0);
4736 WriteConformance(pStubMsg);
4738 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4740 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4742 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4743 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4745 ERR("integer overflow of memory_size %u with bufsize %u\n",
4746 pCStructFormat->memory_size, bufsize);
4747 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4749 /* copy constant sized part of struct */
4750 pStubMsg->BufferMark = pStubMsg->Buffer;
4751 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4753 if (pCStructFormat->type == FC_CPSTRUCT)
4754 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4756 return NULL;
4759 /***********************************************************************
4760 * NdrConformantStructUnmarshall [RPCRT4.@]
4762 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4763 unsigned char **ppMemory,
4764 PFORMAT_STRING pFormat,
4765 unsigned char fMustAlloc)
4767 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4768 PFORMAT_STRING pCArrayFormat;
4769 ULONG esize, bufsize;
4770 unsigned char *saved_buffer;
4772 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4774 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4775 if ((pCStructFormat->type != FC_CPSTRUCT) && (pCStructFormat->type != FC_CSTRUCT))
4777 ERR("invalid format type %x\n", pCStructFormat->type);
4778 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4779 return NULL;
4781 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4782 pCStructFormat->offset_to_array_description;
4783 if (*pCArrayFormat != FC_CARRAY)
4785 ERR("invalid array format type %x\n", pCStructFormat->type);
4786 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4787 return NULL;
4789 esize = *(const WORD*)(pCArrayFormat+2);
4791 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4793 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4795 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4797 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4798 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4800 ERR("integer overflow of memory_size %u with bufsize %u\n",
4801 pCStructFormat->memory_size, bufsize);
4802 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4805 if (fMustAlloc)
4807 SIZE_T size = pCStructFormat->memory_size + bufsize;
4808 *ppMemory = NdrAllocateZero(pStubMsg, size);
4810 else
4812 if (!pStubMsg->IsClient && !*ppMemory)
4813 /* for servers, we just point straight into the RPC buffer */
4814 *ppMemory = pStubMsg->Buffer;
4817 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4818 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4819 if (pCStructFormat->type == FC_CPSTRUCT)
4820 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4822 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4823 if (*ppMemory != saved_buffer)
4824 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4826 return NULL;
4829 /***********************************************************************
4830 * NdrConformantStructBufferSize [RPCRT4.@]
4832 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4833 unsigned char *pMemory,
4834 PFORMAT_STRING pFormat)
4836 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4837 PFORMAT_STRING pCArrayFormat;
4838 ULONG esize;
4840 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4842 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4843 if ((pCStructFormat->type != FC_CPSTRUCT) && (pCStructFormat->type != FC_CSTRUCT))
4845 ERR("invalid format type %x\n", pCStructFormat->type);
4846 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4847 return;
4849 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4850 pCStructFormat->offset_to_array_description;
4851 if (*pCArrayFormat != FC_CARRAY)
4853 ERR("invalid array format type %x\n", pCStructFormat->type);
4854 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4855 return;
4857 esize = *(const WORD*)(pCArrayFormat+2);
4859 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4860 SizeConformance(pStubMsg);
4862 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4864 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4866 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4867 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4869 if (pCStructFormat->type == FC_CPSTRUCT)
4870 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4873 /***********************************************************************
4874 * NdrConformantStructMemorySize [RPCRT4.@]
4876 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4877 PFORMAT_STRING pFormat)
4879 FIXME("stub\n");
4880 return 0;
4883 /***********************************************************************
4884 * NdrConformantStructFree [RPCRT4.@]
4886 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4887 unsigned char *pMemory,
4888 PFORMAT_STRING pFormat)
4890 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4891 PFORMAT_STRING pCArrayFormat;
4893 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4895 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4896 if ((pCStructFormat->type != FC_CPSTRUCT) && (pCStructFormat->type != FC_CSTRUCT))
4898 ERR("invalid format type %x\n", pCStructFormat->type);
4899 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4900 return;
4903 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4904 pCStructFormat->offset_to_array_description;
4905 if (*pCArrayFormat != FC_CARRAY)
4907 ERR("invalid array format type %x\n", pCStructFormat->type);
4908 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4909 return;
4912 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4913 pCArrayFormat + 4, 0);
4915 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4917 /* copy constant sized part of struct */
4918 pStubMsg->BufferMark = pStubMsg->Buffer;
4920 if (pCStructFormat->type == FC_CPSTRUCT)
4921 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4924 /***********************************************************************
4925 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4927 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4928 unsigned char *pMemory,
4929 PFORMAT_STRING pFormat)
4931 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4932 PFORMAT_STRING pCVArrayFormat;
4934 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4936 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4937 if (pCVStructFormat->type != FC_CVSTRUCT)
4939 ERR("invalid format type %x\n", pCVStructFormat->type);
4940 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4941 return NULL;
4944 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4945 pCVStructFormat->offset_to_array_description;
4947 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4948 pMemory + pCVStructFormat->memory_size,
4949 pCVArrayFormat);
4951 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4953 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4955 /* write constant sized part */
4956 pStubMsg->BufferMark = pStubMsg->Buffer;
4957 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4959 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4960 pMemory + pCVStructFormat->memory_size,
4961 pCVArrayFormat, FALSE /* fHasPointers */);
4963 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4965 return NULL;
4968 /***********************************************************************
4969 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4971 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4972 unsigned char **ppMemory,
4973 PFORMAT_STRING pFormat,
4974 unsigned char fMustAlloc)
4976 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4977 PFORMAT_STRING pCVArrayFormat;
4978 ULONG memsize, bufsize;
4979 unsigned char *saved_buffer, *saved_array_buffer;
4980 ULONG offset;
4981 unsigned char *array_memory;
4983 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4985 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4986 if (pCVStructFormat->type != FC_CVSTRUCT)
4988 ERR("invalid format type %x\n", pCVStructFormat->type);
4989 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4990 return NULL;
4993 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4994 pCVStructFormat->offset_to_array_description;
4996 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4997 pCVArrayFormat);
4999 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5001 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5003 /* work out how much memory to allocate if we need to do so */
5004 if (!fMustAlloc && !*ppMemory)
5005 fMustAlloc = TRUE;
5006 if (fMustAlloc)
5008 SIZE_T size = pCVStructFormat->memory_size + memsize;
5009 *ppMemory = NdrAllocateZero(pStubMsg, size);
5012 /* mark the start of the constant data */
5013 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5014 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5016 array_memory = *ppMemory + pCVStructFormat->memory_size;
5017 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
5018 &array_memory, pCVArrayFormat,
5019 FALSE /* fMustAlloc */,
5020 FALSE /* fUseServerBufferMemory */,
5021 FALSE /* fUnmarshall */);
5023 /* save offset in case unmarshalling pointers changes it */
5024 offset = pStubMsg->Offset;
5026 /* mark the start of the array data */
5027 saved_array_buffer = pStubMsg->Buffer;
5028 safe_buffer_increment(pStubMsg, bufsize);
5030 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5032 /* copy the constant data */
5033 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
5034 /* copy the array data */
5035 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
5036 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
5037 saved_array_buffer, bufsize);
5039 if (*pCVArrayFormat == FC_C_CSTRING)
5040 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5041 else if (*pCVArrayFormat == FC_C_WSTRING)
5042 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5044 return NULL;
5047 /***********************************************************************
5048 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5050 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5051 unsigned char *pMemory,
5052 PFORMAT_STRING pFormat)
5054 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5055 PFORMAT_STRING pCVArrayFormat;
5057 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5059 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5060 if (pCVStructFormat->type != FC_CVSTRUCT)
5062 ERR("invalid format type %x\n", pCVStructFormat->type);
5063 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5064 return;
5067 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5068 pCVStructFormat->offset_to_array_description;
5069 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5070 pMemory + pCVStructFormat->memory_size,
5071 pCVArrayFormat);
5073 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5075 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5077 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5079 array_buffer_size(*pCVArrayFormat, pStubMsg,
5080 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5081 FALSE /* fHasPointers */);
5083 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5086 /***********************************************************************
5087 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5089 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5090 PFORMAT_STRING pFormat)
5092 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5093 PFORMAT_STRING pCVArrayFormat;
5095 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5097 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5098 if (pCVStructFormat->type != FC_CVSTRUCT)
5100 ERR("invalid format type %x\n", pCVStructFormat->type);
5101 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5102 return 0;
5105 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5106 pCVStructFormat->offset_to_array_description;
5107 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5109 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5111 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5113 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5114 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5115 FALSE /* fHasPointers */);
5117 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5119 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5121 return pStubMsg->MemorySize;
5124 /***********************************************************************
5125 * NdrConformantVaryingStructFree [RPCRT4.@]
5127 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5128 unsigned char *pMemory,
5129 PFORMAT_STRING pFormat)
5131 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5132 PFORMAT_STRING pCVArrayFormat;
5134 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5136 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5137 if (pCVStructFormat->type != FC_CVSTRUCT)
5139 ERR("invalid format type %x\n", pCVStructFormat->type);
5140 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5141 return;
5144 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5145 pCVStructFormat->offset_to_array_description;
5146 array_free(*pCVArrayFormat, pStubMsg,
5147 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5148 FALSE /* fHasPointers */);
5150 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5152 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5155 #include "pshpack1.h"
5156 typedef struct
5158 unsigned char type;
5159 unsigned char alignment;
5160 unsigned short total_size;
5161 } NDR_SMFARRAY_FORMAT;
5163 typedef struct
5165 unsigned char type;
5166 unsigned char alignment;
5167 ULONG total_size;
5168 } NDR_LGFARRAY_FORMAT;
5169 #include "poppack.h"
5171 /***********************************************************************
5172 * NdrFixedArrayMarshall [RPCRT4.@]
5174 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5175 unsigned char *pMemory,
5176 PFORMAT_STRING pFormat)
5178 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5179 ULONG total_size;
5181 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5183 if ((pSmFArrayFormat->type != FC_SMFARRAY) &&
5184 (pSmFArrayFormat->type != FC_LGFARRAY))
5186 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5187 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5188 return NULL;
5191 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5193 if (pSmFArrayFormat->type == FC_SMFARRAY)
5195 total_size = pSmFArrayFormat->total_size;
5196 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5198 else
5200 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5201 total_size = pLgFArrayFormat->total_size;
5202 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5205 pStubMsg->BufferMark = pStubMsg->Buffer;
5206 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5208 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5210 return NULL;
5213 /***********************************************************************
5214 * NdrFixedArrayUnmarshall [RPCRT4.@]
5216 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5217 unsigned char **ppMemory,
5218 PFORMAT_STRING pFormat,
5219 unsigned char fMustAlloc)
5221 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5222 ULONG total_size;
5223 unsigned char *saved_buffer;
5225 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5227 if ((pSmFArrayFormat->type != FC_SMFARRAY) &&
5228 (pSmFArrayFormat->type != FC_LGFARRAY))
5230 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5231 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5232 return NULL;
5235 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5237 if (pSmFArrayFormat->type == FC_SMFARRAY)
5239 total_size = pSmFArrayFormat->total_size;
5240 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5242 else
5244 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5245 total_size = pLgFArrayFormat->total_size;
5246 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5249 if (fMustAlloc)
5250 *ppMemory = NdrAllocateZero(pStubMsg, total_size);
5251 else
5253 if (!pStubMsg->IsClient && !*ppMemory)
5254 /* for servers, we just point straight into the RPC buffer */
5255 *ppMemory = pStubMsg->Buffer;
5258 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5259 safe_buffer_increment(pStubMsg, total_size);
5260 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5262 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5263 if (*ppMemory != saved_buffer)
5264 memcpy(*ppMemory, saved_buffer, total_size);
5266 return NULL;
5269 /***********************************************************************
5270 * NdrFixedArrayBufferSize [RPCRT4.@]
5272 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5273 unsigned char *pMemory,
5274 PFORMAT_STRING pFormat)
5276 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5277 ULONG total_size;
5279 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5281 if ((pSmFArrayFormat->type != FC_SMFARRAY) &&
5282 (pSmFArrayFormat->type != FC_LGFARRAY))
5284 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5285 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5286 return;
5289 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5291 if (pSmFArrayFormat->type == FC_SMFARRAY)
5293 total_size = pSmFArrayFormat->total_size;
5294 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5296 else
5298 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5299 total_size = pLgFArrayFormat->total_size;
5300 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5302 safe_buffer_length_increment(pStubMsg, total_size);
5304 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5307 /***********************************************************************
5308 * NdrFixedArrayMemorySize [RPCRT4.@]
5310 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5311 PFORMAT_STRING pFormat)
5313 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5314 ULONG total_size;
5316 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5318 if ((pSmFArrayFormat->type != FC_SMFARRAY) &&
5319 (pSmFArrayFormat->type != FC_LGFARRAY))
5321 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5322 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5323 return 0;
5326 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5328 if (pSmFArrayFormat->type == FC_SMFARRAY)
5330 total_size = pSmFArrayFormat->total_size;
5331 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5333 else
5335 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5336 total_size = pLgFArrayFormat->total_size;
5337 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5339 pStubMsg->BufferMark = pStubMsg->Buffer;
5340 safe_buffer_increment(pStubMsg, total_size);
5341 pStubMsg->MemorySize += total_size;
5343 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5345 return total_size;
5348 /***********************************************************************
5349 * NdrFixedArrayFree [RPCRT4.@]
5351 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5352 unsigned char *pMemory,
5353 PFORMAT_STRING pFormat)
5355 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5357 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5359 if ((pSmFArrayFormat->type != FC_SMFARRAY) &&
5360 (pSmFArrayFormat->type != FC_LGFARRAY))
5362 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5363 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5364 return;
5367 if (pSmFArrayFormat->type == FC_SMFARRAY)
5368 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5369 else
5371 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5372 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5375 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5378 /***********************************************************************
5379 * NdrVaryingArrayMarshall [RPCRT4.@]
5381 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5382 unsigned char *pMemory,
5383 PFORMAT_STRING pFormat)
5385 unsigned char alignment;
5386 DWORD elements, esize;
5387 ULONG bufsize;
5389 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5391 if ((pFormat[0] != FC_SMVARRAY) &&
5392 (pFormat[0] != FC_LGVARRAY))
5394 ERR("invalid format type %x\n", pFormat[0]);
5395 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5396 return NULL;
5399 alignment = pFormat[1] + 1;
5401 if (pFormat[0] == FC_SMVARRAY)
5403 pFormat += 2;
5404 pFormat += sizeof(WORD);
5405 elements = *(const WORD*)pFormat;
5406 pFormat += sizeof(WORD);
5408 else
5410 pFormat += 2;
5411 pFormat += sizeof(DWORD);
5412 elements = *(const DWORD*)pFormat;
5413 pFormat += sizeof(DWORD);
5416 esize = *(const WORD*)pFormat;
5417 pFormat += sizeof(WORD);
5419 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5420 if ((pStubMsg->ActualCount > elements) ||
5421 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5423 RpcRaiseException(RPC_S_INVALID_BOUND);
5424 return NULL;
5427 WriteVariance(pStubMsg);
5429 align_pointer_clear(&pStubMsg->Buffer, alignment);
5431 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5432 pStubMsg->BufferMark = pStubMsg->Buffer;
5433 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5435 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5437 return NULL;
5440 /***********************************************************************
5441 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5443 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5444 unsigned char **ppMemory,
5445 PFORMAT_STRING pFormat,
5446 unsigned char fMustAlloc)
5448 unsigned char alignment;
5449 DWORD size, elements, esize;
5450 ULONG bufsize;
5451 unsigned char *saved_buffer;
5452 ULONG offset;
5454 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5456 if ((pFormat[0] != FC_SMVARRAY) &&
5457 (pFormat[0] != FC_LGVARRAY))
5459 ERR("invalid format type %x\n", pFormat[0]);
5460 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5461 return NULL;
5464 alignment = pFormat[1] + 1;
5466 if (pFormat[0] == FC_SMVARRAY)
5468 pFormat += 2;
5469 size = *(const WORD*)pFormat;
5470 pFormat += sizeof(WORD);
5471 elements = *(const WORD*)pFormat;
5472 pFormat += sizeof(WORD);
5474 else
5476 pFormat += 2;
5477 size = *(const DWORD*)pFormat;
5478 pFormat += sizeof(DWORD);
5479 elements = *(const DWORD*)pFormat;
5480 pFormat += sizeof(DWORD);
5483 esize = *(const WORD*)pFormat;
5484 pFormat += sizeof(WORD);
5486 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5488 align_pointer(&pStubMsg->Buffer, alignment);
5490 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5491 offset = pStubMsg->Offset;
5493 if (!fMustAlloc && !*ppMemory)
5494 fMustAlloc = TRUE;
5495 if (fMustAlloc)
5496 *ppMemory = NdrAllocateZero(pStubMsg, size);
5497 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5498 safe_buffer_increment(pStubMsg, bufsize);
5500 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5502 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5504 return NULL;
5507 /***********************************************************************
5508 * NdrVaryingArrayBufferSize [RPCRT4.@]
5510 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5511 unsigned char *pMemory,
5512 PFORMAT_STRING pFormat)
5514 unsigned char alignment;
5515 DWORD elements, esize;
5517 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5519 if ((pFormat[0] != FC_SMVARRAY) &&
5520 (pFormat[0] != FC_LGVARRAY))
5522 ERR("invalid format type %x\n", pFormat[0]);
5523 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5524 return;
5527 alignment = pFormat[1] + 1;
5529 if (pFormat[0] == FC_SMVARRAY)
5531 pFormat += 2;
5532 pFormat += sizeof(WORD);
5533 elements = *(const WORD*)pFormat;
5534 pFormat += sizeof(WORD);
5536 else
5538 pFormat += 2;
5539 pFormat += sizeof(DWORD);
5540 elements = *(const DWORD*)pFormat;
5541 pFormat += sizeof(DWORD);
5544 esize = *(const WORD*)pFormat;
5545 pFormat += sizeof(WORD);
5547 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5548 if ((pStubMsg->ActualCount > elements) ||
5549 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5551 RpcRaiseException(RPC_S_INVALID_BOUND);
5552 return;
5555 SizeVariance(pStubMsg);
5557 align_length(&pStubMsg->BufferLength, alignment);
5559 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5561 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5564 /***********************************************************************
5565 * NdrVaryingArrayMemorySize [RPCRT4.@]
5567 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5568 PFORMAT_STRING pFormat)
5570 unsigned char alignment;
5571 DWORD size, elements, esize;
5573 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5575 if ((pFormat[0] != FC_SMVARRAY) &&
5576 (pFormat[0] != FC_LGVARRAY))
5578 ERR("invalid format type %x\n", pFormat[0]);
5579 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5580 return 0;
5583 alignment = pFormat[1] + 1;
5585 if (pFormat[0] == FC_SMVARRAY)
5587 pFormat += 2;
5588 size = *(const WORD*)pFormat;
5589 pFormat += sizeof(WORD);
5590 elements = *(const WORD*)pFormat;
5591 pFormat += sizeof(WORD);
5593 else
5595 pFormat += 2;
5596 size = *(const DWORD*)pFormat;
5597 pFormat += sizeof(DWORD);
5598 elements = *(const DWORD*)pFormat;
5599 pFormat += sizeof(DWORD);
5602 esize = *(const WORD*)pFormat;
5603 pFormat += sizeof(WORD);
5605 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5607 align_pointer(&pStubMsg->Buffer, alignment);
5609 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5610 pStubMsg->MemorySize += size;
5612 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5614 return pStubMsg->MemorySize;
5617 /***********************************************************************
5618 * NdrVaryingArrayFree [RPCRT4.@]
5620 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5621 unsigned char *pMemory,
5622 PFORMAT_STRING pFormat)
5624 DWORD elements;
5626 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5628 if ((pFormat[0] != FC_SMVARRAY) &&
5629 (pFormat[0] != FC_LGVARRAY))
5631 ERR("invalid format type %x\n", pFormat[0]);
5632 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5633 return;
5636 if (pFormat[0] == FC_SMVARRAY)
5638 pFormat += 2;
5639 pFormat += sizeof(WORD);
5640 elements = *(const WORD*)pFormat;
5641 pFormat += sizeof(WORD);
5643 else
5645 pFormat += 2;
5646 pFormat += sizeof(DWORD);
5647 elements = *(const DWORD*)pFormat;
5648 pFormat += sizeof(DWORD);
5651 pFormat += sizeof(WORD);
5653 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5654 if ((pStubMsg->ActualCount > elements) ||
5655 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5657 RpcRaiseException(RPC_S_INVALID_BOUND);
5658 return;
5661 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5664 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5666 switch (fc)
5668 case FC_BYTE:
5669 case FC_CHAR:
5670 case FC_SMALL:
5671 case FC_USMALL:
5672 return *pMemory;
5673 case FC_WCHAR:
5674 case FC_SHORT:
5675 case FC_USHORT:
5676 case FC_ENUM16:
5677 return *(const USHORT *)pMemory;
5678 case FC_LONG:
5679 case FC_ULONG:
5680 case FC_ENUM32:
5681 return *(const ULONG *)pMemory;
5682 default:
5683 FIXME("Unhandled base type: 0x%02x\n", fc);
5684 return 0;
5688 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5689 ULONG discriminant,
5690 PFORMAT_STRING pFormat)
5692 unsigned short num_arms, arm, type;
5694 num_arms = *(const SHORT*)pFormat & 0x0fff;
5695 pFormat += 2;
5696 for(arm = 0; arm < num_arms; arm++)
5698 if(discriminant == *(const ULONG*)pFormat)
5700 pFormat += 4;
5701 break;
5703 pFormat += 6;
5706 type = *(const unsigned short*)pFormat;
5707 TRACE("type %04x\n", type);
5708 if(arm == num_arms) /* default arm extras */
5710 if(type == 0xffff)
5712 ERR("no arm for 0x%x and no default case\n", discriminant);
5713 RpcRaiseException(RPC_S_INVALID_TAG);
5714 return NULL;
5716 if(type == 0)
5718 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5719 return NULL;
5722 return pFormat;
5725 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5727 unsigned short type;
5729 pFormat += 2;
5731 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5732 if(!pFormat)
5733 return NULL;
5735 type = *(const unsigned short*)pFormat;
5736 if((type & 0xff00) == 0x8000)
5738 unsigned char basetype = LOBYTE(type);
5739 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5741 else
5743 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5744 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5745 if (m)
5747 unsigned char *saved_buffer = NULL;
5748 BOOL pointer_buffer_mark_set = FALSE;
5749 switch(*desc)
5751 case FC_RP:
5752 case FC_UP:
5753 case FC_OP:
5754 case FC_FP:
5755 align_pointer_clear(&pStubMsg->Buffer, 4);
5756 saved_buffer = pStubMsg->Buffer;
5757 if (pStubMsg->PointerBufferMark)
5759 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5760 pStubMsg->PointerBufferMark = NULL;
5761 pointer_buffer_mark_set = TRUE;
5763 else
5764 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5766 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5767 if (pointer_buffer_mark_set)
5769 STD_OVERFLOW_CHECK(pStubMsg);
5770 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5771 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5773 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5774 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5775 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5777 pStubMsg->Buffer = saved_buffer + 4;
5779 break;
5780 case FC_IP:
5781 /* must be dereferenced first */
5782 m(pStubMsg, *(unsigned char **)pMemory, desc);
5783 break;
5784 default:
5785 m(pStubMsg, pMemory, desc);
5788 else if (*desc)
5789 FIXME("no marshaller for embedded type %02x\n", *desc);
5791 return NULL;
5794 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5795 unsigned char **ppMemory,
5796 ULONG discriminant,
5797 PFORMAT_STRING pFormat,
5798 unsigned char fMustAlloc)
5800 unsigned short type;
5802 pFormat += 2;
5804 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5805 if(!pFormat)
5806 return NULL;
5808 type = *(const unsigned short*)pFormat;
5809 if((type & 0xff00) == 0x8000)
5811 unsigned char basetype = LOBYTE(type);
5812 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5814 else
5816 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5817 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5818 if (m)
5820 unsigned char *saved_buffer = NULL;
5821 BOOL pointer_buffer_mark_set = FALSE;
5822 switch(*desc)
5824 case FC_RP:
5825 case FC_UP:
5826 case FC_OP:
5827 case FC_FP:
5828 align_pointer(&pStubMsg->Buffer, 4);
5829 saved_buffer = pStubMsg->Buffer;
5830 if (pStubMsg->PointerBufferMark)
5832 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5833 pStubMsg->PointerBufferMark = NULL;
5834 pointer_buffer_mark_set = TRUE;
5836 else
5837 pStubMsg->Buffer += 4; /* for pointer ID */
5839 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5841 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5842 saved_buffer, pStubMsg->BufferEnd);
5843 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5846 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5847 if (pointer_buffer_mark_set)
5849 STD_OVERFLOW_CHECK(pStubMsg);
5850 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5851 pStubMsg->Buffer = saved_buffer + 4;
5853 break;
5854 case FC_IP:
5855 /* must be dereferenced first */
5856 m(pStubMsg, *(unsigned char ***)ppMemory, desc, fMustAlloc);
5857 break;
5858 default:
5859 m(pStubMsg, ppMemory, desc, fMustAlloc);
5862 else if (*desc)
5863 FIXME("no marshaller for embedded type %02x\n", *desc);
5865 return NULL;
5868 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5869 unsigned char *pMemory,
5870 ULONG discriminant,
5871 PFORMAT_STRING pFormat)
5873 unsigned short type;
5875 pFormat += 2;
5877 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5878 if(!pFormat)
5879 return;
5881 type = *(const unsigned short*)pFormat;
5882 if((type & 0xff00) == 0x8000)
5884 unsigned char basetype = LOBYTE(type);
5885 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5887 else
5889 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5890 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5891 if (m)
5893 switch(*desc)
5895 case FC_RP:
5896 case FC_UP:
5897 case FC_OP:
5898 case FC_FP:
5899 align_length(&pStubMsg->BufferLength, 4);
5900 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5901 if (!pStubMsg->IgnoreEmbeddedPointers)
5903 int saved_buffer_length = pStubMsg->BufferLength;
5904 pStubMsg->BufferLength = pStubMsg->PointerLength;
5905 pStubMsg->PointerLength = 0;
5906 if(!pStubMsg->BufferLength)
5907 ERR("BufferLength == 0??\n");
5908 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5909 pStubMsg->PointerLength = pStubMsg->BufferLength;
5910 pStubMsg->BufferLength = saved_buffer_length;
5912 break;
5913 case FC_IP:
5914 /* must be dereferenced first */
5915 m(pStubMsg, *(unsigned char **)pMemory, desc);
5916 break;
5917 default:
5918 m(pStubMsg, pMemory, desc);
5921 else if (*desc)
5922 FIXME("no buffersizer for embedded type %02x\n", *desc);
5926 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5927 ULONG discriminant,
5928 PFORMAT_STRING pFormat)
5930 unsigned short type, size;
5932 size = *(const unsigned short*)pFormat;
5933 pStubMsg->Memory += size;
5934 pFormat += 2;
5936 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5937 if(!pFormat)
5938 return 0;
5940 type = *(const unsigned short*)pFormat;
5941 if((type & 0xff00) == 0x8000)
5943 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5945 else
5947 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5948 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5949 unsigned char *saved_buffer;
5950 if (m)
5952 switch(*desc)
5954 case FC_RP:
5955 case FC_UP:
5956 case FC_OP:
5957 case FC_FP:
5958 align_pointer(&pStubMsg->Buffer, 4);
5959 saved_buffer = pStubMsg->Buffer;
5960 safe_buffer_increment(pStubMsg, 4);
5961 align_length(&pStubMsg->MemorySize, sizeof(void *));
5962 pStubMsg->MemorySize += sizeof(void *);
5963 if (!pStubMsg->IgnoreEmbeddedPointers)
5964 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5965 break;
5966 default:
5967 return m(pStubMsg, desc);
5970 else if (*desc)
5971 FIXME("no marshaller for embedded type %02x\n", *desc);
5974 TRACE("size %d\n", size);
5975 return size;
5978 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5979 unsigned char *pMemory,
5980 ULONG discriminant,
5981 PFORMAT_STRING pFormat)
5983 unsigned short type;
5985 pFormat += 2;
5987 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5988 if(!pFormat)
5989 return;
5991 type = *(const unsigned short*)pFormat;
5992 if((type & 0xff00) != 0x8000)
5994 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5995 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5996 if (m)
5998 switch(*desc)
6000 case FC_RP:
6001 case FC_UP:
6002 case FC_OP:
6003 case FC_FP:
6004 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
6005 break;
6006 case FC_IP:
6007 /* must be dereferenced first */
6008 m(pStubMsg, *(unsigned char **)pMemory, desc);
6009 break;
6010 default:
6011 m(pStubMsg, pMemory, desc);
6017 /***********************************************************************
6018 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
6020 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6021 unsigned char *pMemory,
6022 PFORMAT_STRING pFormat)
6024 unsigned char switch_type;
6025 unsigned char increment;
6026 ULONG switch_value;
6028 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6029 pFormat++;
6031 switch_type = *pFormat & 0xf;
6032 increment = (*pFormat & 0xf0) >> 4;
6033 pFormat++;
6035 align_pointer_clear(&pStubMsg->Buffer, increment);
6037 switch_value = get_discriminant(switch_type, pMemory);
6038 TRACE("got switch value 0x%x\n", switch_value);
6040 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
6041 pMemory += increment;
6043 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
6046 /***********************************************************************
6047 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
6049 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6050 unsigned char **ppMemory,
6051 PFORMAT_STRING pFormat,
6052 unsigned char fMustAlloc)
6054 unsigned char switch_type;
6055 unsigned char increment;
6056 ULONG switch_value;
6057 unsigned short size;
6058 unsigned char *pMemoryArm;
6060 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6061 pFormat++;
6063 switch_type = *pFormat & 0xf;
6064 increment = (*pFormat & 0xf0) >> 4;
6065 pFormat++;
6067 align_pointer(&pStubMsg->Buffer, increment);
6068 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6069 TRACE("got switch value 0x%x\n", switch_value);
6071 size = *(const unsigned short*)pFormat + increment;
6072 if (!fMustAlloc && !*ppMemory)
6073 fMustAlloc = TRUE;
6074 if (fMustAlloc)
6075 *ppMemory = NdrAllocate(pStubMsg, size);
6077 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6078 * since the arm is part of the memory block that is encompassed by
6079 * the whole union. Memory is forced to allocate when pointers
6080 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6081 * clearing the memory we pass in to the unmarshaller */
6082 if (fMustAlloc)
6083 memset(*ppMemory, 0, size);
6085 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6086 pMemoryArm = *ppMemory + increment;
6088 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6091 /***********************************************************************
6092 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6094 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6095 unsigned char *pMemory,
6096 PFORMAT_STRING pFormat)
6098 unsigned char switch_type;
6099 unsigned char increment;
6100 ULONG switch_value;
6102 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6103 pFormat++;
6105 switch_type = *pFormat & 0xf;
6106 increment = (*pFormat & 0xf0) >> 4;
6107 pFormat++;
6109 align_length(&pStubMsg->BufferLength, increment);
6110 switch_value = get_discriminant(switch_type, pMemory);
6111 TRACE("got switch value 0x%x\n", switch_value);
6113 /* Add discriminant size */
6114 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6115 pMemory += increment;
6117 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6120 /***********************************************************************
6121 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6123 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6124 PFORMAT_STRING pFormat)
6126 unsigned char switch_type;
6127 unsigned char increment;
6128 ULONG switch_value;
6130 switch_type = *pFormat & 0xf;
6131 increment = (*pFormat & 0xf0) >> 4;
6132 pFormat++;
6134 align_pointer(&pStubMsg->Buffer, increment);
6135 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6136 TRACE("got switch value 0x%x\n", switch_value);
6138 pStubMsg->Memory += increment;
6140 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6143 /***********************************************************************
6144 * NdrEncapsulatedUnionFree [RPCRT4.@]
6146 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6147 unsigned char *pMemory,
6148 PFORMAT_STRING pFormat)
6150 unsigned char switch_type;
6151 unsigned char increment;
6152 ULONG switch_value;
6154 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6155 pFormat++;
6157 switch_type = *pFormat & 0xf;
6158 increment = (*pFormat & 0xf0) >> 4;
6159 pFormat++;
6161 switch_value = get_discriminant(switch_type, pMemory);
6162 TRACE("got switch value 0x%x\n", switch_value);
6164 pMemory += increment;
6166 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6169 /***********************************************************************
6170 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6172 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6173 unsigned char *pMemory,
6174 PFORMAT_STRING pFormat)
6176 unsigned char switch_type;
6178 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6179 pFormat++;
6181 switch_type = *pFormat;
6182 pFormat++;
6184 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6185 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6186 /* Marshall discriminant */
6187 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6189 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6192 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6193 PFORMAT_STRING *ppFormat)
6195 LONG discriminant = 0;
6197 switch(**ppFormat)
6199 case FC_BYTE:
6200 case FC_CHAR:
6201 case FC_SMALL:
6202 case FC_USMALL:
6204 UCHAR d;
6205 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6206 discriminant = d;
6207 break;
6209 case FC_WCHAR:
6210 case FC_SHORT:
6211 case FC_USHORT:
6212 case FC_ENUM16:
6214 USHORT d;
6215 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6216 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6217 discriminant = d;
6218 break;
6220 case FC_LONG:
6221 case FC_ULONG:
6223 ULONG d;
6224 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6225 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6226 discriminant = d;
6227 break;
6229 default:
6230 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6232 (*ppFormat)++;
6234 *ppFormat = SkipConformance(pStubMsg, *ppFormat);
6235 return discriminant;
6238 /**********************************************************************
6239 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6241 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6242 unsigned char **ppMemory,
6243 PFORMAT_STRING pFormat,
6244 unsigned char fMustAlloc)
6246 LONG discriminant;
6247 unsigned short size;
6249 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6250 pFormat++;
6252 /* Unmarshall discriminant */
6253 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6254 TRACE("unmarshalled discriminant %x\n", discriminant);
6256 pFormat += *(const SHORT*)pFormat;
6258 size = *(const unsigned short*)pFormat;
6260 if (!fMustAlloc && !*ppMemory)
6261 fMustAlloc = TRUE;
6262 if (fMustAlloc)
6263 *ppMemory = NdrAllocate(pStubMsg, size);
6265 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6266 * since the arm is part of the memory block that is encompassed by
6267 * the whole union. Memory is forced to allocate when pointers
6268 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6269 * clearing the memory we pass in to the unmarshaller */
6270 if (fMustAlloc)
6271 memset(*ppMemory, 0, size);
6273 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6276 /***********************************************************************
6277 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6279 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6280 unsigned char *pMemory,
6281 PFORMAT_STRING pFormat)
6283 unsigned char switch_type;
6285 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6286 pFormat++;
6288 switch_type = *pFormat;
6289 pFormat++;
6291 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6292 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6293 /* Add discriminant size */
6294 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6296 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6299 /***********************************************************************
6300 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6302 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6303 PFORMAT_STRING pFormat)
6305 ULONG discriminant;
6307 pFormat++;
6308 /* Unmarshall discriminant */
6309 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6310 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6312 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6315 /***********************************************************************
6316 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6318 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6319 unsigned char *pMemory,
6320 PFORMAT_STRING pFormat)
6322 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6323 pFormat++;
6324 pFormat++;
6326 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6327 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6329 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6332 /***********************************************************************
6333 * NdrByteCountPointerMarshall [RPCRT4.@]
6335 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6336 unsigned char *pMemory,
6337 PFORMAT_STRING pFormat)
6339 FIXME("stub\n");
6340 return NULL;
6343 /***********************************************************************
6344 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6346 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6347 unsigned char **ppMemory,
6348 PFORMAT_STRING pFormat,
6349 unsigned char fMustAlloc)
6351 FIXME("stub\n");
6352 return NULL;
6355 /***********************************************************************
6356 * NdrByteCountPointerBufferSize [RPCRT4.@]
6358 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6359 unsigned char *pMemory,
6360 PFORMAT_STRING pFormat)
6362 FIXME("stub\n");
6365 /***********************************************************************
6366 * NdrByteCountPointerMemorySize [internal]
6368 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6369 PFORMAT_STRING pFormat)
6371 FIXME("stub\n");
6372 return 0;
6375 /***********************************************************************
6376 * NdrByteCountPointerFree [RPCRT4.@]
6378 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6379 unsigned char *pMemory,
6380 PFORMAT_STRING pFormat)
6382 FIXME("stub\n");
6385 /***********************************************************************
6386 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6388 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6389 unsigned char *pMemory,
6390 PFORMAT_STRING pFormat)
6392 FIXME("stub\n");
6393 return NULL;
6396 /***********************************************************************
6397 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6399 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6400 unsigned char **ppMemory,
6401 PFORMAT_STRING pFormat,
6402 unsigned char fMustAlloc)
6404 FIXME("stub\n");
6405 return NULL;
6408 /***********************************************************************
6409 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6411 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6412 unsigned char *pMemory,
6413 PFORMAT_STRING pFormat)
6415 FIXME("stub\n");
6418 /***********************************************************************
6419 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6421 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6422 PFORMAT_STRING pFormat)
6424 FIXME("stub\n");
6425 return 0;
6428 /***********************************************************************
6429 * NdrXmitOrRepAsFree [RPCRT4.@]
6431 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6432 unsigned char *pMemory,
6433 PFORMAT_STRING pFormat)
6435 FIXME("stub\n");
6438 /***********************************************************************
6439 * NdrRangeMarshall [internal]
6441 static unsigned char *WINAPI NdrRangeMarshall(
6442 PMIDL_STUB_MESSAGE pStubMsg,
6443 unsigned char *pMemory,
6444 PFORMAT_STRING pFormat)
6446 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6447 unsigned char base_type;
6449 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6451 if (pRange->type != FC_RANGE)
6453 ERR("invalid format type %x\n", pRange->type);
6454 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6455 return NULL;
6458 base_type = pRange->flags_type & 0xf;
6460 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6463 /***********************************************************************
6464 * NdrRangeUnmarshall [RPCRT4.@]
6466 unsigned char *WINAPI NdrRangeUnmarshall(
6467 PMIDL_STUB_MESSAGE pStubMsg,
6468 unsigned char **ppMemory,
6469 PFORMAT_STRING pFormat,
6470 unsigned char fMustAlloc)
6472 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6473 unsigned char base_type;
6475 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6477 if (pRange->type != FC_RANGE)
6479 ERR("invalid format type %x\n", pRange->type);
6480 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6481 return NULL;
6483 base_type = pRange->flags_type & 0xf;
6485 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6486 base_type, pRange->low_value, pRange->high_value);
6488 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6489 do \
6491 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6492 if (!fMustAlloc && !*ppMemory) \
6493 fMustAlloc = TRUE; \
6494 if (fMustAlloc) \
6495 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6496 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6498 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6499 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6500 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6502 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6503 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6505 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6506 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6507 (mem_type)pRange->high_value); \
6508 RpcRaiseException(RPC_S_INVALID_BOUND); \
6509 return NULL; \
6511 TRACE("*ppMemory: %p\n", *ppMemory); \
6512 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6513 pStubMsg->Buffer += sizeof(wire_type); \
6514 } while (0)
6516 switch(base_type)
6518 case FC_CHAR:
6519 case FC_SMALL:
6520 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6521 TRACE("value: 0x%02x\n", **ppMemory);
6522 break;
6523 case FC_BYTE:
6524 case FC_USMALL:
6525 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6526 TRACE("value: 0x%02x\n", **ppMemory);
6527 break;
6528 case FC_WCHAR: /* FIXME: valid? */
6529 case FC_USHORT:
6530 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6531 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6532 break;
6533 case FC_SHORT:
6534 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6535 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6536 break;
6537 case FC_LONG:
6538 case FC_ENUM32:
6539 RANGE_UNMARSHALL(LONG, LONG, "%d");
6540 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6541 break;
6542 case FC_ULONG:
6543 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6544 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6545 break;
6546 case FC_ENUM16:
6547 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6548 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6549 break;
6550 case FC_FLOAT:
6551 case FC_DOUBLE:
6552 case FC_HYPER:
6553 default:
6554 ERR("invalid range base type: 0x%02x\n", base_type);
6555 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6558 return NULL;
6561 /***********************************************************************
6562 * NdrRangeBufferSize [internal]
6564 static void WINAPI NdrRangeBufferSize(
6565 PMIDL_STUB_MESSAGE pStubMsg,
6566 unsigned char *pMemory,
6567 PFORMAT_STRING pFormat)
6569 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6570 unsigned char base_type;
6572 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6574 if (pRange->type != FC_RANGE)
6576 ERR("invalid format type %x\n", pRange->type);
6577 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6579 base_type = pRange->flags_type & 0xf;
6581 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6584 /***********************************************************************
6585 * NdrRangeMemorySize [internal]
6587 static ULONG WINAPI NdrRangeMemorySize(
6588 PMIDL_STUB_MESSAGE pStubMsg,
6589 PFORMAT_STRING pFormat)
6591 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6592 unsigned char base_type;
6594 if (pRange->type != FC_RANGE)
6596 ERR("invalid format type %x\n", pRange->type);
6597 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6598 return 0;
6600 base_type = pRange->flags_type & 0xf;
6602 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6605 /***********************************************************************
6606 * NdrRangeFree [internal]
6608 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6609 unsigned char *pMemory,
6610 PFORMAT_STRING pFormat)
6612 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6614 /* nothing to do */
6617 /***********************************************************************
6618 * NdrBaseTypeMarshall [internal]
6620 static unsigned char *WINAPI NdrBaseTypeMarshall(
6621 PMIDL_STUB_MESSAGE pStubMsg,
6622 unsigned char *pMemory,
6623 PFORMAT_STRING pFormat)
6625 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6627 switch(*pFormat)
6629 case FC_BYTE:
6630 case FC_CHAR:
6631 case FC_SMALL:
6632 case FC_USMALL:
6633 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6634 TRACE("value: 0x%02x\n", *pMemory);
6635 break;
6636 case FC_WCHAR:
6637 case FC_SHORT:
6638 case FC_USHORT:
6639 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6640 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6641 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6642 break;
6643 case FC_LONG:
6644 case FC_ULONG:
6645 case FC_ERROR_STATUS_T:
6646 case FC_ENUM32:
6647 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6648 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6649 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6650 break;
6651 case FC_FLOAT:
6652 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6653 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6654 break;
6655 case FC_DOUBLE:
6656 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6657 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6658 break;
6659 case FC_HYPER:
6660 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6661 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6662 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6663 break;
6664 case FC_ENUM16:
6666 USHORT val = *(UINT *)pMemory;
6667 /* only 16-bits on the wire, so do a sanity check */
6668 if (*(UINT *)pMemory > SHRT_MAX)
6669 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6670 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6671 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6672 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6673 break;
6675 case FC_INT3264:
6676 case FC_UINT3264:
6678 UINT val = *(UINT_PTR *)pMemory;
6679 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6680 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6681 break;
6683 case FC_IGNORE:
6684 break;
6685 default:
6686 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6689 /* FIXME: what is the correct return value? */
6690 return NULL;
6693 /***********************************************************************
6694 * NdrBaseTypeUnmarshall [internal]
6696 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6697 PMIDL_STUB_MESSAGE pStubMsg,
6698 unsigned char **ppMemory,
6699 PFORMAT_STRING pFormat,
6700 unsigned char fMustAlloc)
6702 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6704 #define BASE_TYPE_UNMARSHALL(type) do { \
6705 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6706 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6708 *ppMemory = pStubMsg->Buffer; \
6709 TRACE("*ppMemory: %p\n", *ppMemory); \
6710 safe_buffer_increment(pStubMsg, sizeof(type)); \
6712 else \
6714 if (fMustAlloc) \
6715 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6716 TRACE("*ppMemory: %p\n", *ppMemory); \
6717 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6719 } while (0)
6721 switch(*pFormat)
6723 case FC_BYTE:
6724 case FC_CHAR:
6725 case FC_SMALL:
6726 case FC_USMALL:
6727 BASE_TYPE_UNMARSHALL(UCHAR);
6728 TRACE("value: 0x%02x\n", **ppMemory);
6729 break;
6730 case FC_WCHAR:
6731 case FC_SHORT:
6732 case FC_USHORT:
6733 BASE_TYPE_UNMARSHALL(USHORT);
6734 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6735 break;
6736 case FC_LONG:
6737 case FC_ULONG:
6738 case FC_ERROR_STATUS_T:
6739 case FC_ENUM32:
6740 BASE_TYPE_UNMARSHALL(ULONG);
6741 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6742 break;
6743 case FC_FLOAT:
6744 BASE_TYPE_UNMARSHALL(float);
6745 TRACE("value: %f\n", **(float **)ppMemory);
6746 break;
6747 case FC_DOUBLE:
6748 BASE_TYPE_UNMARSHALL(double);
6749 TRACE("value: %f\n", **(double **)ppMemory);
6750 break;
6751 case FC_HYPER:
6752 BASE_TYPE_UNMARSHALL(ULONGLONG);
6753 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6754 break;
6755 case FC_ENUM16:
6757 USHORT val;
6758 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6759 if (!fMustAlloc && !*ppMemory)
6760 fMustAlloc = TRUE;
6761 if (fMustAlloc)
6762 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6763 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6764 /* 16-bits on the wire, but int in memory */
6765 **(UINT **)ppMemory = val;
6766 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6767 break;
6769 case FC_INT3264:
6770 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6771 else
6773 INT val;
6774 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6775 if (!fMustAlloc && !*ppMemory)
6776 fMustAlloc = TRUE;
6777 if (fMustAlloc)
6778 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6779 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6780 **(INT_PTR **)ppMemory = val;
6781 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6783 break;
6784 case FC_UINT3264:
6785 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6786 else
6788 UINT val;
6789 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6790 if (!fMustAlloc && !*ppMemory)
6791 fMustAlloc = TRUE;
6792 if (fMustAlloc)
6793 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6794 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6795 **(UINT_PTR **)ppMemory = val;
6796 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6798 break;
6799 case FC_IGNORE:
6800 break;
6801 default:
6802 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6804 #undef BASE_TYPE_UNMARSHALL
6806 /* FIXME: what is the correct return value? */
6808 return NULL;
6811 /***********************************************************************
6812 * NdrBaseTypeBufferSize [internal]
6814 static void WINAPI NdrBaseTypeBufferSize(
6815 PMIDL_STUB_MESSAGE pStubMsg,
6816 unsigned char *pMemory,
6817 PFORMAT_STRING pFormat)
6819 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6821 switch(*pFormat)
6823 case FC_BYTE:
6824 case FC_CHAR:
6825 case FC_SMALL:
6826 case FC_USMALL:
6827 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6828 break;
6829 case FC_WCHAR:
6830 case FC_SHORT:
6831 case FC_USHORT:
6832 case FC_ENUM16:
6833 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6834 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6835 break;
6836 case FC_LONG:
6837 case FC_ULONG:
6838 case FC_ENUM32:
6839 case FC_INT3264:
6840 case FC_UINT3264:
6841 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6842 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6843 break;
6844 case FC_FLOAT:
6845 align_length(&pStubMsg->BufferLength, sizeof(float));
6846 safe_buffer_length_increment(pStubMsg, sizeof(float));
6847 break;
6848 case FC_DOUBLE:
6849 align_length(&pStubMsg->BufferLength, sizeof(double));
6850 safe_buffer_length_increment(pStubMsg, sizeof(double));
6851 break;
6852 case FC_HYPER:
6853 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6854 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6855 break;
6856 case FC_ERROR_STATUS_T:
6857 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6858 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6859 break;
6860 case FC_IGNORE:
6861 break;
6862 default:
6863 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6867 /***********************************************************************
6868 * NdrBaseTypeMemorySize [internal]
6870 static ULONG WINAPI NdrBaseTypeMemorySize(
6871 PMIDL_STUB_MESSAGE pStubMsg,
6872 PFORMAT_STRING pFormat)
6874 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6876 switch(*pFormat)
6878 case FC_BYTE:
6879 case FC_CHAR:
6880 case FC_SMALL:
6881 case FC_USMALL:
6882 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6883 pStubMsg->MemorySize += sizeof(UCHAR);
6884 return sizeof(UCHAR);
6885 case FC_WCHAR:
6886 case FC_SHORT:
6887 case FC_USHORT:
6888 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6889 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6890 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6891 pStubMsg->MemorySize += sizeof(USHORT);
6892 return sizeof(USHORT);
6893 case FC_LONG:
6894 case FC_ULONG:
6895 case FC_ENUM32:
6896 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6897 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6898 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6899 pStubMsg->MemorySize += sizeof(ULONG);
6900 return sizeof(ULONG);
6901 case FC_FLOAT:
6902 align_pointer(&pStubMsg->Buffer, sizeof(float));
6903 safe_buffer_increment(pStubMsg, sizeof(float));
6904 align_length(&pStubMsg->MemorySize, sizeof(float));
6905 pStubMsg->MemorySize += sizeof(float);
6906 return sizeof(float);
6907 case FC_DOUBLE:
6908 align_pointer(&pStubMsg->Buffer, sizeof(double));
6909 safe_buffer_increment(pStubMsg, sizeof(double));
6910 align_length(&pStubMsg->MemorySize, sizeof(double));
6911 pStubMsg->MemorySize += sizeof(double);
6912 return sizeof(double);
6913 case FC_HYPER:
6914 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6915 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6916 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6917 pStubMsg->MemorySize += sizeof(ULONGLONG);
6918 return sizeof(ULONGLONG);
6919 case FC_ERROR_STATUS_T:
6920 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6921 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6922 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6923 pStubMsg->MemorySize += sizeof(error_status_t);
6924 return sizeof(error_status_t);
6925 case FC_ENUM16:
6926 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6927 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6928 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6929 pStubMsg->MemorySize += sizeof(UINT);
6930 return sizeof(UINT);
6931 case FC_INT3264:
6932 case FC_UINT3264:
6933 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6934 safe_buffer_increment(pStubMsg, sizeof(UINT));
6935 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6936 pStubMsg->MemorySize += sizeof(UINT_PTR);
6937 return sizeof(UINT_PTR);
6938 case FC_IGNORE:
6939 align_length(&pStubMsg->MemorySize, sizeof(void *));
6940 pStubMsg->MemorySize += sizeof(void *);
6941 return sizeof(void *);
6942 default:
6943 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6944 return 0;
6948 /***********************************************************************
6949 * NdrBaseTypeFree [internal]
6951 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6952 unsigned char *pMemory,
6953 PFORMAT_STRING pFormat)
6955 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6957 /* nothing to do */
6960 /***********************************************************************
6961 * NdrContextHandleBufferSize [internal]
6963 static void WINAPI NdrContextHandleBufferSize(
6964 PMIDL_STUB_MESSAGE pStubMsg,
6965 unsigned char *pMemory,
6966 PFORMAT_STRING pFormat)
6968 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6970 if (*pFormat != FC_BIND_CONTEXT)
6972 ERR("invalid format type %x\n", *pFormat);
6973 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6975 align_length(&pStubMsg->BufferLength, 4);
6976 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6979 /***********************************************************************
6980 * NdrContextHandleMarshall [internal]
6982 static unsigned char *WINAPI NdrContextHandleMarshall(
6983 PMIDL_STUB_MESSAGE pStubMsg,
6984 unsigned char *pMemory,
6985 PFORMAT_STRING pFormat)
6987 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6989 if (*pFormat != FC_BIND_CONTEXT)
6991 ERR("invalid format type %x\n", *pFormat);
6992 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6994 TRACE("flags: 0x%02x\n", pFormat[1]);
6996 if (pStubMsg->IsClient)
6998 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6999 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
7000 else
7001 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
7003 else
7005 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
7006 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
7007 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
7010 return NULL;
7013 /***********************************************************************
7014 * NdrContextHandleUnmarshall [internal]
7016 static unsigned char *WINAPI NdrContextHandleUnmarshall(
7017 PMIDL_STUB_MESSAGE pStubMsg,
7018 unsigned char **ppMemory,
7019 PFORMAT_STRING pFormat,
7020 unsigned char fMustAlloc)
7022 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
7023 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
7025 if (*pFormat != FC_BIND_CONTEXT)
7027 ERR("invalid format type %x\n", *pFormat);
7028 RpcRaiseException(RPC_S_INTERNAL_ERROR);
7030 TRACE("flags: 0x%02x\n", pFormat[1]);
7032 if (pStubMsg->IsClient)
7034 /* [out]-only or [ret] param */
7035 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
7036 **(NDR_CCONTEXT **)ppMemory = NULL;
7037 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
7039 else
7041 NDR_SCONTEXT ctxt;
7042 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
7043 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
7044 *(void **)ppMemory = NDRSContextValue(ctxt);
7045 else
7046 *(void **)ppMemory = *NDRSContextValue(ctxt);
7049 return NULL;
7052 /***********************************************************************
7053 * NdrClientContextMarshall [RPCRT4.@]
7055 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7056 NDR_CCONTEXT ContextHandle,
7057 int fCheck)
7059 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7061 align_pointer_clear(&pStubMsg->Buffer, 4);
7063 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7065 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7066 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7067 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7070 /* FIXME: what does fCheck do? */
7071 NDRCContextMarshall(ContextHandle,
7072 pStubMsg->Buffer);
7074 pStubMsg->Buffer += cbNDRContext;
7077 /***********************************************************************
7078 * NdrClientContextUnmarshall [RPCRT4.@]
7080 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7081 NDR_CCONTEXT * pContextHandle,
7082 RPC_BINDING_HANDLE BindHandle)
7084 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7086 align_pointer(&pStubMsg->Buffer, 4);
7088 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7089 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7091 NDRCContextUnmarshall(pContextHandle,
7092 BindHandle,
7093 pStubMsg->Buffer,
7094 pStubMsg->RpcMsg->DataRepresentation);
7096 pStubMsg->Buffer += cbNDRContext;
7099 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7100 NDR_SCONTEXT ContextHandle,
7101 NDR_RUNDOWN RundownRoutine )
7103 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7105 align_pointer(&pStubMsg->Buffer, 4);
7107 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7109 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7110 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7111 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7114 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7115 pStubMsg->Buffer, RundownRoutine, NULL,
7116 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7117 pStubMsg->Buffer += cbNDRContext;
7120 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7122 NDR_SCONTEXT ContextHandle;
7124 TRACE("(%p)\n", pStubMsg);
7126 align_pointer(&pStubMsg->Buffer, 4);
7128 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7130 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7131 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7132 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7135 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7136 pStubMsg->Buffer,
7137 pStubMsg->RpcMsg->DataRepresentation,
7138 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7139 pStubMsg->Buffer += cbNDRContext;
7141 return ContextHandle;
7144 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7145 unsigned char* pMemory,
7146 PFORMAT_STRING pFormat)
7148 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7151 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7152 PFORMAT_STRING pFormat)
7154 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7155 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7157 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7159 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7160 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7161 if (pFormat[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE)
7162 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7163 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7165 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7166 if_id = &sif->InterfaceId;
7169 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7170 pStubMsg->RpcMsg->DataRepresentation, if_id,
7171 flags);
7174 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7175 NDR_SCONTEXT ContextHandle,
7176 NDR_RUNDOWN RundownRoutine,
7177 PFORMAT_STRING pFormat)
7179 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7180 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7182 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7184 align_pointer(&pStubMsg->Buffer, 4);
7186 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7188 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7189 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7190 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7193 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7194 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7195 if (pFormat[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE)
7196 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7197 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7199 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7200 if_id = &sif->InterfaceId;
7203 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7204 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7205 pStubMsg->Buffer += cbNDRContext;
7208 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7209 PFORMAT_STRING pFormat)
7211 NDR_SCONTEXT ContextHandle;
7212 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7213 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7215 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7217 align_pointer(&pStubMsg->Buffer, 4);
7219 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7221 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7222 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7223 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7226 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7227 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7228 if (pFormat[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE)
7229 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7230 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7232 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7233 if_id = &sif->InterfaceId;
7236 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7237 pStubMsg->Buffer,
7238 pStubMsg->RpcMsg->DataRepresentation,
7239 if_id, flags);
7240 pStubMsg->Buffer += cbNDRContext;
7242 return ContextHandle;
7245 /***********************************************************************
7246 * NdrCorrelationInitialize [RPCRT4.@]
7248 * Initializes correlation validity checking.
7250 * PARAMS
7251 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7252 * pMemory [I] Pointer to memory to use as a cache.
7253 * CacheSize [I] Size of the memory pointed to by pMemory.
7254 * Flags [I] Reserved. Set to zero.
7256 * RETURNS
7257 * Nothing.
7259 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7261 FIXME("(%p, %p, %d, 0x%x): semi-stub\n", pStubMsg, pMemory, CacheSize, Flags);
7263 if (pStubMsg->CorrDespIncrement == 0)
7264 pStubMsg->CorrDespIncrement = 2; /* size of the normal (non-range) /robust payload */
7266 pStubMsg->fHasNewCorrDesc = TRUE;
7269 /***********************************************************************
7270 * NdrCorrelationPass [RPCRT4.@]
7272 * Performs correlation validity checking.
7274 * PARAMS
7275 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7277 * RETURNS
7278 * Nothing.
7280 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7282 FIXME("(%p): stub\n", pStubMsg);
7285 /***********************************************************************
7286 * NdrCorrelationFree [RPCRT4.@]
7288 * Frees any resources used while unmarshalling parameters that need
7289 * correlation validity checking.
7291 * PARAMS
7292 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7294 * RETURNS
7295 * Nothing.
7297 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7299 FIXME("(%p): stub\n", pStubMsg);