d3dx9: Improve get_parameter_by_name().
[wine/multimedia.git] / dlls / rpcrt4 / ndr_marshall.c
blob1e99c2e7013ca6bf74925fdaeb604762db3e8425
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/rpcfc.h"
48 #include "wine/debug.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(ole);
52 #if defined(__i386__)
53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
54 (*((UINT32 *)(pchar)) = (uint32))
56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
57 (*((UINT32 *)(pchar)))
58 #else
59 /* these would work for i386 too, but less efficient */
60 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
61 (*(pchar) = LOBYTE(LOWORD(uint32)), \
62 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
63 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
64 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
66 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
67 (MAKELONG( \
68 MAKEWORD(*(pchar), *((pchar)+1)), \
69 MAKEWORD(*((pchar)+2), *((pchar)+3))))
70 #endif
72 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
73 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
74 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
75 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
76 *(pchar) = HIBYTE(HIWORD(uint32)))
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
79 (MAKELONG( \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
88 #else
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
93 #endif
95 static inline void align_length( ULONG *len, unsigned int align )
97 *len = (*len + align - 1) & ~(align - 1);
100 static inline void align_pointer( unsigned char **ptr, unsigned int align )
102 ULONG_PTR mask = align - 1;
103 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
106 static inline void align_pointer_clear( unsigned char **ptr, unsigned int align )
108 ULONG_PTR mask = align - 1;
109 memset( *ptr, 0, (align - (ULONG_PTR)*ptr) & mask );
110 *ptr = (unsigned char *)(((ULONG_PTR)*ptr + mask) & ~mask);
113 #define STD_OVERFLOW_CHECK(_Msg) do { \
114 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
115 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
116 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
117 } while (0)
119 #define NDR_POINTER_ID_BASE 0x20000
120 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
121 #define NDR_TABLE_SIZE 128
122 #define NDR_TABLE_MASK 127
124 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
126 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
127 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
128 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
129 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
130 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
132 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
133 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
134 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
136 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING);
137 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
138 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
139 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
141 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
143 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
144 unsigned char *pMemory,
145 PFORMAT_STRING pFormat,
146 PFORMAT_STRING pPointer);
147 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
148 unsigned char *pMemory,
149 PFORMAT_STRING pFormat,
150 PFORMAT_STRING pPointer);
151 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
152 unsigned char *pMemory,
153 PFORMAT_STRING pFormat,
154 PFORMAT_STRING pPointer,
155 unsigned char fMustAlloc);
156 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
157 PFORMAT_STRING pFormat,
158 PFORMAT_STRING pPointer);
159 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
160 unsigned char *pMemory,
161 PFORMAT_STRING pFormat,
162 PFORMAT_STRING pPointer);
164 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
166 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
167 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
168 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
169 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
170 /* 0x10 */
171 NdrBaseTypeMarshall,
172 /* 0x11 */
173 NdrPointerMarshall, NdrPointerMarshall,
174 NdrPointerMarshall, NdrPointerMarshall,
175 /* 0x15 */
176 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
177 NdrConformantStructMarshall, NdrConformantStructMarshall,
178 NdrConformantVaryingStructMarshall,
179 NdrComplexStructMarshall,
180 /* 0x1b */
181 NdrConformantArrayMarshall,
182 NdrConformantVaryingArrayMarshall,
183 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
184 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
185 NdrComplexArrayMarshall,
186 /* 0x22 */
187 NdrConformantStringMarshall, 0, 0,
188 NdrConformantStringMarshall,
189 NdrNonConformantStringMarshall, 0, 0, 0,
190 /* 0x2a */
191 NdrEncapsulatedUnionMarshall,
192 NdrNonEncapsulatedUnionMarshall,
193 NdrByteCountPointerMarshall,
194 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
195 /* 0x2f */
196 NdrInterfacePointerMarshall,
197 /* 0x30 */
198 NdrContextHandleMarshall,
199 /* 0xb1 */
200 0, 0, 0,
201 NdrUserMarshalMarshall,
202 0, 0,
203 /* 0xb7 */
204 NdrRangeMarshall
206 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
208 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
209 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
210 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
211 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
212 /* 0x10 */
213 NdrBaseTypeUnmarshall,
214 /* 0x11 */
215 NdrPointerUnmarshall, NdrPointerUnmarshall,
216 NdrPointerUnmarshall, NdrPointerUnmarshall,
217 /* 0x15 */
218 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
219 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
220 NdrConformantVaryingStructUnmarshall,
221 NdrComplexStructUnmarshall,
222 /* 0x1b */
223 NdrConformantArrayUnmarshall,
224 NdrConformantVaryingArrayUnmarshall,
225 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
226 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
227 NdrComplexArrayUnmarshall,
228 /* 0x22 */
229 NdrConformantStringUnmarshall, 0, 0,
230 NdrConformantStringUnmarshall,
231 NdrNonConformantStringUnmarshall, 0, 0, 0,
232 /* 0x2a */
233 NdrEncapsulatedUnionUnmarshall,
234 NdrNonEncapsulatedUnionUnmarshall,
235 NdrByteCountPointerUnmarshall,
236 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
237 /* 0x2f */
238 NdrInterfacePointerUnmarshall,
239 /* 0x30 */
240 NdrContextHandleUnmarshall,
241 /* 0xb1 */
242 0, 0, 0,
243 NdrUserMarshalUnmarshall,
244 0, 0,
245 /* 0xb7 */
246 NdrRangeUnmarshall
248 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
250 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
251 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
252 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
253 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
254 /* 0x10 */
255 NdrBaseTypeBufferSize,
256 /* 0x11 */
257 NdrPointerBufferSize, NdrPointerBufferSize,
258 NdrPointerBufferSize, NdrPointerBufferSize,
259 /* 0x15 */
260 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
261 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
262 NdrConformantVaryingStructBufferSize,
263 NdrComplexStructBufferSize,
264 /* 0x1b */
265 NdrConformantArrayBufferSize,
266 NdrConformantVaryingArrayBufferSize,
267 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
268 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
269 NdrComplexArrayBufferSize,
270 /* 0x22 */
271 NdrConformantStringBufferSize, 0, 0,
272 NdrConformantStringBufferSize,
273 NdrNonConformantStringBufferSize, 0, 0, 0,
274 /* 0x2a */
275 NdrEncapsulatedUnionBufferSize,
276 NdrNonEncapsulatedUnionBufferSize,
277 NdrByteCountPointerBufferSize,
278 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
279 /* 0x2f */
280 NdrInterfacePointerBufferSize,
281 /* 0x30 */
282 NdrContextHandleBufferSize,
283 /* 0xb1 */
284 0, 0, 0,
285 NdrUserMarshalBufferSize,
286 0, 0,
287 /* 0xb7 */
288 NdrRangeBufferSize
290 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
292 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
293 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
294 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
295 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
296 /* 0x10 */
297 NdrBaseTypeMemorySize,
298 /* 0x11 */
299 NdrPointerMemorySize, NdrPointerMemorySize,
300 NdrPointerMemorySize, NdrPointerMemorySize,
301 /* 0x15 */
302 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
303 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
304 NdrConformantVaryingStructMemorySize,
305 NdrComplexStructMemorySize,
306 /* 0x1b */
307 NdrConformantArrayMemorySize,
308 NdrConformantVaryingArrayMemorySize,
309 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
310 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
311 NdrComplexArrayMemorySize,
312 /* 0x22 */
313 NdrConformantStringMemorySize, 0, 0,
314 NdrConformantStringMemorySize,
315 NdrNonConformantStringMemorySize, 0, 0, 0,
316 /* 0x2a */
317 NdrEncapsulatedUnionMemorySize,
318 NdrNonEncapsulatedUnionMemorySize,
319 NdrByteCountPointerMemorySize,
320 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
321 /* 0x2f */
322 NdrInterfacePointerMemorySize,
323 /* 0x30 */
325 /* 0xb1 */
326 0, 0, 0,
327 NdrUserMarshalMemorySize,
328 0, 0,
329 /* 0xb7 */
330 NdrRangeMemorySize
332 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
334 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
335 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
336 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
337 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
338 /* 0x10 */
339 NdrBaseTypeFree,
340 /* 0x11 */
341 NdrPointerFree, NdrPointerFree,
342 NdrPointerFree, NdrPointerFree,
343 /* 0x15 */
344 NdrSimpleStructFree, NdrSimpleStructFree,
345 NdrConformantStructFree, NdrConformantStructFree,
346 NdrConformantVaryingStructFree,
347 NdrComplexStructFree,
348 /* 0x1b */
349 NdrConformantArrayFree,
350 NdrConformantVaryingArrayFree,
351 NdrFixedArrayFree, NdrFixedArrayFree,
352 NdrVaryingArrayFree, NdrVaryingArrayFree,
353 NdrComplexArrayFree,
354 /* 0x22 */
355 0, 0, 0,
356 0, 0, 0, 0, 0,
357 /* 0x2a */
358 NdrEncapsulatedUnionFree,
359 NdrNonEncapsulatedUnionFree,
361 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
362 /* 0x2f */
363 NdrInterfacePointerFree,
364 /* 0x30 */
366 /* 0xb1 */
367 0, 0, 0,
368 NdrUserMarshalFree,
369 0, 0,
370 /* 0xb7 */
371 NdrRangeFree
374 typedef struct _NDR_MEMORY_LIST
376 ULONG magic;
377 ULONG size;
378 ULONG reserved;
379 struct _NDR_MEMORY_LIST *next;
380 } NDR_MEMORY_LIST;
382 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
384 /***********************************************************************
385 * NdrAllocate [RPCRT4.@]
387 * Allocates a block of memory using pStubMsg->pfnAllocate.
389 * PARAMS
390 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
391 * len [I] Size of memory block to allocate.
393 * RETURNS
394 * The memory block of size len that was allocated.
396 * NOTES
397 * The memory block is always 8-byte aligned.
398 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
399 * exception is raised.
401 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
403 SIZE_T aligned_len;
404 SIZE_T adjusted_len;
405 void *p;
406 NDR_MEMORY_LIST *mem_list;
408 aligned_len = (len + 7) & ~7;
409 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
410 /* check for overflow */
411 if (adjusted_len < len)
413 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
414 RpcRaiseException(RPC_X_BAD_STUB_DATA);
417 p = pStubMsg->pfnAllocate(adjusted_len);
418 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
420 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
421 mem_list->magic = MEML_MAGIC;
422 mem_list->size = aligned_len;
423 mem_list->reserved = 0;
424 mem_list->next = pStubMsg->pMemoryList;
425 pStubMsg->pMemoryList = mem_list;
427 TRACE("-- %p\n", p);
428 return p;
431 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
433 TRACE("(%p, %p)\n", pStubMsg, Pointer);
435 pStubMsg->pfnFree(Pointer);
438 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
440 return (*(const ULONG *)pFormat != -1);
443 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
445 align_pointer(&pStubMsg->Buffer, 4);
446 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
447 RpcRaiseException(RPC_X_BAD_STUB_DATA);
448 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
449 pStubMsg->Buffer += 4;
450 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
451 if (pStubMsg->fHasNewCorrDesc)
452 return pFormat+6;
453 else
454 return pFormat+4;
457 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
459 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
461 pStubMsg->Offset = 0;
462 pStubMsg->ActualCount = pStubMsg->MaxCount;
463 goto done;
466 align_pointer(&pStubMsg->Buffer, 4);
467 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
468 RpcRaiseException(RPC_X_BAD_STUB_DATA);
469 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
470 pStubMsg->Buffer += 4;
471 TRACE("offset is %d\n", pStubMsg->Offset);
472 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
473 pStubMsg->Buffer += 4;
474 TRACE("variance is %d\n", pStubMsg->ActualCount);
476 if ((pStubMsg->ActualCount > MaxValue) ||
477 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
479 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
480 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
481 RpcRaiseException(RPC_S_INVALID_BOUND);
482 return NULL;
485 done:
486 if (pStubMsg->fHasNewCorrDesc)
487 return pFormat+6;
488 else
489 return pFormat+4;
492 /* writes the conformance value to the buffer */
493 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
495 align_pointer_clear(&pStubMsg->Buffer, 4);
496 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
497 RpcRaiseException(RPC_X_BAD_STUB_DATA);
498 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
499 pStubMsg->Buffer += 4;
502 /* writes the variance values to the buffer */
503 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
505 align_pointer_clear(&pStubMsg->Buffer, 4);
506 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
507 RpcRaiseException(RPC_X_BAD_STUB_DATA);
508 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
509 pStubMsg->Buffer += 4;
510 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
511 pStubMsg->Buffer += 4;
514 /* requests buffer space for the conformance value */
515 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
517 align_length(&pStubMsg->BufferLength, 4);
518 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
519 RpcRaiseException(RPC_X_BAD_STUB_DATA);
520 pStubMsg->BufferLength += 4;
523 /* requests buffer space for the variance values */
524 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
526 align_length(&pStubMsg->BufferLength, 4);
527 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
528 RpcRaiseException(RPC_X_BAD_STUB_DATA);
529 pStubMsg->BufferLength += 8;
532 PFORMAT_STRING ComputeConformanceOrVariance(
533 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
534 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
536 BYTE dtype = pFormat[0] & 0xf;
537 short ofs = *(const short *)&pFormat[2];
538 LPVOID ptr = NULL;
539 DWORD data = 0;
541 if (!IsConformanceOrVariancePresent(pFormat)) {
542 /* null descriptor */
543 *pCount = def;
544 goto finish_conf;
547 switch (pFormat[0] & 0xf0) {
548 case RPC_FC_NORMAL_CONFORMANCE:
549 TRACE("normal conformance, ofs=%d\n", ofs);
550 ptr = pMemory;
551 break;
552 case RPC_FC_POINTER_CONFORMANCE:
553 TRACE("pointer conformance, ofs=%d\n", ofs);
554 ptr = pStubMsg->Memory;
555 break;
556 case RPC_FC_TOP_LEVEL_CONFORMANCE:
557 TRACE("toplevel conformance, ofs=%d\n", ofs);
558 if (pStubMsg->StackTop) {
559 ptr = pStubMsg->StackTop;
561 else {
562 /* -Os mode, *pCount is already set */
563 goto finish_conf;
565 break;
566 case RPC_FC_CONSTANT_CONFORMANCE:
567 data = ofs | ((DWORD)pFormat[1] << 16);
568 TRACE("constant conformance, val=%d\n", data);
569 *pCount = data;
570 goto finish_conf;
571 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
572 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
573 if (pStubMsg->StackTop) {
574 ptr = pStubMsg->StackTop;
576 else {
577 /* ? */
578 goto done_conf_grab;
580 break;
581 default:
582 FIXME("unknown conformance type %x, expect crash.\n", pFormat[0] & 0xf0);
583 goto finish_conf;
586 switch (pFormat[1]) {
587 case RPC_FC_DEREFERENCE:
588 ptr = *(LPVOID*)((char *)ptr + ofs);
589 break;
590 case RPC_FC_CALLBACK:
592 unsigned char *old_stack_top = pStubMsg->StackTop;
593 pStubMsg->StackTop = ptr;
595 /* ofs is index into StubDesc->apfnExprEval */
596 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
597 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
599 pStubMsg->StackTop = old_stack_top;
601 /* the callback function always stores the computed value in MaxCount */
602 *pCount = pStubMsg->MaxCount;
603 goto finish_conf;
605 default:
606 ptr = (char *)ptr + ofs;
607 break;
610 switch (dtype) {
611 case RPC_FC_LONG:
612 case RPC_FC_ULONG:
613 data = *(DWORD*)ptr;
614 break;
615 case RPC_FC_SHORT:
616 data = *(SHORT*)ptr;
617 break;
618 case RPC_FC_USHORT:
619 data = *(USHORT*)ptr;
620 break;
621 case RPC_FC_CHAR:
622 case RPC_FC_SMALL:
623 data = *(CHAR*)ptr;
624 break;
625 case RPC_FC_BYTE:
626 case RPC_FC_USMALL:
627 data = *(UCHAR*)ptr;
628 break;
629 default:
630 FIXME("unknown conformance data type %x\n", dtype);
631 goto done_conf_grab;
633 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
635 done_conf_grab:
636 switch (pFormat[1]) {
637 case RPC_FC_DEREFERENCE: /* already handled */
638 case 0: /* no op */
639 *pCount = data;
640 break;
641 case RPC_FC_ADD_1:
642 *pCount = data + 1;
643 break;
644 case RPC_FC_SUB_1:
645 *pCount = data - 1;
646 break;
647 case RPC_FC_MULT_2:
648 *pCount = data * 2;
649 break;
650 case RPC_FC_DIV_2:
651 *pCount = data / 2;
652 break;
653 default:
654 FIXME("unknown conformance op %d\n", pFormat[1]);
655 goto finish_conf;
658 finish_conf:
659 TRACE("resulting conformance is %ld\n", *pCount);
660 if (pStubMsg->fHasNewCorrDesc)
661 return pFormat+6;
662 else
663 return pFormat+4;
666 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
667 PFORMAT_STRING pFormat)
669 if (pStubMsg->fHasNewCorrDesc)
670 pFormat += 6;
671 else
672 pFormat += 4;
673 return pFormat;
676 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
678 return SkipConformance( pStubMsg, pFormat );
681 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
682 * the result overflows 32-bits */
683 static inline ULONG safe_multiply(ULONG a, ULONG b)
685 ULONGLONG ret = (ULONGLONG)a * b;
686 if (ret > 0xffffffff)
688 RpcRaiseException(RPC_S_INVALID_BOUND);
689 return 0;
691 return ret;
694 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
696 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
697 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
698 RpcRaiseException(RPC_X_BAD_STUB_DATA);
699 pStubMsg->Buffer += size;
702 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
704 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
706 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
707 pStubMsg->BufferLength, size);
708 RpcRaiseException(RPC_X_BAD_STUB_DATA);
710 pStubMsg->BufferLength += size;
713 /* copies data from the buffer, checking that there is enough data in the buffer
714 * to do so */
715 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
717 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
718 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
720 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
721 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
722 RpcRaiseException(RPC_X_BAD_STUB_DATA);
724 if (p == pStubMsg->Buffer)
725 ERR("pointer is the same as the buffer\n");
726 memcpy(p, pStubMsg->Buffer, size);
727 pStubMsg->Buffer += size;
730 /* copies data to the buffer, checking that there is enough space to do so */
731 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
733 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
734 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
736 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
737 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
738 size);
739 RpcRaiseException(RPC_X_BAD_STUB_DATA);
741 memcpy(pStubMsg->Buffer, p, size);
742 pStubMsg->Buffer += size;
745 /* verify that string data sitting in the buffer is valid and safe to
746 * unmarshall */
747 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
749 ULONG i;
751 /* verify the buffer is safe to access */
752 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
753 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
755 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
756 pStubMsg->BufferEnd, pStubMsg->Buffer);
757 RpcRaiseException(RPC_X_BAD_STUB_DATA);
760 /* strings must always have null terminating bytes */
761 if (bufsize < esize)
763 ERR("invalid string length of %d\n", bufsize / esize);
764 RpcRaiseException(RPC_S_INVALID_BOUND);
767 for (i = bufsize - esize; i < bufsize; i++)
768 if (pStubMsg->Buffer[i] != 0)
770 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
771 i, pStubMsg->Buffer[i]);
772 RpcRaiseException(RPC_S_INVALID_BOUND);
776 static inline void dump_pointer_attr(unsigned char attr)
778 if (attr & RPC_FC_P_ALLOCALLNODES)
779 TRACE(" RPC_FC_P_ALLOCALLNODES");
780 if (attr & RPC_FC_P_DONTFREE)
781 TRACE(" RPC_FC_P_DONTFREE");
782 if (attr & RPC_FC_P_ONSTACK)
783 TRACE(" RPC_FC_P_ONSTACK");
784 if (attr & RPC_FC_P_SIMPLEPOINTER)
785 TRACE(" RPC_FC_P_SIMPLEPOINTER");
786 if (attr & RPC_FC_P_DEREF)
787 TRACE(" RPC_FC_P_DEREF");
788 TRACE("\n");
791 /***********************************************************************
792 * PointerMarshall [internal]
794 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
795 unsigned char *Buffer,
796 unsigned char *Pointer,
797 PFORMAT_STRING pFormat)
799 unsigned type = pFormat[0], attr = pFormat[1];
800 PFORMAT_STRING desc;
801 NDR_MARSHALL m;
802 ULONG pointer_id;
803 int pointer_needs_marshaling;
805 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
806 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
807 pFormat += 2;
808 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
809 else desc = pFormat + *(const SHORT*)pFormat;
811 switch (type) {
812 case RPC_FC_RP: /* ref pointer (always non-null) */
813 if (!Pointer)
815 ERR("NULL ref pointer is not allowed\n");
816 RpcRaiseException(RPC_X_NULL_REF_POINTER);
818 pointer_needs_marshaling = 1;
819 break;
820 case RPC_FC_UP: /* unique pointer */
821 case RPC_FC_OP: /* object pointer - same as unique here */
822 if (Pointer)
823 pointer_needs_marshaling = 1;
824 else
825 pointer_needs_marshaling = 0;
826 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
827 TRACE("writing 0x%08x to buffer\n", pointer_id);
828 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
829 break;
830 case RPC_FC_FP:
831 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
832 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
833 TRACE("writing 0x%08x to buffer\n", pointer_id);
834 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
835 break;
836 default:
837 FIXME("unhandled ptr type=%02x\n", type);
838 RpcRaiseException(RPC_X_BAD_STUB_DATA);
839 return;
842 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
844 if (pointer_needs_marshaling) {
845 if (attr & RPC_FC_P_DEREF) {
846 Pointer = *(unsigned char**)Pointer;
847 TRACE("deref => %p\n", Pointer);
849 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
850 if (m) m(pStubMsg, Pointer, desc);
851 else FIXME("no marshaller for data type=%02x\n", *desc);
854 STD_OVERFLOW_CHECK(pStubMsg);
857 /***********************************************************************
858 * PointerUnmarshall [internal]
860 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
861 unsigned char *Buffer,
862 unsigned char **pPointer,
863 unsigned char *pSrcPointer,
864 PFORMAT_STRING pFormat,
865 unsigned char fMustAlloc)
867 unsigned type = pFormat[0], attr = pFormat[1];
868 PFORMAT_STRING desc;
869 NDR_UNMARSHALL m;
870 DWORD pointer_id = 0;
871 int pointer_needs_unmarshaling;
873 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
874 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
875 pFormat += 2;
876 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
877 else desc = pFormat + *(const SHORT*)pFormat;
879 switch (type) {
880 case RPC_FC_RP: /* ref pointer (always non-null) */
881 pointer_needs_unmarshaling = 1;
882 break;
883 case RPC_FC_UP: /* unique pointer */
884 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
885 TRACE("pointer_id is 0x%08x\n", pointer_id);
886 if (pointer_id)
887 pointer_needs_unmarshaling = 1;
888 else {
889 *pPointer = NULL;
890 pointer_needs_unmarshaling = 0;
892 break;
893 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
894 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
895 TRACE("pointer_id is 0x%08x\n", pointer_id);
896 if (!fMustAlloc && pSrcPointer)
898 FIXME("free object pointer %p\n", pSrcPointer);
899 fMustAlloc = TRUE;
901 if (pointer_id)
902 pointer_needs_unmarshaling = 1;
903 else
905 *pPointer = NULL;
906 pointer_needs_unmarshaling = 0;
908 break;
909 case RPC_FC_FP:
910 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
911 TRACE("pointer_id is 0x%08x\n", pointer_id);
912 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
913 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
914 break;
915 default:
916 FIXME("unhandled ptr type=%02x\n", type);
917 RpcRaiseException(RPC_X_BAD_STUB_DATA);
918 return;
921 if (pointer_needs_unmarshaling) {
922 unsigned char **current_ptr = pPointer;
923 if (pStubMsg->IsClient) {
924 TRACE("client\n");
925 /* if we aren't forcing allocation of memory then try to use the existing
926 * (source) pointer to unmarshall the data into so that [in,out]
927 * parameters behave correctly. it doesn't matter if the parameter is
928 * [out] only since in that case the pointer will be NULL. we force
929 * allocation when the source pointer is NULL here instead of in the type
930 * unmarshalling routine for the benefit of the deref code below */
931 if (!fMustAlloc) {
932 if (pSrcPointer) {
933 TRACE("setting *pPointer to %p\n", pSrcPointer);
934 *pPointer = pSrcPointer;
935 } else
936 fMustAlloc = TRUE;
938 } else {
939 TRACE("server\n");
940 /* the memory in a stub is never initialised, so we have to work out here
941 * whether we have to initialise it so we can use the optimisation of
942 * setting the pointer to the buffer, if possible, or set fMustAlloc to
943 * TRUE. */
944 if (attr & RPC_FC_P_DEREF) {
945 fMustAlloc = TRUE;
946 } else {
947 *current_ptr = NULL;
951 if (attr & RPC_FC_P_ALLOCALLNODES)
952 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
954 if (attr & RPC_FC_P_DEREF) {
955 if (fMustAlloc) {
956 unsigned char *base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
957 *pPointer = base_ptr_val;
958 current_ptr = (unsigned char **)base_ptr_val;
959 } else
960 current_ptr = *(unsigned char***)current_ptr;
961 TRACE("deref => %p\n", current_ptr);
962 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
964 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
965 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
966 else FIXME("no unmarshaller for data type=%02x\n", *desc);
968 if (type == RPC_FC_FP)
969 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
970 *pPointer);
973 TRACE("pointer=%p\n", *pPointer);
976 /***********************************************************************
977 * PointerBufferSize [internal]
979 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
980 unsigned char *Pointer,
981 PFORMAT_STRING pFormat)
983 unsigned type = pFormat[0], attr = pFormat[1];
984 PFORMAT_STRING desc;
985 NDR_BUFFERSIZE m;
986 int pointer_needs_sizing;
987 ULONG pointer_id;
989 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
990 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
991 pFormat += 2;
992 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
993 else desc = pFormat + *(const SHORT*)pFormat;
995 switch (type) {
996 case RPC_FC_RP: /* ref pointer (always non-null) */
997 if (!Pointer)
999 ERR("NULL ref pointer is not allowed\n");
1000 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1002 break;
1003 case RPC_FC_OP:
1004 case RPC_FC_UP:
1005 /* NULL pointer has no further representation */
1006 if (!Pointer)
1007 return;
1008 break;
1009 case RPC_FC_FP:
1010 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1011 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1012 if (!pointer_needs_sizing)
1013 return;
1014 break;
1015 default:
1016 FIXME("unhandled ptr type=%02x\n", type);
1017 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1018 return;
1021 if (attr & RPC_FC_P_DEREF) {
1022 Pointer = *(unsigned char**)Pointer;
1023 TRACE("deref => %p\n", Pointer);
1026 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1027 if (m) m(pStubMsg, Pointer, desc);
1028 else FIXME("no buffersizer for data type=%02x\n", *desc);
1031 /***********************************************************************
1032 * PointerMemorySize [internal]
1034 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1035 unsigned char *Buffer, PFORMAT_STRING pFormat)
1037 unsigned type = pFormat[0], attr = pFormat[1];
1038 PFORMAT_STRING desc;
1039 NDR_MEMORYSIZE m;
1040 DWORD pointer_id = 0;
1041 int pointer_needs_sizing;
1043 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1044 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1045 pFormat += 2;
1046 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1047 else desc = pFormat + *(const SHORT*)pFormat;
1049 switch (type) {
1050 case RPC_FC_RP: /* ref pointer (always non-null) */
1051 pointer_needs_sizing = 1;
1052 break;
1053 case RPC_FC_UP: /* unique pointer */
1054 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1055 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1056 TRACE("pointer_id is 0x%08x\n", pointer_id);
1057 if (pointer_id)
1058 pointer_needs_sizing = 1;
1059 else
1060 pointer_needs_sizing = 0;
1061 break;
1062 case RPC_FC_FP:
1064 void *pointer;
1065 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1066 TRACE("pointer_id is 0x%08x\n", pointer_id);
1067 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1068 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1069 break;
1071 default:
1072 FIXME("unhandled ptr type=%02x\n", type);
1073 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1074 return 0;
1077 if (attr & RPC_FC_P_DEREF) {
1078 align_length(&pStubMsg->MemorySize, sizeof(void*));
1079 pStubMsg->MemorySize += sizeof(void*);
1080 TRACE("deref\n");
1083 if (pointer_needs_sizing) {
1084 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1085 if (m) m(pStubMsg, desc);
1086 else FIXME("no memorysizer for data type=%02x\n", *desc);
1089 return pStubMsg->MemorySize;
1092 /***********************************************************************
1093 * PointerFree [internal]
1095 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1096 unsigned char *Pointer,
1097 PFORMAT_STRING pFormat)
1099 unsigned type = pFormat[0], attr = pFormat[1];
1100 PFORMAT_STRING desc;
1101 NDR_FREE m;
1102 unsigned char *current_pointer = Pointer;
1104 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1105 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1106 if (attr & RPC_FC_P_DONTFREE) return;
1107 pFormat += 2;
1108 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1109 else desc = pFormat + *(const SHORT*)pFormat;
1111 if (!Pointer) return;
1113 if (type == RPC_FC_FP) {
1114 int pointer_needs_freeing = NdrFullPointerFree(
1115 pStubMsg->FullPtrXlatTables, Pointer);
1116 if (!pointer_needs_freeing)
1117 return;
1120 if (attr & RPC_FC_P_DEREF) {
1121 current_pointer = *(unsigned char**)Pointer;
1122 TRACE("deref => %p\n", current_pointer);
1125 m = NdrFreer[*desc & NDR_TABLE_MASK];
1126 if (m) m(pStubMsg, current_pointer, desc);
1128 /* this check stops us from trying to free buffer memory. we don't have to
1129 * worry about clients, since they won't call this function.
1130 * we don't have to check for the buffer being reallocated because
1131 * BufferStart and BufferEnd won't be reset when allocating memory for
1132 * sending the response. we don't have to check for the new buffer here as
1133 * it won't be used a type memory, only for buffer memory */
1134 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1135 goto notfree;
1137 if (attr & RPC_FC_P_ONSTACK) {
1138 TRACE("not freeing stack ptr %p\n", Pointer);
1139 return;
1141 TRACE("freeing %p\n", Pointer);
1142 NdrFree(pStubMsg, Pointer);
1143 return;
1144 notfree:
1145 TRACE("not freeing %p\n", Pointer);
1148 /***********************************************************************
1149 * EmbeddedPointerMarshall
1151 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1152 unsigned char *pMemory,
1153 PFORMAT_STRING pFormat)
1155 unsigned char *Mark = pStubMsg->BufferMark;
1156 unsigned rep, count, stride;
1157 unsigned i;
1158 unsigned char *saved_buffer = NULL;
1160 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1162 if (*pFormat != RPC_FC_PP) return NULL;
1163 pFormat += 2;
1165 if (pStubMsg->PointerBufferMark)
1167 saved_buffer = pStubMsg->Buffer;
1168 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1169 pStubMsg->PointerBufferMark = NULL;
1172 while (pFormat[0] != RPC_FC_END) {
1173 switch (pFormat[0]) {
1174 default:
1175 FIXME("unknown repeat type %d\n", pFormat[0]);
1176 case RPC_FC_NO_REPEAT:
1177 rep = 1;
1178 stride = 0;
1179 count = 1;
1180 pFormat += 2;
1181 break;
1182 case RPC_FC_FIXED_REPEAT:
1183 rep = *(const WORD*)&pFormat[2];
1184 stride = *(const WORD*)&pFormat[4];
1185 count = *(const WORD*)&pFormat[8];
1186 pFormat += 10;
1187 break;
1188 case RPC_FC_VARIABLE_REPEAT:
1189 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1190 stride = *(const WORD*)&pFormat[2];
1191 count = *(const WORD*)&pFormat[6];
1192 pFormat += 8;
1193 break;
1195 for (i = 0; i < rep; i++) {
1196 PFORMAT_STRING info = pFormat;
1197 unsigned char *membase = pMemory + (i * stride);
1198 unsigned char *bufbase = Mark + (i * stride);
1199 unsigned u;
1201 for (u=0; u<count; u++,info+=8) {
1202 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1203 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1204 unsigned char *saved_memory = pStubMsg->Memory;
1206 pStubMsg->Memory = pMemory;
1207 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1208 pStubMsg->Memory = saved_memory;
1211 pFormat += 8 * count;
1214 if (saved_buffer)
1216 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1217 pStubMsg->Buffer = saved_buffer;
1220 STD_OVERFLOW_CHECK(pStubMsg);
1222 return NULL;
1225 /***********************************************************************
1226 * EmbeddedPointerUnmarshall
1228 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1229 unsigned char *pDstBuffer,
1230 unsigned char *pSrcMemoryPtrs,
1231 PFORMAT_STRING pFormat,
1232 unsigned char fMustAlloc)
1234 unsigned char *Mark = pStubMsg->BufferMark;
1235 unsigned rep, count, stride;
1236 unsigned i;
1237 unsigned char *saved_buffer = NULL;
1239 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1241 if (*pFormat != RPC_FC_PP) return NULL;
1242 pFormat += 2;
1244 if (pStubMsg->PointerBufferMark)
1246 saved_buffer = pStubMsg->Buffer;
1247 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1248 pStubMsg->PointerBufferMark = NULL;
1251 while (pFormat[0] != RPC_FC_END) {
1252 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1253 switch (pFormat[0]) {
1254 default:
1255 FIXME("unknown repeat type %d\n", pFormat[0]);
1256 case RPC_FC_NO_REPEAT:
1257 rep = 1;
1258 stride = 0;
1259 count = 1;
1260 pFormat += 2;
1261 break;
1262 case RPC_FC_FIXED_REPEAT:
1263 rep = *(const WORD*)&pFormat[2];
1264 stride = *(const WORD*)&pFormat[4];
1265 count = *(const WORD*)&pFormat[8];
1266 pFormat += 10;
1267 break;
1268 case RPC_FC_VARIABLE_REPEAT:
1269 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1270 stride = *(const WORD*)&pFormat[2];
1271 count = *(const WORD*)&pFormat[6];
1272 pFormat += 8;
1273 break;
1275 for (i = 0; i < rep; i++) {
1276 PFORMAT_STRING info = pFormat;
1277 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1278 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1279 unsigned char *bufbase = Mark + (i * stride);
1280 unsigned u;
1282 for (u=0; u<count; u++,info+=8) {
1283 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1284 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1285 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1286 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1289 pFormat += 8 * count;
1292 if (saved_buffer)
1294 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1295 pStubMsg->Buffer = saved_buffer;
1298 return NULL;
1301 /***********************************************************************
1302 * EmbeddedPointerBufferSize
1304 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1305 unsigned char *pMemory,
1306 PFORMAT_STRING pFormat)
1308 unsigned rep, count, stride;
1309 unsigned i;
1310 ULONG saved_buffer_length = 0;
1312 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1314 if (pStubMsg->IgnoreEmbeddedPointers) return;
1316 if (*pFormat != RPC_FC_PP) return;
1317 pFormat += 2;
1319 if (pStubMsg->PointerLength)
1321 saved_buffer_length = pStubMsg->BufferLength;
1322 pStubMsg->BufferLength = pStubMsg->PointerLength;
1323 pStubMsg->PointerLength = 0;
1326 while (pFormat[0] != RPC_FC_END) {
1327 switch (pFormat[0]) {
1328 default:
1329 FIXME("unknown repeat type %d\n", pFormat[0]);
1330 case RPC_FC_NO_REPEAT:
1331 rep = 1;
1332 stride = 0;
1333 count = 1;
1334 pFormat += 2;
1335 break;
1336 case RPC_FC_FIXED_REPEAT:
1337 rep = *(const WORD*)&pFormat[2];
1338 stride = *(const WORD*)&pFormat[4];
1339 count = *(const WORD*)&pFormat[8];
1340 pFormat += 10;
1341 break;
1342 case RPC_FC_VARIABLE_REPEAT:
1343 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1344 stride = *(const WORD*)&pFormat[2];
1345 count = *(const WORD*)&pFormat[6];
1346 pFormat += 8;
1347 break;
1349 for (i = 0; i < rep; i++) {
1350 PFORMAT_STRING info = pFormat;
1351 unsigned char *membase = pMemory + (i * stride);
1352 unsigned u;
1354 for (u=0; u<count; u++,info+=8) {
1355 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1356 unsigned char *saved_memory = pStubMsg->Memory;
1358 pStubMsg->Memory = pMemory;
1359 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1360 pStubMsg->Memory = saved_memory;
1363 pFormat += 8 * count;
1366 if (saved_buffer_length)
1368 pStubMsg->PointerLength = pStubMsg->BufferLength;
1369 pStubMsg->BufferLength = saved_buffer_length;
1373 /***********************************************************************
1374 * EmbeddedPointerMemorySize [internal]
1376 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1377 PFORMAT_STRING pFormat)
1379 unsigned char *Mark = pStubMsg->BufferMark;
1380 unsigned rep, count, stride;
1381 unsigned i;
1382 unsigned char *saved_buffer = NULL;
1384 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1386 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1388 if (pStubMsg->PointerBufferMark)
1390 saved_buffer = pStubMsg->Buffer;
1391 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1392 pStubMsg->PointerBufferMark = NULL;
1395 if (*pFormat != RPC_FC_PP) return 0;
1396 pFormat += 2;
1398 while (pFormat[0] != RPC_FC_END) {
1399 switch (pFormat[0]) {
1400 default:
1401 FIXME("unknown repeat type %d\n", pFormat[0]);
1402 case RPC_FC_NO_REPEAT:
1403 rep = 1;
1404 stride = 0;
1405 count = 1;
1406 pFormat += 2;
1407 break;
1408 case RPC_FC_FIXED_REPEAT:
1409 rep = *(const WORD*)&pFormat[2];
1410 stride = *(const WORD*)&pFormat[4];
1411 count = *(const WORD*)&pFormat[8];
1412 pFormat += 10;
1413 break;
1414 case RPC_FC_VARIABLE_REPEAT:
1415 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1416 stride = *(const WORD*)&pFormat[2];
1417 count = *(const WORD*)&pFormat[6];
1418 pFormat += 8;
1419 break;
1421 for (i = 0; i < rep; i++) {
1422 PFORMAT_STRING info = pFormat;
1423 unsigned char *bufbase = Mark + (i * stride);
1424 unsigned u;
1425 for (u=0; u<count; u++,info+=8) {
1426 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1427 PointerMemorySize(pStubMsg, bufptr, info+4);
1430 pFormat += 8 * count;
1433 if (saved_buffer)
1435 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1436 pStubMsg->Buffer = saved_buffer;
1439 return 0;
1442 /***********************************************************************
1443 * EmbeddedPointerFree [internal]
1445 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1446 unsigned char *pMemory,
1447 PFORMAT_STRING pFormat)
1449 unsigned rep, count, stride;
1450 unsigned i;
1452 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1453 if (*pFormat != RPC_FC_PP) return;
1454 pFormat += 2;
1456 while (pFormat[0] != RPC_FC_END) {
1457 switch (pFormat[0]) {
1458 default:
1459 FIXME("unknown repeat type %d\n", pFormat[0]);
1460 case RPC_FC_NO_REPEAT:
1461 rep = 1;
1462 stride = 0;
1463 count = 1;
1464 pFormat += 2;
1465 break;
1466 case RPC_FC_FIXED_REPEAT:
1467 rep = *(const WORD*)&pFormat[2];
1468 stride = *(const WORD*)&pFormat[4];
1469 count = *(const WORD*)&pFormat[8];
1470 pFormat += 10;
1471 break;
1472 case RPC_FC_VARIABLE_REPEAT:
1473 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1474 stride = *(const WORD*)&pFormat[2];
1475 count = *(const WORD*)&pFormat[6];
1476 pFormat += 8;
1477 break;
1479 for (i = 0; i < rep; i++) {
1480 PFORMAT_STRING info = pFormat;
1481 unsigned char *membase = pMemory + (i * stride);
1482 unsigned u;
1484 for (u=0; u<count; u++,info+=8) {
1485 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1486 unsigned char *saved_memory = pStubMsg->Memory;
1488 pStubMsg->Memory = pMemory;
1489 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1490 pStubMsg->Memory = saved_memory;
1493 pFormat += 8 * count;
1497 /***********************************************************************
1498 * NdrPointerMarshall [RPCRT4.@]
1500 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1501 unsigned char *pMemory,
1502 PFORMAT_STRING pFormat)
1504 unsigned char *Buffer;
1506 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1508 /* Increment the buffer here instead of in PointerMarshall,
1509 * as that is used by embedded pointers which already handle the incrementing
1510 * the buffer, and shouldn't write any additional pointer data to the wire */
1511 if (*pFormat != RPC_FC_RP)
1513 align_pointer_clear(&pStubMsg->Buffer, 4);
1514 Buffer = pStubMsg->Buffer;
1515 safe_buffer_increment(pStubMsg, 4);
1517 else
1518 Buffer = pStubMsg->Buffer;
1520 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1522 return NULL;
1525 /***********************************************************************
1526 * NdrPointerUnmarshall [RPCRT4.@]
1528 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1529 unsigned char **ppMemory,
1530 PFORMAT_STRING pFormat,
1531 unsigned char fMustAlloc)
1533 unsigned char *Buffer;
1535 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1537 if (*pFormat == RPC_FC_RP)
1539 Buffer = pStubMsg->Buffer;
1540 /* Do the NULL ref pointer check here because embedded pointers can be
1541 * NULL if the type the pointer is embedded in was allocated rather than
1542 * being passed in by the client */
1543 if (pStubMsg->IsClient && !*ppMemory)
1545 ERR("NULL ref pointer is not allowed\n");
1546 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1549 else
1551 /* Increment the buffer here instead of in PointerUnmarshall,
1552 * as that is used by embedded pointers which already handle the incrementing
1553 * the buffer, and shouldn't read any additional pointer data from the
1554 * buffer */
1555 align_pointer(&pStubMsg->Buffer, 4);
1556 Buffer = pStubMsg->Buffer;
1557 safe_buffer_increment(pStubMsg, 4);
1560 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1562 return NULL;
1565 /***********************************************************************
1566 * NdrPointerBufferSize [RPCRT4.@]
1568 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1569 unsigned char *pMemory,
1570 PFORMAT_STRING pFormat)
1572 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1574 /* Increment the buffer length here instead of in PointerBufferSize,
1575 * as that is used by embedded pointers which already handle the buffer
1576 * length, and shouldn't write anything more to the wire */
1577 if (*pFormat != RPC_FC_RP)
1579 align_length(&pStubMsg->BufferLength, 4);
1580 safe_buffer_length_increment(pStubMsg, 4);
1583 PointerBufferSize(pStubMsg, pMemory, pFormat);
1586 /***********************************************************************
1587 * NdrPointerMemorySize [RPCRT4.@]
1589 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1590 PFORMAT_STRING pFormat)
1592 unsigned char *Buffer = pStubMsg->Buffer;
1593 if (*pFormat != RPC_FC_RP)
1595 align_pointer(&pStubMsg->Buffer, 4);
1596 safe_buffer_increment(pStubMsg, 4);
1598 align_length(&pStubMsg->MemorySize, sizeof(void *));
1599 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1602 /***********************************************************************
1603 * NdrPointerFree [RPCRT4.@]
1605 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1606 unsigned char *pMemory,
1607 PFORMAT_STRING pFormat)
1609 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1610 PointerFree(pStubMsg, pMemory, pFormat);
1613 /***********************************************************************
1614 * NdrSimpleTypeMarshall [RPCRT4.@]
1616 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1617 unsigned char FormatChar )
1619 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1622 /***********************************************************************
1623 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1625 * Unmarshall a base type.
1627 * NOTES
1628 * Doesn't check that the buffer is long enough before copying, so the caller
1629 * should do this.
1631 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1632 unsigned char FormatChar )
1634 #define BASE_TYPE_UNMARSHALL(type) \
1635 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1636 TRACE("pMemory: %p\n", pMemory); \
1637 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1638 pStubMsg->Buffer += sizeof(type);
1640 switch(FormatChar)
1642 case RPC_FC_BYTE:
1643 case RPC_FC_CHAR:
1644 case RPC_FC_SMALL:
1645 case RPC_FC_USMALL:
1646 BASE_TYPE_UNMARSHALL(UCHAR);
1647 TRACE("value: 0x%02x\n", *pMemory);
1648 break;
1649 case RPC_FC_WCHAR:
1650 case RPC_FC_SHORT:
1651 case RPC_FC_USHORT:
1652 BASE_TYPE_UNMARSHALL(USHORT);
1653 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1654 break;
1655 case RPC_FC_LONG:
1656 case RPC_FC_ULONG:
1657 case RPC_FC_ERROR_STATUS_T:
1658 case RPC_FC_ENUM32:
1659 BASE_TYPE_UNMARSHALL(ULONG);
1660 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1661 break;
1662 case RPC_FC_FLOAT:
1663 BASE_TYPE_UNMARSHALL(float);
1664 TRACE("value: %f\n", *(float *)pMemory);
1665 break;
1666 case RPC_FC_DOUBLE:
1667 BASE_TYPE_UNMARSHALL(double);
1668 TRACE("value: %f\n", *(double *)pMemory);
1669 break;
1670 case RPC_FC_HYPER:
1671 BASE_TYPE_UNMARSHALL(ULONGLONG);
1672 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1673 break;
1674 case RPC_FC_ENUM16:
1675 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
1676 TRACE("pMemory: %p\n", pMemory);
1677 /* 16-bits on the wire, but int in memory */
1678 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1679 pStubMsg->Buffer += sizeof(USHORT);
1680 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1681 break;
1682 case RPC_FC_INT3264:
1683 align_pointer(&pStubMsg->Buffer, sizeof(INT));
1684 /* 32-bits on the wire, but int_ptr in memory */
1685 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer;
1686 pStubMsg->Buffer += sizeof(INT);
1687 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory);
1688 break;
1689 case RPC_FC_UINT3264:
1690 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
1691 /* 32-bits on the wire, but int_ptr in memory */
1692 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer;
1693 pStubMsg->Buffer += sizeof(UINT);
1694 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory);
1695 break;
1696 case RPC_FC_IGNORE:
1697 break;
1698 default:
1699 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1701 #undef BASE_TYPE_UNMARSHALL
1704 /***********************************************************************
1705 * NdrSimpleStructMarshall [RPCRT4.@]
1707 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1708 unsigned char *pMemory,
1709 PFORMAT_STRING pFormat)
1711 unsigned size = *(const WORD*)(pFormat+2);
1712 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1714 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
1716 pStubMsg->BufferMark = pStubMsg->Buffer;
1717 safe_copy_to_buffer(pStubMsg, pMemory, size);
1719 if (pFormat[0] != RPC_FC_STRUCT)
1720 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1722 return NULL;
1725 /***********************************************************************
1726 * NdrSimpleStructUnmarshall [RPCRT4.@]
1728 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1729 unsigned char **ppMemory,
1730 PFORMAT_STRING pFormat,
1731 unsigned char fMustAlloc)
1733 unsigned size = *(const WORD*)(pFormat+2);
1734 unsigned char *saved_buffer;
1735 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1737 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1739 if (fMustAlloc)
1740 *ppMemory = NdrAllocate(pStubMsg, size);
1741 else
1743 if (!pStubMsg->IsClient && !*ppMemory)
1744 /* for servers, we just point straight into the RPC buffer */
1745 *ppMemory = pStubMsg->Buffer;
1748 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1749 safe_buffer_increment(pStubMsg, size);
1750 if (pFormat[0] == RPC_FC_PSTRUCT)
1751 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1753 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1754 if (*ppMemory != saved_buffer)
1755 memcpy(*ppMemory, saved_buffer, size);
1757 return NULL;
1760 /***********************************************************************
1761 * NdrSimpleStructBufferSize [RPCRT4.@]
1763 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1764 unsigned char *pMemory,
1765 PFORMAT_STRING pFormat)
1767 unsigned size = *(const WORD*)(pFormat+2);
1768 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1770 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
1772 safe_buffer_length_increment(pStubMsg, size);
1773 if (pFormat[0] != RPC_FC_STRUCT)
1774 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1777 /***********************************************************************
1778 * NdrSimpleStructMemorySize [RPCRT4.@]
1780 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1781 PFORMAT_STRING pFormat)
1783 unsigned short size = *(const WORD *)(pFormat+2);
1785 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1787 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1788 pStubMsg->MemorySize += size;
1789 safe_buffer_increment(pStubMsg, size);
1791 if (pFormat[0] != RPC_FC_STRUCT)
1792 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1793 return pStubMsg->MemorySize;
1796 /***********************************************************************
1797 * NdrSimpleStructFree [RPCRT4.@]
1799 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1800 unsigned char *pMemory,
1801 PFORMAT_STRING pFormat)
1803 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1804 if (pFormat[0] != RPC_FC_STRUCT)
1805 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1808 /* Array helpers */
1810 static inline void array_compute_and_size_conformance(
1811 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1812 PFORMAT_STRING pFormat)
1814 DWORD count;
1816 switch (fc)
1818 case RPC_FC_CARRAY:
1819 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1820 SizeConformance(pStubMsg);
1821 break;
1822 case RPC_FC_CVARRAY:
1823 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1824 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1825 SizeConformance(pStubMsg);
1826 break;
1827 case RPC_FC_C_CSTRING:
1828 case RPC_FC_C_WSTRING:
1829 if (fc == RPC_FC_C_CSTRING)
1831 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1832 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1834 else
1836 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1837 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1840 if (pFormat[1] == RPC_FC_STRING_SIZED)
1841 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1842 else
1843 pStubMsg->MaxCount = pStubMsg->ActualCount;
1845 SizeConformance(pStubMsg);
1846 break;
1847 case RPC_FC_BOGUS_ARRAY:
1848 count = *(const WORD *)(pFormat + 2);
1849 pFormat += 4;
1850 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg);
1851 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count);
1852 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1853 break;
1854 default:
1855 ERR("unknown array format 0x%x\n", fc);
1856 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1860 static inline void array_buffer_size(
1861 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1862 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1864 DWORD i, size;
1865 DWORD esize;
1866 unsigned char alignment;
1868 switch (fc)
1870 case RPC_FC_CARRAY:
1871 esize = *(const WORD*)(pFormat+2);
1872 alignment = pFormat[1] + 1;
1874 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1876 align_length(&pStubMsg->BufferLength, alignment);
1878 size = safe_multiply(esize, pStubMsg->MaxCount);
1879 /* conformance value plus array */
1880 safe_buffer_length_increment(pStubMsg, size);
1882 if (fHasPointers)
1883 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1884 break;
1885 case RPC_FC_CVARRAY:
1886 esize = *(const WORD*)(pFormat+2);
1887 alignment = pFormat[1] + 1;
1889 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1890 pFormat = SkipVariance(pStubMsg, pFormat);
1892 SizeVariance(pStubMsg);
1894 align_length(&pStubMsg->BufferLength, alignment);
1896 size = safe_multiply(esize, pStubMsg->ActualCount);
1897 safe_buffer_length_increment(pStubMsg, size);
1899 if (fHasPointers)
1900 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1901 break;
1902 case RPC_FC_C_CSTRING:
1903 case RPC_FC_C_WSTRING:
1904 if (fc == RPC_FC_C_CSTRING)
1905 esize = 1;
1906 else
1907 esize = 2;
1909 SizeVariance(pStubMsg);
1911 size = safe_multiply(esize, pStubMsg->ActualCount);
1912 safe_buffer_length_increment(pStubMsg, size);
1913 break;
1914 case RPC_FC_BOGUS_ARRAY:
1915 alignment = pFormat[1] + 1;
1916 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1917 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg);
1918 pFormat = SkipVariance(pStubMsg, pFormat);
1920 align_length(&pStubMsg->BufferLength, alignment);
1922 size = pStubMsg->ActualCount;
1923 for (i = 0; i < size; i++)
1924 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1925 break;
1926 default:
1927 ERR("unknown array format 0x%x\n", fc);
1928 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1932 static inline void array_compute_and_write_conformance(
1933 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1934 PFORMAT_STRING pFormat)
1936 ULONG def;
1937 BOOL conformance_present;
1939 switch (fc)
1941 case RPC_FC_CARRAY:
1942 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1943 WriteConformance(pStubMsg);
1944 break;
1945 case RPC_FC_CVARRAY:
1946 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1947 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1948 WriteConformance(pStubMsg);
1949 break;
1950 case RPC_FC_C_CSTRING:
1951 case RPC_FC_C_WSTRING:
1952 if (fc == RPC_FC_C_CSTRING)
1954 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1955 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1957 else
1959 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1960 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1962 if (pFormat[1] == RPC_FC_STRING_SIZED)
1963 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1964 else
1965 pStubMsg->MaxCount = pStubMsg->ActualCount;
1966 pStubMsg->Offset = 0;
1967 WriteConformance(pStubMsg);
1968 break;
1969 case RPC_FC_BOGUS_ARRAY:
1970 def = *(const WORD *)(pFormat + 2);
1971 pFormat += 4;
1972 conformance_present = IsConformanceOrVariancePresent(pFormat);
1973 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1974 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1975 if (conformance_present) WriteConformance(pStubMsg);
1976 break;
1977 default:
1978 ERR("unknown array format 0x%x\n", fc);
1979 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1983 static inline void array_write_variance_and_marshall(
1984 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1985 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1987 DWORD i, size;
1988 DWORD esize;
1989 unsigned char alignment;
1991 switch (fc)
1993 case RPC_FC_CARRAY:
1994 esize = *(const WORD*)(pFormat+2);
1995 alignment = pFormat[1] + 1;
1997 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1999 align_pointer_clear(&pStubMsg->Buffer, alignment);
2001 size = safe_multiply(esize, pStubMsg->MaxCount);
2002 if (fHasPointers)
2003 pStubMsg->BufferMark = pStubMsg->Buffer;
2004 safe_copy_to_buffer(pStubMsg, pMemory, size);
2006 if (fHasPointers)
2007 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2008 break;
2009 case RPC_FC_CVARRAY:
2010 esize = *(const WORD*)(pFormat+2);
2011 alignment = pFormat[1] + 1;
2013 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2014 pFormat = SkipVariance(pStubMsg, pFormat);
2016 WriteVariance(pStubMsg);
2018 align_pointer_clear(&pStubMsg->Buffer, alignment);
2020 size = safe_multiply(esize, pStubMsg->ActualCount);
2022 if (fHasPointers)
2023 pStubMsg->BufferMark = pStubMsg->Buffer;
2024 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
2026 if (fHasPointers)
2027 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2028 break;
2029 case RPC_FC_C_CSTRING:
2030 case RPC_FC_C_WSTRING:
2031 if (fc == RPC_FC_C_CSTRING)
2032 esize = 1;
2033 else
2034 esize = 2;
2036 WriteVariance(pStubMsg);
2038 size = safe_multiply(esize, pStubMsg->ActualCount);
2039 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2040 break;
2041 case RPC_FC_BOGUS_ARRAY:
2042 alignment = pFormat[1] + 1;
2043 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2044 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg);
2045 pFormat = SkipVariance(pStubMsg, pFormat);
2047 align_pointer_clear(&pStubMsg->Buffer, alignment);
2049 size = pStubMsg->ActualCount;
2050 for (i = 0; i < size; i++)
2051 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2052 break;
2053 default:
2054 ERR("unknown array format 0x%x\n", fc);
2055 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2059 static inline ULONG array_read_conformance(
2060 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
2062 DWORD def, esize;
2064 switch (fc)
2066 case RPC_FC_CARRAY:
2067 esize = *(const WORD*)(pFormat+2);
2068 pFormat = ReadConformance(pStubMsg, pFormat+4);
2069 return safe_multiply(esize, pStubMsg->MaxCount);
2070 case RPC_FC_CVARRAY:
2071 esize = *(const WORD*)(pFormat+2);
2072 pFormat = ReadConformance(pStubMsg, pFormat+4);
2073 return safe_multiply(esize, pStubMsg->MaxCount);
2074 case RPC_FC_C_CSTRING:
2075 case RPC_FC_C_WSTRING:
2076 if (fc == RPC_FC_C_CSTRING)
2077 esize = 1;
2078 else
2079 esize = 2;
2081 if (pFormat[1] == RPC_FC_STRING_SIZED)
2082 ReadConformance(pStubMsg, pFormat + 2);
2083 else
2084 ReadConformance(pStubMsg, NULL);
2085 return safe_multiply(esize, pStubMsg->MaxCount);
2086 case RPC_FC_BOGUS_ARRAY:
2087 def = *(const WORD *)(pFormat + 2);
2088 pFormat += 4;
2089 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2090 else
2092 pStubMsg->MaxCount = def;
2093 pFormat = SkipConformance( pStubMsg, pFormat );
2095 pFormat = SkipVariance( pStubMsg, pFormat );
2097 esize = ComplexStructSize(pStubMsg, pFormat);
2098 return safe_multiply(pStubMsg->MaxCount, esize);
2099 default:
2100 ERR("unknown array format 0x%x\n", fc);
2101 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2105 static inline ULONG array_read_variance_and_unmarshall(
2106 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2107 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2108 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2110 ULONG bufsize, memsize;
2111 WORD esize;
2112 unsigned char alignment;
2113 unsigned char *saved_buffer, *pMemory;
2114 ULONG i, offset, count;
2116 switch (fc)
2118 case RPC_FC_CARRAY:
2119 esize = *(const WORD*)(pFormat+2);
2120 alignment = pFormat[1] + 1;
2122 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2124 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2126 align_pointer(&pStubMsg->Buffer, alignment);
2128 if (fUnmarshall)
2130 if (fMustAlloc)
2131 *ppMemory = NdrAllocate(pStubMsg, memsize);
2132 else
2134 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2135 /* for servers, we just point straight into the RPC buffer */
2136 *ppMemory = pStubMsg->Buffer;
2139 saved_buffer = pStubMsg->Buffer;
2140 safe_buffer_increment(pStubMsg, bufsize);
2142 pStubMsg->BufferMark = saved_buffer;
2143 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2145 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2146 if (*ppMemory != saved_buffer)
2147 memcpy(*ppMemory, saved_buffer, bufsize);
2149 return bufsize;
2150 case RPC_FC_CVARRAY:
2151 esize = *(const WORD*)(pFormat+2);
2152 alignment = pFormat[1] + 1;
2154 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2156 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2158 align_pointer(&pStubMsg->Buffer, alignment);
2160 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2161 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2163 if (fUnmarshall)
2165 offset = pStubMsg->Offset;
2167 if (!fMustAlloc && !*ppMemory)
2168 fMustAlloc = TRUE;
2169 if (fMustAlloc)
2170 *ppMemory = NdrAllocate(pStubMsg, memsize);
2171 saved_buffer = pStubMsg->Buffer;
2172 safe_buffer_increment(pStubMsg, bufsize);
2174 pStubMsg->BufferMark = saved_buffer;
2175 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2176 fMustAlloc);
2178 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2180 return bufsize;
2181 case RPC_FC_C_CSTRING:
2182 case RPC_FC_C_WSTRING:
2183 if (fc == RPC_FC_C_CSTRING)
2184 esize = 1;
2185 else
2186 esize = 2;
2188 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2190 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2192 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2193 pStubMsg->ActualCount, pStubMsg->MaxCount);
2194 RpcRaiseException(RPC_S_INVALID_BOUND);
2196 if (pStubMsg->Offset)
2198 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2199 RpcRaiseException(RPC_S_INVALID_BOUND);
2202 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2203 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2205 validate_string_data(pStubMsg, bufsize, esize);
2207 if (fUnmarshall)
2209 if (fMustAlloc)
2210 *ppMemory = NdrAllocate(pStubMsg, memsize);
2211 else
2213 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2214 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2215 /* if the data in the RPC buffer is big enough, we just point
2216 * straight into it */
2217 *ppMemory = pStubMsg->Buffer;
2218 else if (!*ppMemory)
2219 *ppMemory = NdrAllocate(pStubMsg, memsize);
2222 if (*ppMemory == pStubMsg->Buffer)
2223 safe_buffer_increment(pStubMsg, bufsize);
2224 else
2225 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2227 if (*pFormat == RPC_FC_C_CSTRING)
2228 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2229 else
2230 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2232 return bufsize;
2234 case RPC_FC_BOGUS_ARRAY:
2235 alignment = pFormat[1] + 1;
2236 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2237 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2239 esize = ComplexStructSize(pStubMsg, pFormat);
2240 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2242 assert( fUnmarshall );
2244 if (!fMustAlloc && !*ppMemory)
2245 fMustAlloc = TRUE;
2246 if (fMustAlloc)
2247 *ppMemory = NdrAllocate(pStubMsg, memsize);
2249 align_pointer(&pStubMsg->Buffer, alignment);
2250 saved_buffer = pStubMsg->Buffer;
2252 pMemory = *ppMemory;
2253 count = pStubMsg->ActualCount;
2254 for (i = 0; i < count; i++)
2255 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2256 return pStubMsg->Buffer - saved_buffer;
2258 default:
2259 ERR("unknown array format 0x%x\n", fc);
2260 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2264 static inline void array_memory_size(
2265 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2266 unsigned char fHasPointers)
2268 ULONG i, count, SavedMemorySize;
2269 ULONG bufsize, memsize;
2270 DWORD esize;
2271 unsigned char alignment;
2273 switch (fc)
2275 case RPC_FC_CARRAY:
2276 esize = *(const WORD*)(pFormat+2);
2277 alignment = pFormat[1] + 1;
2279 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2281 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2282 pStubMsg->MemorySize += memsize;
2284 align_pointer(&pStubMsg->Buffer, alignment);
2285 if (fHasPointers)
2286 pStubMsg->BufferMark = pStubMsg->Buffer;
2287 safe_buffer_increment(pStubMsg, bufsize);
2289 if (fHasPointers)
2290 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2291 break;
2292 case RPC_FC_CVARRAY:
2293 esize = *(const WORD*)(pFormat+2);
2294 alignment = pFormat[1] + 1;
2296 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2298 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2300 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2301 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2302 pStubMsg->MemorySize += memsize;
2304 align_pointer(&pStubMsg->Buffer, alignment);
2305 if (fHasPointers)
2306 pStubMsg->BufferMark = pStubMsg->Buffer;
2307 safe_buffer_increment(pStubMsg, bufsize);
2309 if (fHasPointers)
2310 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2311 break;
2312 case RPC_FC_C_CSTRING:
2313 case RPC_FC_C_WSTRING:
2314 if (fc == RPC_FC_C_CSTRING)
2315 esize = 1;
2316 else
2317 esize = 2;
2319 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2321 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2323 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2324 pStubMsg->ActualCount, pStubMsg->MaxCount);
2325 RpcRaiseException(RPC_S_INVALID_BOUND);
2327 if (pStubMsg->Offset)
2329 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2330 RpcRaiseException(RPC_S_INVALID_BOUND);
2333 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2334 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2336 validate_string_data(pStubMsg, bufsize, esize);
2338 safe_buffer_increment(pStubMsg, bufsize);
2339 pStubMsg->MemorySize += memsize;
2340 break;
2341 case RPC_FC_BOGUS_ARRAY:
2342 alignment = pFormat[1] + 1;
2343 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2344 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2346 align_pointer(&pStubMsg->Buffer, alignment);
2348 SavedMemorySize = pStubMsg->MemorySize;
2350 esize = ComplexStructSize(pStubMsg, pFormat);
2351 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2353 count = pStubMsg->ActualCount;
2354 for (i = 0; i < count; i++)
2355 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2357 pStubMsg->MemorySize = SavedMemorySize + memsize;
2358 break;
2359 default:
2360 ERR("unknown array format 0x%x\n", fc);
2361 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2365 static inline void array_free(
2366 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2367 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2369 DWORD i, count;
2371 switch (fc)
2373 case RPC_FC_CARRAY:
2374 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2375 if (fHasPointers)
2376 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2377 break;
2378 case RPC_FC_CVARRAY:
2379 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2380 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2381 if (fHasPointers)
2382 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2383 break;
2384 case RPC_FC_C_CSTRING:
2385 case RPC_FC_C_WSTRING:
2386 /* No embedded pointers so nothing to do */
2387 break;
2388 case RPC_FC_BOGUS_ARRAY:
2389 count = *(const WORD *)(pFormat + 2);
2390 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2391 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2393 count = pStubMsg->ActualCount;
2394 for (i = 0; i < count; i++)
2395 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2396 break;
2397 default:
2398 ERR("unknown array format 0x%x\n", fc);
2399 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2404 * NdrConformantString:
2406 * What MS calls a ConformantString is, in DCE terminology,
2407 * a Varying-Conformant String.
2409 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2410 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2411 * into unmarshalled string)
2412 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2414 * data: CHARTYPE[maxlen]
2416 * ], where CHARTYPE is the appropriate character type (specified externally)
2420 /***********************************************************************
2421 * NdrConformantStringMarshall [RPCRT4.@]
2423 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2424 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2426 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2428 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2429 ERR("Unhandled string type: %#x\n", pFormat[0]);
2430 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2433 /* allow compiler to optimise inline function by passing constant into
2434 * these functions */
2435 if (pFormat[0] == RPC_FC_C_CSTRING) {
2436 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2437 pFormat);
2438 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2439 pFormat, TRUE /* fHasPointers */);
2440 } else {
2441 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2442 pFormat);
2443 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2444 pFormat, TRUE /* fHasPointers */);
2447 return NULL;
2450 /***********************************************************************
2451 * NdrConformantStringBufferSize [RPCRT4.@]
2453 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2454 unsigned char* pMemory, PFORMAT_STRING pFormat)
2456 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2458 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2459 ERR("Unhandled string type: %#x\n", pFormat[0]);
2460 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2463 /* allow compiler to optimise inline function by passing constant into
2464 * these functions */
2465 if (pFormat[0] == RPC_FC_C_CSTRING) {
2466 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2467 pFormat);
2468 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2469 TRUE /* fHasPointers */);
2470 } else {
2471 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2472 pFormat);
2473 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2474 TRUE /* fHasPointers */);
2478 /************************************************************************
2479 * NdrConformantStringMemorySize [RPCRT4.@]
2481 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2482 PFORMAT_STRING pFormat )
2484 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2486 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2487 ERR("Unhandled string type: %#x\n", pFormat[0]);
2488 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2491 /* allow compiler to optimise inline function by passing constant into
2492 * these functions */
2493 if (pFormat[0] == RPC_FC_C_CSTRING) {
2494 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2495 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2496 TRUE /* fHasPointers */);
2497 } else {
2498 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2499 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2500 TRUE /* fHasPointers */);
2503 return pStubMsg->MemorySize;
2506 /************************************************************************
2507 * NdrConformantStringUnmarshall [RPCRT4.@]
2509 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2510 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2512 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2513 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2515 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2516 ERR("Unhandled string type: %#x\n", *pFormat);
2517 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2520 /* allow compiler to optimise inline function by passing constant into
2521 * these functions */
2522 if (pFormat[0] == RPC_FC_C_CSTRING) {
2523 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2524 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2525 pFormat, fMustAlloc,
2526 TRUE /* fUseBufferMemoryServer */,
2527 TRUE /* fUnmarshall */);
2528 } else {
2529 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2530 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2531 pFormat, fMustAlloc,
2532 TRUE /* fUseBufferMemoryServer */,
2533 TRUE /* fUnmarshall */);
2536 return NULL;
2539 /***********************************************************************
2540 * NdrNonConformantStringMarshall [RPCRT4.@]
2542 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2543 unsigned char *pMemory,
2544 PFORMAT_STRING pFormat)
2546 ULONG esize, size, maxsize;
2548 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2550 maxsize = *(const USHORT *)&pFormat[2];
2552 if (*pFormat == RPC_FC_CSTRING)
2554 ULONG i = 0;
2555 const char *str = (const char *)pMemory;
2556 while (i < maxsize && str[i]) i++;
2557 TRACE("string=%s\n", debugstr_an(str, i));
2558 pStubMsg->ActualCount = i + 1;
2559 esize = 1;
2561 else if (*pFormat == RPC_FC_WSTRING)
2563 ULONG i = 0;
2564 const WCHAR *str = (const WCHAR *)pMemory;
2565 while (i < maxsize && str[i]) i++;
2566 TRACE("string=%s\n", debugstr_wn(str, i));
2567 pStubMsg->ActualCount = i + 1;
2568 esize = 2;
2570 else
2572 ERR("Unhandled string type: %#x\n", *pFormat);
2573 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2576 pStubMsg->Offset = 0;
2577 WriteVariance(pStubMsg);
2579 size = safe_multiply(esize, pStubMsg->ActualCount);
2580 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2582 return NULL;
2585 /***********************************************************************
2586 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2588 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2589 unsigned char **ppMemory,
2590 PFORMAT_STRING pFormat,
2591 unsigned char fMustAlloc)
2593 ULONG bufsize, memsize, esize, maxsize;
2595 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2596 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2598 maxsize = *(const USHORT *)&pFormat[2];
2600 ReadVariance(pStubMsg, NULL, maxsize);
2601 if (pStubMsg->Offset)
2603 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2604 RpcRaiseException(RPC_S_INVALID_BOUND);
2607 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2608 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2609 else
2611 ERR("Unhandled string type: %#x\n", *pFormat);
2612 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2615 memsize = esize * maxsize;
2616 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2618 validate_string_data(pStubMsg, bufsize, esize);
2620 if (!fMustAlloc && !*ppMemory)
2621 fMustAlloc = TRUE;
2622 if (fMustAlloc)
2623 *ppMemory = NdrAllocate(pStubMsg, memsize);
2625 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2627 if (*pFormat == RPC_FC_CSTRING) {
2628 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2630 else if (*pFormat == RPC_FC_WSTRING) {
2631 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2634 return NULL;
2637 /***********************************************************************
2638 * NdrNonConformantStringBufferSize [RPCRT4.@]
2640 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2641 unsigned char *pMemory,
2642 PFORMAT_STRING pFormat)
2644 ULONG esize, maxsize;
2646 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2648 maxsize = *(const USHORT *)&pFormat[2];
2650 SizeVariance(pStubMsg);
2652 if (*pFormat == RPC_FC_CSTRING)
2654 ULONG i = 0;
2655 const char *str = (const char *)pMemory;
2656 while (i < maxsize && str[i]) i++;
2657 TRACE("string=%s\n", debugstr_an(str, i));
2658 pStubMsg->ActualCount = i + 1;
2659 esize = 1;
2661 else if (*pFormat == RPC_FC_WSTRING)
2663 ULONG i = 0;
2664 const WCHAR *str = (const WCHAR *)pMemory;
2665 while (i < maxsize && str[i]) i++;
2666 TRACE("string=%s\n", debugstr_wn(str, i));
2667 pStubMsg->ActualCount = i + 1;
2668 esize = 2;
2670 else
2672 ERR("Unhandled string type: %#x\n", *pFormat);
2673 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2676 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2679 /***********************************************************************
2680 * NdrNonConformantStringMemorySize [RPCRT4.@]
2682 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2683 PFORMAT_STRING pFormat)
2685 ULONG bufsize, memsize, esize, maxsize;
2687 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2689 maxsize = *(const USHORT *)&pFormat[2];
2691 ReadVariance(pStubMsg, NULL, maxsize);
2693 if (pStubMsg->Offset)
2695 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2696 RpcRaiseException(RPC_S_INVALID_BOUND);
2699 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2700 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2701 else
2703 ERR("Unhandled string type: %#x\n", *pFormat);
2704 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2707 memsize = esize * maxsize;
2708 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2710 validate_string_data(pStubMsg, bufsize, esize);
2712 safe_buffer_increment(pStubMsg, bufsize);
2713 pStubMsg->MemorySize += memsize;
2715 return pStubMsg->MemorySize;
2718 /* Complex types */
2720 #include "pshpack1.h"
2721 typedef struct
2723 unsigned char type;
2724 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2725 ULONG low_value;
2726 ULONG high_value;
2727 } NDR_RANGE;
2728 #include "poppack.h"
2730 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2731 PFORMAT_STRING pFormat)
2733 switch (*pFormat) {
2734 case RPC_FC_STRUCT:
2735 case RPC_FC_PSTRUCT:
2736 case RPC_FC_CSTRUCT:
2737 case RPC_FC_BOGUS_STRUCT:
2738 case RPC_FC_SMFARRAY:
2739 case RPC_FC_SMVARRAY:
2740 case RPC_FC_CSTRING:
2741 return *(const WORD*)&pFormat[2];
2742 case RPC_FC_USER_MARSHAL:
2743 return *(const WORD*)&pFormat[4];
2744 case RPC_FC_RANGE: {
2745 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2746 case RPC_FC_BYTE:
2747 case RPC_FC_CHAR:
2748 case RPC_FC_SMALL:
2749 case RPC_FC_USMALL:
2750 return sizeof(UCHAR);
2751 case RPC_FC_WCHAR:
2752 case RPC_FC_SHORT:
2753 case RPC_FC_USHORT:
2754 return sizeof(USHORT);
2755 case RPC_FC_LONG:
2756 case RPC_FC_ULONG:
2757 case RPC_FC_ENUM32:
2758 case RPC_FC_INT3264:
2759 case RPC_FC_UINT3264:
2760 return sizeof(ULONG);
2761 case RPC_FC_FLOAT:
2762 return sizeof(float);
2763 case RPC_FC_DOUBLE:
2764 return sizeof(double);
2765 case RPC_FC_HYPER:
2766 return sizeof(ULONGLONG);
2767 case RPC_FC_ENUM16:
2768 return sizeof(UINT);
2769 default:
2770 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2771 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2774 case RPC_FC_NON_ENCAPSULATED_UNION:
2775 pFormat += 2;
2776 if (pStubMsg->fHasNewCorrDesc)
2777 pFormat += 6;
2778 else
2779 pFormat += 4;
2781 pFormat += *(const SHORT*)pFormat;
2782 return *(const SHORT*)pFormat;
2783 case RPC_FC_IP:
2784 return sizeof(void *);
2785 case RPC_FC_WSTRING:
2786 return *(const WORD*)&pFormat[2] * 2;
2787 default:
2788 FIXME("unhandled embedded type %02x\n", *pFormat);
2790 return 0;
2794 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2795 PFORMAT_STRING pFormat)
2797 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2799 if (!m)
2801 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2802 return 0;
2805 return m(pStubMsg, pFormat);
2809 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2810 unsigned char *pMemory,
2811 PFORMAT_STRING pFormat,
2812 PFORMAT_STRING pPointer)
2814 PFORMAT_STRING desc;
2815 NDR_MARSHALL m;
2816 ULONG size;
2818 while (*pFormat != RPC_FC_END) {
2819 switch (*pFormat) {
2820 case RPC_FC_BYTE:
2821 case RPC_FC_CHAR:
2822 case RPC_FC_SMALL:
2823 case RPC_FC_USMALL:
2824 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2825 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2826 pMemory += 1;
2827 break;
2828 case RPC_FC_WCHAR:
2829 case RPC_FC_SHORT:
2830 case RPC_FC_USHORT:
2831 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2832 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2833 pMemory += 2;
2834 break;
2835 case RPC_FC_ENUM16:
2837 USHORT val = *(DWORD *)pMemory;
2838 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2839 if (32767 < *(DWORD*)pMemory)
2840 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2841 safe_copy_to_buffer(pStubMsg, &val, 2);
2842 pMemory += 4;
2843 break;
2845 case RPC_FC_LONG:
2846 case RPC_FC_ULONG:
2847 case RPC_FC_ENUM32:
2848 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2849 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2850 pMemory += 4;
2851 break;
2852 case RPC_FC_INT3264:
2853 case RPC_FC_UINT3264:
2855 UINT val = *(UINT_PTR *)pMemory;
2856 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2857 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2858 pMemory += sizeof(UINT_PTR);
2859 break;
2861 case RPC_FC_FLOAT:
2862 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2863 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2864 pMemory += sizeof(float);
2865 break;
2866 case RPC_FC_HYPER:
2867 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2868 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2869 pMemory += 8;
2870 break;
2871 case RPC_FC_DOUBLE:
2872 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2873 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2874 pMemory += sizeof(double);
2875 break;
2876 case RPC_FC_RP:
2877 case RPC_FC_UP:
2878 case RPC_FC_OP:
2879 case RPC_FC_FP:
2880 case RPC_FC_POINTER:
2882 unsigned char *saved_buffer;
2883 int pointer_buffer_mark_set = 0;
2884 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2885 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2886 if (*pFormat != RPC_FC_POINTER)
2887 pPointer = pFormat;
2888 if (*pPointer != RPC_FC_RP)
2889 align_pointer_clear(&pStubMsg->Buffer, 4);
2890 saved_buffer = pStubMsg->Buffer;
2891 if (pStubMsg->PointerBufferMark)
2893 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2894 pStubMsg->PointerBufferMark = NULL;
2895 pointer_buffer_mark_set = 1;
2897 else if (*pPointer != RPC_FC_RP)
2898 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2899 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2900 if (pointer_buffer_mark_set)
2902 STD_OVERFLOW_CHECK(pStubMsg);
2903 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2904 pStubMsg->Buffer = saved_buffer;
2905 if (*pPointer != RPC_FC_RP)
2906 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2908 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2909 if (*pFormat == RPC_FC_POINTER)
2910 pPointer += 4;
2911 else
2912 pFormat += 4;
2913 pMemory += sizeof(void *);
2914 break;
2916 case RPC_FC_ALIGNM2:
2917 align_pointer(&pMemory, 2);
2918 break;
2919 case RPC_FC_ALIGNM4:
2920 align_pointer(&pMemory, 4);
2921 break;
2922 case RPC_FC_ALIGNM8:
2923 align_pointer(&pMemory, 8);
2924 break;
2925 case RPC_FC_STRUCTPAD1:
2926 case RPC_FC_STRUCTPAD2:
2927 case RPC_FC_STRUCTPAD3:
2928 case RPC_FC_STRUCTPAD4:
2929 case RPC_FC_STRUCTPAD5:
2930 case RPC_FC_STRUCTPAD6:
2931 case RPC_FC_STRUCTPAD7:
2932 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2933 break;
2934 case RPC_FC_EMBEDDED_COMPLEX:
2935 pMemory += pFormat[1];
2936 pFormat += 2;
2937 desc = pFormat + *(const SHORT*)pFormat;
2938 size = EmbeddedComplexSize(pStubMsg, desc);
2939 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2940 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2941 if (m)
2943 /* for some reason interface pointers aren't generated as
2944 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2945 * they still need the derefencing treatment that pointers are
2946 * given */
2947 if (*desc == RPC_FC_IP)
2948 m(pStubMsg, *(unsigned char **)pMemory, desc);
2949 else
2950 m(pStubMsg, pMemory, desc);
2952 else FIXME("no marshaller for embedded type %02x\n", *desc);
2953 pMemory += size;
2954 pFormat += 2;
2955 continue;
2956 case RPC_FC_PAD:
2957 break;
2958 default:
2959 FIXME("unhandled format 0x%02x\n", *pFormat);
2961 pFormat++;
2964 return pMemory;
2967 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2968 unsigned char *pMemory,
2969 PFORMAT_STRING pFormat,
2970 PFORMAT_STRING pPointer,
2971 unsigned char fMustAlloc)
2973 PFORMAT_STRING desc;
2974 NDR_UNMARSHALL m;
2975 ULONG size;
2977 while (*pFormat != RPC_FC_END) {
2978 switch (*pFormat) {
2979 case RPC_FC_BYTE:
2980 case RPC_FC_CHAR:
2981 case RPC_FC_SMALL:
2982 case RPC_FC_USMALL:
2983 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2984 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2985 pMemory += 1;
2986 break;
2987 case RPC_FC_WCHAR:
2988 case RPC_FC_SHORT:
2989 case RPC_FC_USHORT:
2990 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2991 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2992 pMemory += 2;
2993 break;
2994 case RPC_FC_ENUM16:
2996 WORD val;
2997 safe_copy_from_buffer(pStubMsg, &val, 2);
2998 *(DWORD*)pMemory = val;
2999 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
3000 if (32767 < *(DWORD*)pMemory)
3001 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3002 pMemory += 4;
3003 break;
3005 case RPC_FC_LONG:
3006 case RPC_FC_ULONG:
3007 case RPC_FC_ENUM32:
3008 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3009 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3010 pMemory += 4;
3011 break;
3012 case RPC_FC_INT3264:
3014 INT val;
3015 safe_copy_from_buffer(pStubMsg, &val, 4);
3016 *(INT_PTR *)pMemory = val;
3017 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3018 pMemory += sizeof(INT_PTR);
3019 break;
3021 case RPC_FC_UINT3264:
3023 UINT val;
3024 safe_copy_from_buffer(pStubMsg, &val, 4);
3025 *(UINT_PTR *)pMemory = val;
3026 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3027 pMemory += sizeof(UINT_PTR);
3028 break;
3030 case RPC_FC_FLOAT:
3031 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3032 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3033 pMemory += sizeof(float);
3034 break;
3035 case RPC_FC_HYPER:
3036 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3037 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3038 pMemory += 8;
3039 break;
3040 case RPC_FC_DOUBLE:
3041 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3042 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3043 pMemory += sizeof(double);
3044 break;
3045 case RPC_FC_RP:
3046 case RPC_FC_UP:
3047 case RPC_FC_OP:
3048 case RPC_FC_FP:
3049 case RPC_FC_POINTER:
3051 unsigned char *saved_buffer;
3052 int pointer_buffer_mark_set = 0;
3053 TRACE("pointer => %p\n", pMemory);
3054 if (*pFormat != RPC_FC_POINTER)
3055 pPointer = pFormat;
3056 if (*pPointer != RPC_FC_RP)
3057 align_pointer(&pStubMsg->Buffer, 4);
3058 saved_buffer = pStubMsg->Buffer;
3059 if (pStubMsg->PointerBufferMark)
3061 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3062 pStubMsg->PointerBufferMark = NULL;
3063 pointer_buffer_mark_set = 1;
3065 else if (*pPointer != RPC_FC_RP)
3066 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3068 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3069 if (pointer_buffer_mark_set)
3071 STD_OVERFLOW_CHECK(pStubMsg);
3072 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3073 pStubMsg->Buffer = saved_buffer;
3074 if (*pPointer != RPC_FC_RP)
3075 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3077 if (*pFormat == RPC_FC_POINTER)
3078 pPointer += 4;
3079 else
3080 pFormat += 4;
3081 pMemory += sizeof(void *);
3082 break;
3084 case RPC_FC_ALIGNM2:
3085 align_pointer_clear(&pMemory, 2);
3086 break;
3087 case RPC_FC_ALIGNM4:
3088 align_pointer_clear(&pMemory, 4);
3089 break;
3090 case RPC_FC_ALIGNM8:
3091 align_pointer_clear(&pMemory, 8);
3092 break;
3093 case RPC_FC_STRUCTPAD1:
3094 case RPC_FC_STRUCTPAD2:
3095 case RPC_FC_STRUCTPAD3:
3096 case RPC_FC_STRUCTPAD4:
3097 case RPC_FC_STRUCTPAD5:
3098 case RPC_FC_STRUCTPAD6:
3099 case RPC_FC_STRUCTPAD7:
3100 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
3101 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3102 break;
3103 case RPC_FC_EMBEDDED_COMPLEX:
3104 pMemory += pFormat[1];
3105 pFormat += 2;
3106 desc = pFormat + *(const SHORT*)pFormat;
3107 size = EmbeddedComplexSize(pStubMsg, desc);
3108 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3109 if (fMustAlloc)
3110 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3111 * since the type is part of the memory block that is encompassed by
3112 * the whole complex type. Memory is forced to allocate when pointers
3113 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3114 * clearing the memory we pass in to the unmarshaller */
3115 memset(pMemory, 0, size);
3116 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3117 if (m)
3119 /* for some reason interface pointers aren't generated as
3120 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3121 * they still need the derefencing treatment that pointers are
3122 * given */
3123 if (*desc == RPC_FC_IP)
3124 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3125 else
3126 m(pStubMsg, &pMemory, desc, FALSE);
3128 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3129 pMemory += size;
3130 pFormat += 2;
3131 continue;
3132 case RPC_FC_PAD:
3133 break;
3134 default:
3135 FIXME("unhandled format %d\n", *pFormat);
3137 pFormat++;
3140 return pMemory;
3143 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3144 unsigned char *pMemory,
3145 PFORMAT_STRING pFormat,
3146 PFORMAT_STRING pPointer)
3148 PFORMAT_STRING desc;
3149 NDR_BUFFERSIZE m;
3150 ULONG size;
3152 while (*pFormat != RPC_FC_END) {
3153 switch (*pFormat) {
3154 case RPC_FC_BYTE:
3155 case RPC_FC_CHAR:
3156 case RPC_FC_SMALL:
3157 case RPC_FC_USMALL:
3158 safe_buffer_length_increment(pStubMsg, 1);
3159 pMemory += 1;
3160 break;
3161 case RPC_FC_WCHAR:
3162 case RPC_FC_SHORT:
3163 case RPC_FC_USHORT:
3164 safe_buffer_length_increment(pStubMsg, 2);
3165 pMemory += 2;
3166 break;
3167 case RPC_FC_ENUM16:
3168 safe_buffer_length_increment(pStubMsg, 2);
3169 pMemory += 4;
3170 break;
3171 case RPC_FC_LONG:
3172 case RPC_FC_ULONG:
3173 case RPC_FC_ENUM32:
3174 case RPC_FC_FLOAT:
3175 safe_buffer_length_increment(pStubMsg, 4);
3176 pMemory += 4;
3177 break;
3178 case RPC_FC_INT3264:
3179 case RPC_FC_UINT3264:
3180 safe_buffer_length_increment(pStubMsg, 4);
3181 pMemory += sizeof(INT_PTR);
3182 break;
3183 case RPC_FC_HYPER:
3184 case RPC_FC_DOUBLE:
3185 safe_buffer_length_increment(pStubMsg, 8);
3186 pMemory += 8;
3187 break;
3188 case RPC_FC_RP:
3189 case RPC_FC_UP:
3190 case RPC_FC_OP:
3191 case RPC_FC_FP:
3192 case RPC_FC_POINTER:
3193 if (*pFormat != RPC_FC_POINTER)
3194 pPointer = pFormat;
3195 if (!pStubMsg->IgnoreEmbeddedPointers)
3197 int saved_buffer_length = pStubMsg->BufferLength;
3198 pStubMsg->BufferLength = pStubMsg->PointerLength;
3199 pStubMsg->PointerLength = 0;
3200 if(!pStubMsg->BufferLength)
3201 ERR("BufferLength == 0??\n");
3202 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3203 pStubMsg->PointerLength = pStubMsg->BufferLength;
3204 pStubMsg->BufferLength = saved_buffer_length;
3206 if (*pPointer != RPC_FC_RP)
3208 align_length(&pStubMsg->BufferLength, 4);
3209 safe_buffer_length_increment(pStubMsg, 4);
3211 if (*pFormat == RPC_FC_POINTER)
3212 pPointer += 4;
3213 else
3214 pFormat += 4;
3215 pMemory += sizeof(void*);
3216 break;
3217 case RPC_FC_ALIGNM2:
3218 align_pointer(&pMemory, 2);
3219 break;
3220 case RPC_FC_ALIGNM4:
3221 align_pointer(&pMemory, 4);
3222 break;
3223 case RPC_FC_ALIGNM8:
3224 align_pointer(&pMemory, 8);
3225 break;
3226 case RPC_FC_STRUCTPAD1:
3227 case RPC_FC_STRUCTPAD2:
3228 case RPC_FC_STRUCTPAD3:
3229 case RPC_FC_STRUCTPAD4:
3230 case RPC_FC_STRUCTPAD5:
3231 case RPC_FC_STRUCTPAD6:
3232 case RPC_FC_STRUCTPAD7:
3233 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3234 break;
3235 case RPC_FC_EMBEDDED_COMPLEX:
3236 pMemory += pFormat[1];
3237 pFormat += 2;
3238 desc = pFormat + *(const SHORT*)pFormat;
3239 size = EmbeddedComplexSize(pStubMsg, desc);
3240 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3241 if (m)
3243 /* for some reason interface pointers aren't generated as
3244 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3245 * they still need the derefencing treatment that pointers are
3246 * given */
3247 if (*desc == RPC_FC_IP)
3248 m(pStubMsg, *(unsigned char **)pMemory, desc);
3249 else
3250 m(pStubMsg, pMemory, desc);
3252 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3253 pMemory += size;
3254 pFormat += 2;
3255 continue;
3256 case RPC_FC_PAD:
3257 break;
3258 default:
3259 FIXME("unhandled format 0x%02x\n", *pFormat);
3261 pFormat++;
3264 return pMemory;
3267 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3268 unsigned char *pMemory,
3269 PFORMAT_STRING pFormat,
3270 PFORMAT_STRING pPointer)
3272 PFORMAT_STRING desc;
3273 NDR_FREE m;
3274 ULONG size;
3276 while (*pFormat != RPC_FC_END) {
3277 switch (*pFormat) {
3278 case RPC_FC_BYTE:
3279 case RPC_FC_CHAR:
3280 case RPC_FC_SMALL:
3281 case RPC_FC_USMALL:
3282 pMemory += 1;
3283 break;
3284 case RPC_FC_WCHAR:
3285 case RPC_FC_SHORT:
3286 case RPC_FC_USHORT:
3287 pMemory += 2;
3288 break;
3289 case RPC_FC_LONG:
3290 case RPC_FC_ULONG:
3291 case RPC_FC_ENUM16:
3292 case RPC_FC_ENUM32:
3293 case RPC_FC_FLOAT:
3294 pMemory += 4;
3295 break;
3296 case RPC_FC_INT3264:
3297 case RPC_FC_UINT3264:
3298 pMemory += sizeof(INT_PTR);
3299 break;
3300 case RPC_FC_HYPER:
3301 case RPC_FC_DOUBLE:
3302 pMemory += 8;
3303 break;
3304 case RPC_FC_RP:
3305 case RPC_FC_UP:
3306 case RPC_FC_OP:
3307 case RPC_FC_FP:
3308 case RPC_FC_POINTER:
3309 if (*pFormat != RPC_FC_POINTER)
3310 pPointer = pFormat;
3311 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3312 if (*pFormat == RPC_FC_POINTER)
3313 pPointer += 4;
3314 else
3315 pFormat += 4;
3316 pMemory += sizeof(void *);
3317 break;
3318 case RPC_FC_ALIGNM2:
3319 align_pointer(&pMemory, 2);
3320 break;
3321 case RPC_FC_ALIGNM4:
3322 align_pointer(&pMemory, 4);
3323 break;
3324 case RPC_FC_ALIGNM8:
3325 align_pointer(&pMemory, 8);
3326 break;
3327 case RPC_FC_STRUCTPAD1:
3328 case RPC_FC_STRUCTPAD2:
3329 case RPC_FC_STRUCTPAD3:
3330 case RPC_FC_STRUCTPAD4:
3331 case RPC_FC_STRUCTPAD5:
3332 case RPC_FC_STRUCTPAD6:
3333 case RPC_FC_STRUCTPAD7:
3334 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3335 break;
3336 case RPC_FC_EMBEDDED_COMPLEX:
3337 pMemory += pFormat[1];
3338 pFormat += 2;
3339 desc = pFormat + *(const SHORT*)pFormat;
3340 size = EmbeddedComplexSize(pStubMsg, desc);
3341 m = NdrFreer[*desc & NDR_TABLE_MASK];
3342 if (m)
3344 /* for some reason interface pointers aren't generated as
3345 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3346 * they still need the derefencing treatment that pointers are
3347 * given */
3348 if (*desc == RPC_FC_IP)
3349 m(pStubMsg, *(unsigned char **)pMemory, desc);
3350 else
3351 m(pStubMsg, pMemory, desc);
3353 pMemory += size;
3354 pFormat += 2;
3355 continue;
3356 case RPC_FC_PAD:
3357 break;
3358 default:
3359 FIXME("unhandled format 0x%02x\n", *pFormat);
3361 pFormat++;
3364 return pMemory;
3367 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3368 PFORMAT_STRING pFormat,
3369 PFORMAT_STRING pPointer)
3371 PFORMAT_STRING desc;
3372 ULONG size = 0;
3374 while (*pFormat != RPC_FC_END) {
3375 switch (*pFormat) {
3376 case RPC_FC_BYTE:
3377 case RPC_FC_CHAR:
3378 case RPC_FC_SMALL:
3379 case RPC_FC_USMALL:
3380 size += 1;
3381 safe_buffer_increment(pStubMsg, 1);
3382 break;
3383 case RPC_FC_WCHAR:
3384 case RPC_FC_SHORT:
3385 case RPC_FC_USHORT:
3386 size += 2;
3387 safe_buffer_increment(pStubMsg, 2);
3388 break;
3389 case RPC_FC_ENUM16:
3390 size += 4;
3391 safe_buffer_increment(pStubMsg, 2);
3392 break;
3393 case RPC_FC_LONG:
3394 case RPC_FC_ULONG:
3395 case RPC_FC_ENUM32:
3396 case RPC_FC_FLOAT:
3397 size += 4;
3398 safe_buffer_increment(pStubMsg, 4);
3399 break;
3400 case RPC_FC_INT3264:
3401 case RPC_FC_UINT3264:
3402 size += sizeof(INT_PTR);
3403 safe_buffer_increment(pStubMsg, 4);
3404 break;
3405 case RPC_FC_HYPER:
3406 case RPC_FC_DOUBLE:
3407 size += 8;
3408 safe_buffer_increment(pStubMsg, 8);
3409 break;
3410 case RPC_FC_RP:
3411 case RPC_FC_UP:
3412 case RPC_FC_OP:
3413 case RPC_FC_FP:
3414 case RPC_FC_POINTER:
3416 unsigned char *saved_buffer;
3417 int pointer_buffer_mark_set = 0;
3418 if (*pFormat != RPC_FC_POINTER)
3419 pPointer = pFormat;
3420 if (*pPointer != RPC_FC_RP)
3421 align_pointer(&pStubMsg->Buffer, 4);
3422 saved_buffer = pStubMsg->Buffer;
3423 if (pStubMsg->PointerBufferMark)
3425 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3426 pStubMsg->PointerBufferMark = NULL;
3427 pointer_buffer_mark_set = 1;
3429 else if (*pPointer != RPC_FC_RP)
3430 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3432 if (!pStubMsg->IgnoreEmbeddedPointers)
3433 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3434 if (pointer_buffer_mark_set)
3436 STD_OVERFLOW_CHECK(pStubMsg);
3437 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3438 pStubMsg->Buffer = saved_buffer;
3439 if (*pPointer != RPC_FC_RP)
3440 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3442 if (*pFormat == RPC_FC_POINTER)
3443 pPointer += 4;
3444 else
3445 pFormat += 4;
3446 size += sizeof(void *);
3447 break;
3449 case RPC_FC_ALIGNM2:
3450 align_length(&size, 2);
3451 break;
3452 case RPC_FC_ALIGNM4:
3453 align_length(&size, 4);
3454 break;
3455 case RPC_FC_ALIGNM8:
3456 align_length(&size, 8);
3457 break;
3458 case RPC_FC_STRUCTPAD1:
3459 case RPC_FC_STRUCTPAD2:
3460 case RPC_FC_STRUCTPAD3:
3461 case RPC_FC_STRUCTPAD4:
3462 case RPC_FC_STRUCTPAD5:
3463 case RPC_FC_STRUCTPAD6:
3464 case RPC_FC_STRUCTPAD7:
3465 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3466 break;
3467 case RPC_FC_EMBEDDED_COMPLEX:
3468 size += pFormat[1];
3469 pFormat += 2;
3470 desc = pFormat + *(const SHORT*)pFormat;
3471 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3472 pFormat += 2;
3473 continue;
3474 case RPC_FC_PAD:
3475 break;
3476 default:
3477 FIXME("unhandled format 0x%02x\n", *pFormat);
3479 pFormat++;
3482 return size;
3485 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3487 PFORMAT_STRING desc;
3488 ULONG size = 0;
3490 while (*pFormat != RPC_FC_END) {
3491 switch (*pFormat) {
3492 case RPC_FC_BYTE:
3493 case RPC_FC_CHAR:
3494 case RPC_FC_SMALL:
3495 case RPC_FC_USMALL:
3496 size += 1;
3497 break;
3498 case RPC_FC_WCHAR:
3499 case RPC_FC_SHORT:
3500 case RPC_FC_USHORT:
3501 size += 2;
3502 break;
3503 case RPC_FC_LONG:
3504 case RPC_FC_ULONG:
3505 case RPC_FC_ENUM16:
3506 case RPC_FC_ENUM32:
3507 case RPC_FC_FLOAT:
3508 size += 4;
3509 break;
3510 case RPC_FC_INT3264:
3511 case RPC_FC_UINT3264:
3512 size += sizeof(INT_PTR);
3513 break;
3514 case RPC_FC_HYPER:
3515 case RPC_FC_DOUBLE:
3516 size += 8;
3517 break;
3518 case RPC_FC_RP:
3519 case RPC_FC_UP:
3520 case RPC_FC_OP:
3521 case RPC_FC_FP:
3522 case RPC_FC_POINTER:
3523 size += sizeof(void *);
3524 if (*pFormat != RPC_FC_POINTER)
3525 pFormat += 4;
3526 break;
3527 case RPC_FC_ALIGNM2:
3528 align_length(&size, 2);
3529 break;
3530 case RPC_FC_ALIGNM4:
3531 align_length(&size, 4);
3532 break;
3533 case RPC_FC_ALIGNM8:
3534 align_length(&size, 8);
3535 break;
3536 case RPC_FC_STRUCTPAD1:
3537 case RPC_FC_STRUCTPAD2:
3538 case RPC_FC_STRUCTPAD3:
3539 case RPC_FC_STRUCTPAD4:
3540 case RPC_FC_STRUCTPAD5:
3541 case RPC_FC_STRUCTPAD6:
3542 case RPC_FC_STRUCTPAD7:
3543 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3544 break;
3545 case RPC_FC_EMBEDDED_COMPLEX:
3546 size += pFormat[1];
3547 pFormat += 2;
3548 desc = pFormat + *(const SHORT*)pFormat;
3549 size += EmbeddedComplexSize(pStubMsg, desc);
3550 pFormat += 2;
3551 continue;
3552 case RPC_FC_PAD:
3553 break;
3554 default:
3555 FIXME("unhandled format 0x%02x\n", *pFormat);
3557 pFormat++;
3560 return size;
3563 /***********************************************************************
3564 * NdrComplexStructMarshall [RPCRT4.@]
3566 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3567 unsigned char *pMemory,
3568 PFORMAT_STRING pFormat)
3570 PFORMAT_STRING conf_array = NULL;
3571 PFORMAT_STRING pointer_desc = NULL;
3572 unsigned char *OldMemory = pStubMsg->Memory;
3573 int pointer_buffer_mark_set = 0;
3574 ULONG count = 0;
3575 ULONG max_count = 0;
3576 ULONG offset = 0;
3578 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3580 if (!pStubMsg->PointerBufferMark)
3582 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3583 /* save buffer length */
3584 ULONG saved_buffer_length = pStubMsg->BufferLength;
3586 /* get the buffer pointer after complex array data, but before
3587 * pointer data */
3588 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3589 pStubMsg->IgnoreEmbeddedPointers = 1;
3590 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3591 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3593 /* save it for use by embedded pointer code later */
3594 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3595 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3596 pointer_buffer_mark_set = 1;
3598 /* restore the original buffer length */
3599 pStubMsg->BufferLength = saved_buffer_length;
3602 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3604 pFormat += 4;
3605 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3606 pFormat += 2;
3607 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3608 pFormat += 2;
3610 pStubMsg->Memory = pMemory;
3612 if (conf_array)
3614 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3615 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3616 pMemory + struct_size, conf_array);
3617 /* these could be changed in ComplexMarshall so save them for later */
3618 max_count = pStubMsg->MaxCount;
3619 count = pStubMsg->ActualCount;
3620 offset = pStubMsg->Offset;
3623 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3625 if (conf_array)
3627 pStubMsg->MaxCount = max_count;
3628 pStubMsg->ActualCount = count;
3629 pStubMsg->Offset = offset;
3630 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3631 conf_array, TRUE /* fHasPointers */);
3634 pStubMsg->Memory = OldMemory;
3636 if (pointer_buffer_mark_set)
3638 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3639 pStubMsg->PointerBufferMark = NULL;
3642 STD_OVERFLOW_CHECK(pStubMsg);
3644 return NULL;
3647 /***********************************************************************
3648 * NdrComplexStructUnmarshall [RPCRT4.@]
3650 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3651 unsigned char **ppMemory,
3652 PFORMAT_STRING pFormat,
3653 unsigned char fMustAlloc)
3655 unsigned size = *(const WORD*)(pFormat+2);
3656 PFORMAT_STRING conf_array = NULL;
3657 PFORMAT_STRING pointer_desc = NULL;
3658 unsigned char *pMemory;
3659 int pointer_buffer_mark_set = 0;
3660 ULONG count = 0;
3661 ULONG max_count = 0;
3662 ULONG offset = 0;
3663 ULONG array_size = 0;
3665 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3667 if (!pStubMsg->PointerBufferMark)
3669 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3670 /* save buffer pointer */
3671 unsigned char *saved_buffer = pStubMsg->Buffer;
3673 /* get the buffer pointer after complex array data, but before
3674 * pointer data */
3675 pStubMsg->IgnoreEmbeddedPointers = 1;
3676 NdrComplexStructMemorySize(pStubMsg, pFormat);
3677 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3679 /* save it for use by embedded pointer code later */
3680 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3681 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3682 pointer_buffer_mark_set = 1;
3684 /* restore the original buffer */
3685 pStubMsg->Buffer = saved_buffer;
3688 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3690 pFormat += 4;
3691 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3692 pFormat += 2;
3693 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3694 pFormat += 2;
3696 if (conf_array)
3698 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3699 size += array_size;
3701 /* these could be changed in ComplexMarshall so save them for later */
3702 max_count = pStubMsg->MaxCount;
3703 count = pStubMsg->ActualCount;
3704 offset = pStubMsg->Offset;
3707 if (!fMustAlloc && !*ppMemory)
3708 fMustAlloc = TRUE;
3709 if (fMustAlloc)
3710 *ppMemory = NdrAllocate(pStubMsg, size);
3712 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3714 if (conf_array)
3716 pStubMsg->MaxCount = max_count;
3717 pStubMsg->ActualCount = count;
3718 pStubMsg->Offset = offset;
3719 if (fMustAlloc)
3720 memset(pMemory, 0, array_size);
3721 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3722 conf_array, FALSE,
3723 FALSE /* fUseBufferMemoryServer */,
3724 TRUE /* fUnmarshall */);
3727 if (pointer_buffer_mark_set)
3729 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3730 pStubMsg->PointerBufferMark = NULL;
3733 return NULL;
3736 /***********************************************************************
3737 * NdrComplexStructBufferSize [RPCRT4.@]
3739 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3740 unsigned char *pMemory,
3741 PFORMAT_STRING pFormat)
3743 PFORMAT_STRING conf_array = NULL;
3744 PFORMAT_STRING pointer_desc = NULL;
3745 unsigned char *OldMemory = pStubMsg->Memory;
3746 int pointer_length_set = 0;
3747 ULONG count = 0;
3748 ULONG max_count = 0;
3749 ULONG offset = 0;
3751 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3753 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3755 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3757 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3758 ULONG saved_buffer_length = pStubMsg->BufferLength;
3760 /* get the buffer length after complex struct data, but before
3761 * pointer data */
3762 pStubMsg->IgnoreEmbeddedPointers = 1;
3763 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3764 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3766 /* save it for use by embedded pointer code later */
3767 pStubMsg->PointerLength = pStubMsg->BufferLength;
3768 pointer_length_set = 1;
3769 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3771 /* restore the original buffer length */
3772 pStubMsg->BufferLength = saved_buffer_length;
3775 pFormat += 4;
3776 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3777 pFormat += 2;
3778 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3779 pFormat += 2;
3781 pStubMsg->Memory = pMemory;
3783 if (conf_array)
3785 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3786 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3787 conf_array);
3789 /* these could be changed in ComplexMarshall so save them for later */
3790 max_count = pStubMsg->MaxCount;
3791 count = pStubMsg->ActualCount;
3792 offset = pStubMsg->Offset;
3795 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3797 if (conf_array)
3799 pStubMsg->MaxCount = max_count;
3800 pStubMsg->ActualCount = count;
3801 pStubMsg->Offset = offset;
3802 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3803 TRUE /* fHasPointers */);
3806 pStubMsg->Memory = OldMemory;
3808 if(pointer_length_set)
3810 pStubMsg->BufferLength = pStubMsg->PointerLength;
3811 pStubMsg->PointerLength = 0;
3816 /***********************************************************************
3817 * NdrComplexStructMemorySize [RPCRT4.@]
3819 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3820 PFORMAT_STRING pFormat)
3822 unsigned size = *(const WORD*)(pFormat+2);
3823 PFORMAT_STRING conf_array = NULL;
3824 PFORMAT_STRING pointer_desc = NULL;
3825 ULONG count = 0;
3826 ULONG max_count = 0;
3827 ULONG offset = 0;
3829 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3831 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3833 pFormat += 4;
3834 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3835 pFormat += 2;
3836 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3837 pFormat += 2;
3839 if (conf_array)
3841 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3843 /* these could be changed in ComplexStructMemorySize so save them for
3844 * later */
3845 max_count = pStubMsg->MaxCount;
3846 count = pStubMsg->ActualCount;
3847 offset = pStubMsg->Offset;
3850 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3852 if (conf_array)
3854 pStubMsg->MaxCount = max_count;
3855 pStubMsg->ActualCount = count;
3856 pStubMsg->Offset = offset;
3857 array_memory_size(conf_array[0], pStubMsg, conf_array,
3858 TRUE /* fHasPointers */);
3861 return size;
3864 /***********************************************************************
3865 * NdrComplexStructFree [RPCRT4.@]
3867 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3868 unsigned char *pMemory,
3869 PFORMAT_STRING pFormat)
3871 PFORMAT_STRING conf_array = NULL;
3872 PFORMAT_STRING pointer_desc = NULL;
3873 unsigned char *OldMemory = pStubMsg->Memory;
3875 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3877 pFormat += 4;
3878 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3879 pFormat += 2;
3880 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3881 pFormat += 2;
3883 pStubMsg->Memory = pMemory;
3885 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3887 if (conf_array)
3888 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3889 TRUE /* fHasPointers */);
3891 pStubMsg->Memory = OldMemory;
3894 /***********************************************************************
3895 * NdrConformantArrayMarshall [RPCRT4.@]
3897 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3898 unsigned char *pMemory,
3899 PFORMAT_STRING pFormat)
3901 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3902 if (pFormat[0] != RPC_FC_CARRAY)
3904 ERR("invalid format = 0x%x\n", pFormat[0]);
3905 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3908 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3909 pFormat);
3910 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3911 TRUE /* fHasPointers */);
3913 return NULL;
3916 /***********************************************************************
3917 * NdrConformantArrayUnmarshall [RPCRT4.@]
3919 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3920 unsigned char **ppMemory,
3921 PFORMAT_STRING pFormat,
3922 unsigned char fMustAlloc)
3924 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3925 if (pFormat[0] != RPC_FC_CARRAY)
3927 ERR("invalid format = 0x%x\n", pFormat[0]);
3928 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3931 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3932 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3933 fMustAlloc,
3934 TRUE /* fUseBufferMemoryServer */,
3935 TRUE /* fUnmarshall */);
3937 return NULL;
3940 /***********************************************************************
3941 * NdrConformantArrayBufferSize [RPCRT4.@]
3943 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3944 unsigned char *pMemory,
3945 PFORMAT_STRING pFormat)
3947 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3948 if (pFormat[0] != RPC_FC_CARRAY)
3950 ERR("invalid format = 0x%x\n", pFormat[0]);
3951 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3954 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3955 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3956 TRUE /* fHasPointers */);
3959 /***********************************************************************
3960 * NdrConformantArrayMemorySize [RPCRT4.@]
3962 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3963 PFORMAT_STRING pFormat)
3965 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3966 if (pFormat[0] != RPC_FC_CARRAY)
3968 ERR("invalid format = 0x%x\n", pFormat[0]);
3969 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3972 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3973 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3975 return pStubMsg->MemorySize;
3978 /***********************************************************************
3979 * NdrConformantArrayFree [RPCRT4.@]
3981 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3982 unsigned char *pMemory,
3983 PFORMAT_STRING pFormat)
3985 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3986 if (pFormat[0] != RPC_FC_CARRAY)
3988 ERR("invalid format = 0x%x\n", pFormat[0]);
3989 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3992 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3993 TRUE /* fHasPointers */);
3997 /***********************************************************************
3998 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4000 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
4001 unsigned char* pMemory,
4002 PFORMAT_STRING pFormat )
4004 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4006 if (pFormat[0] != RPC_FC_CVARRAY)
4008 ERR("invalid format type %x\n", pFormat[0]);
4009 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4010 return NULL;
4013 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4014 pFormat);
4015 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
4016 pFormat, TRUE /* fHasPointers */);
4018 return NULL;
4022 /***********************************************************************
4023 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4025 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4026 unsigned char** ppMemory,
4027 PFORMAT_STRING pFormat,
4028 unsigned char fMustAlloc )
4030 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4032 if (pFormat[0] != RPC_FC_CVARRAY)
4034 ERR("invalid format type %x\n", pFormat[0]);
4035 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4036 return NULL;
4039 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4040 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
4041 pFormat, fMustAlloc,
4042 TRUE /* fUseBufferMemoryServer */,
4043 TRUE /* fUnmarshall */);
4045 return NULL;
4049 /***********************************************************************
4050 * NdrConformantVaryingArrayFree [RPCRT4.@]
4052 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4053 unsigned char* pMemory,
4054 PFORMAT_STRING pFormat )
4056 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4058 if (pFormat[0] != RPC_FC_CVARRAY)
4060 ERR("invalid format type %x\n", pFormat[0]);
4061 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4062 return;
4065 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4066 TRUE /* fHasPointers */);
4070 /***********************************************************************
4071 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4073 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4074 unsigned char* pMemory, PFORMAT_STRING pFormat )
4076 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4078 if (pFormat[0] != RPC_FC_CVARRAY)
4080 ERR("invalid format type %x\n", pFormat[0]);
4081 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4082 return;
4085 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4086 pFormat);
4087 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4088 TRUE /* fHasPointers */);
4092 /***********************************************************************
4093 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4095 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4096 PFORMAT_STRING pFormat )
4098 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4100 if (pFormat[0] != RPC_FC_CVARRAY)
4102 ERR("invalid format type %x\n", pFormat[0]);
4103 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4104 return pStubMsg->MemorySize;
4107 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4108 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
4109 TRUE /* fHasPointers */);
4111 return pStubMsg->MemorySize;
4115 /***********************************************************************
4116 * NdrComplexArrayMarshall [RPCRT4.@]
4118 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4119 unsigned char *pMemory,
4120 PFORMAT_STRING pFormat)
4122 int pointer_buffer_mark_set = 0;
4124 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4126 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4128 ERR("invalid format type %x\n", pFormat[0]);
4129 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4130 return NULL;
4133 if (!pStubMsg->PointerBufferMark)
4135 /* save buffer fields that may be changed by buffer sizer functions
4136 * and that may be needed later on */
4137 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4138 ULONG saved_buffer_length = pStubMsg->BufferLength;
4139 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4140 ULONG saved_offset = pStubMsg->Offset;
4141 ULONG saved_actual_count = pStubMsg->ActualCount;
4143 /* get the buffer pointer after complex array data, but before
4144 * pointer data */
4145 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4146 pStubMsg->IgnoreEmbeddedPointers = 1;
4147 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4148 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4150 /* save it for use by embedded pointer code later */
4151 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4152 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4153 pointer_buffer_mark_set = 1;
4155 /* restore fields */
4156 pStubMsg->ActualCount = saved_actual_count;
4157 pStubMsg->Offset = saved_offset;
4158 pStubMsg->MaxCount = saved_max_count;
4159 pStubMsg->BufferLength = saved_buffer_length;
4162 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4163 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg,
4164 pMemory, pFormat, TRUE /* fHasPointers */);
4166 STD_OVERFLOW_CHECK(pStubMsg);
4168 if (pointer_buffer_mark_set)
4170 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4171 pStubMsg->PointerBufferMark = NULL;
4174 return NULL;
4177 /***********************************************************************
4178 * NdrComplexArrayUnmarshall [RPCRT4.@]
4180 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4181 unsigned char **ppMemory,
4182 PFORMAT_STRING pFormat,
4183 unsigned char fMustAlloc)
4185 unsigned char *saved_buffer;
4186 int pointer_buffer_mark_set = 0;
4187 int saved_ignore_embedded;
4189 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4191 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4193 ERR("invalid format type %x\n", pFormat[0]);
4194 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4195 return NULL;
4198 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4199 /* save buffer pointer */
4200 saved_buffer = pStubMsg->Buffer;
4201 /* get the buffer pointer after complex array data, but before
4202 * pointer data */
4203 pStubMsg->IgnoreEmbeddedPointers = 1;
4204 pStubMsg->MemorySize = 0;
4205 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4206 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4208 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4209 if (!pStubMsg->PointerBufferMark)
4211 /* save it for use by embedded pointer code later */
4212 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4213 pointer_buffer_mark_set = 1;
4215 /* restore the original buffer */
4216 pStubMsg->Buffer = saved_buffer;
4218 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4219 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4220 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4222 if (pointer_buffer_mark_set)
4224 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4225 pStubMsg->PointerBufferMark = NULL;
4228 return NULL;
4231 /***********************************************************************
4232 * NdrComplexArrayBufferSize [RPCRT4.@]
4234 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4235 unsigned char *pMemory,
4236 PFORMAT_STRING pFormat)
4238 int pointer_length_set = 0;
4240 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4242 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4244 ERR("invalid format type %x\n", pFormat[0]);
4245 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4246 return;
4249 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4251 /* save buffer fields that may be changed by buffer sizer functions
4252 * and that may be needed later on */
4253 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4254 ULONG saved_buffer_length = pStubMsg->BufferLength;
4255 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4256 ULONG saved_offset = pStubMsg->Offset;
4257 ULONG saved_actual_count = pStubMsg->ActualCount;
4259 /* get the buffer pointer after complex array data, but before
4260 * pointer data */
4261 pStubMsg->IgnoreEmbeddedPointers = 1;
4262 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4263 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4265 /* save it for use by embedded pointer code later */
4266 pStubMsg->PointerLength = pStubMsg->BufferLength;
4267 pointer_length_set = 1;
4269 /* restore fields */
4270 pStubMsg->ActualCount = saved_actual_count;
4271 pStubMsg->Offset = saved_offset;
4272 pStubMsg->MaxCount = saved_max_count;
4273 pStubMsg->BufferLength = saved_buffer_length;
4276 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4277 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4279 if(pointer_length_set)
4281 pStubMsg->BufferLength = pStubMsg->PointerLength;
4282 pStubMsg->PointerLength = 0;
4286 /***********************************************************************
4287 * NdrComplexArrayMemorySize [RPCRT4.@]
4289 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4290 PFORMAT_STRING pFormat)
4292 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4294 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4296 ERR("invalid format type %x\n", pFormat[0]);
4297 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4298 return 0;
4301 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4302 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4303 return pStubMsg->MemorySize;
4306 /***********************************************************************
4307 * NdrComplexArrayFree [RPCRT4.@]
4309 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4310 unsigned char *pMemory,
4311 PFORMAT_STRING pFormat)
4313 ULONG i, count, def;
4315 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4317 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4319 ERR("invalid format type %x\n", pFormat[0]);
4320 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4321 return;
4324 def = *(const WORD*)&pFormat[2];
4325 pFormat += 4;
4327 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4328 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4330 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4331 TRACE("variance = %d\n", pStubMsg->ActualCount);
4333 count = pStubMsg->ActualCount;
4334 for (i = 0; i < count; i++)
4335 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4338 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4339 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4340 USER_MARSHAL_CB *umcb)
4342 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4343 pStubMsg->RpcMsg->DataRepresentation);
4344 umcb->pStubMsg = pStubMsg;
4345 umcb->pReserve = NULL;
4346 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4347 umcb->CBType = cbtype;
4348 umcb->pFormat = pFormat;
4349 umcb->pTypeFormat = NULL /* FIXME */;
4352 #define USER_MARSHAL_PTR_PREFIX \
4353 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4354 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4356 /***********************************************************************
4357 * NdrUserMarshalMarshall [RPCRT4.@]
4359 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4360 unsigned char *pMemory,
4361 PFORMAT_STRING pFormat)
4363 unsigned flags = pFormat[1];
4364 unsigned index = *(const WORD*)&pFormat[2];
4365 unsigned char *saved_buffer = NULL;
4366 USER_MARSHAL_CB umcb;
4368 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4369 TRACE("index=%d\n", index);
4371 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4373 if (flags & USER_MARSHAL_POINTER)
4375 align_pointer_clear(&pStubMsg->Buffer, 4);
4376 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4377 pStubMsg->Buffer += 4;
4378 if (pStubMsg->PointerBufferMark)
4380 saved_buffer = pStubMsg->Buffer;
4381 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4382 pStubMsg->PointerBufferMark = NULL;
4384 align_pointer_clear(&pStubMsg->Buffer, 8);
4386 else
4387 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4389 pStubMsg->Buffer =
4390 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4391 &umcb.Flags, pStubMsg->Buffer, pMemory);
4393 if (saved_buffer)
4395 STD_OVERFLOW_CHECK(pStubMsg);
4396 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4397 pStubMsg->Buffer = saved_buffer;
4400 STD_OVERFLOW_CHECK(pStubMsg);
4402 return NULL;
4405 /***********************************************************************
4406 * NdrUserMarshalUnmarshall [RPCRT4.@]
4408 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4409 unsigned char **ppMemory,
4410 PFORMAT_STRING pFormat,
4411 unsigned char fMustAlloc)
4413 unsigned flags = pFormat[1];
4414 unsigned index = *(const WORD*)&pFormat[2];
4415 DWORD memsize = *(const WORD*)&pFormat[4];
4416 unsigned char *saved_buffer = NULL;
4417 USER_MARSHAL_CB umcb;
4419 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4420 TRACE("index=%d\n", index);
4422 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4424 if (flags & USER_MARSHAL_POINTER)
4426 align_pointer(&pStubMsg->Buffer, 4);
4427 /* skip pointer prefix */
4428 pStubMsg->Buffer += 4;
4429 if (pStubMsg->PointerBufferMark)
4431 saved_buffer = pStubMsg->Buffer;
4432 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4433 pStubMsg->PointerBufferMark = NULL;
4435 align_pointer(&pStubMsg->Buffer, 8);
4437 else
4438 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4440 if (!fMustAlloc && !*ppMemory)
4441 fMustAlloc = TRUE;
4442 if (fMustAlloc)
4444 *ppMemory = NdrAllocate(pStubMsg, memsize);
4445 memset(*ppMemory, 0, memsize);
4448 pStubMsg->Buffer =
4449 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4450 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4452 if (saved_buffer)
4454 STD_OVERFLOW_CHECK(pStubMsg);
4455 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4456 pStubMsg->Buffer = saved_buffer;
4459 return NULL;
4462 /***********************************************************************
4463 * NdrUserMarshalBufferSize [RPCRT4.@]
4465 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4466 unsigned char *pMemory,
4467 PFORMAT_STRING pFormat)
4469 unsigned flags = pFormat[1];
4470 unsigned index = *(const WORD*)&pFormat[2];
4471 DWORD bufsize = *(const WORD*)&pFormat[6];
4472 USER_MARSHAL_CB umcb;
4473 ULONG saved_buffer_length = 0;
4475 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4476 TRACE("index=%d\n", index);
4478 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4480 if (flags & USER_MARSHAL_POINTER)
4482 align_length(&pStubMsg->BufferLength, 4);
4483 /* skip pointer prefix */
4484 safe_buffer_length_increment(pStubMsg, 4);
4485 if (pStubMsg->IgnoreEmbeddedPointers)
4486 return;
4487 if (pStubMsg->PointerLength)
4489 saved_buffer_length = pStubMsg->BufferLength;
4490 pStubMsg->BufferLength = pStubMsg->PointerLength;
4491 pStubMsg->PointerLength = 0;
4493 align_length(&pStubMsg->BufferLength, 8);
4495 else
4496 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4498 if (bufsize) {
4499 TRACE("size=%d\n", bufsize);
4500 safe_buffer_length_increment(pStubMsg, bufsize);
4502 else
4503 pStubMsg->BufferLength =
4504 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4505 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4507 if (saved_buffer_length)
4509 pStubMsg->PointerLength = pStubMsg->BufferLength;
4510 pStubMsg->BufferLength = saved_buffer_length;
4515 /***********************************************************************
4516 * NdrUserMarshalMemorySize [RPCRT4.@]
4518 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4519 PFORMAT_STRING pFormat)
4521 unsigned flags = pFormat[1];
4522 unsigned index = *(const WORD*)&pFormat[2];
4523 DWORD memsize = *(const WORD*)&pFormat[4];
4524 DWORD bufsize = *(const WORD*)&pFormat[6];
4526 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4527 TRACE("index=%d\n", index);
4529 pStubMsg->MemorySize += memsize;
4531 if (flags & USER_MARSHAL_POINTER)
4533 align_pointer(&pStubMsg->Buffer, 4);
4534 /* skip pointer prefix */
4535 pStubMsg->Buffer += 4;
4536 if (pStubMsg->IgnoreEmbeddedPointers)
4537 return pStubMsg->MemorySize;
4538 align_pointer(&pStubMsg->Buffer, 8);
4540 else
4541 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4543 if (!bufsize)
4544 FIXME("not implemented for varying buffer size\n");
4546 pStubMsg->Buffer += bufsize;
4548 return pStubMsg->MemorySize;
4551 /***********************************************************************
4552 * NdrUserMarshalFree [RPCRT4.@]
4554 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4555 unsigned char *pMemory,
4556 PFORMAT_STRING pFormat)
4558 /* unsigned flags = pFormat[1]; */
4559 unsigned index = *(const WORD*)&pFormat[2];
4560 USER_MARSHAL_CB umcb;
4562 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4563 TRACE("index=%d\n", index);
4565 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4567 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4568 &umcb.Flags, pMemory);
4571 /***********************************************************************
4572 * NdrGetUserMarshalInfo [RPCRT4.@]
4574 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4576 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4578 TRACE("(%p,%u,%p)\n", flags, level, umi);
4580 if (level != 1)
4581 return RPC_S_INVALID_ARG;
4583 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4584 umi->InformationLevel = level;
4586 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4587 return RPC_S_INVALID_ARG;
4589 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4590 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4591 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4593 switch (umcb->CBType)
4595 case USER_MARSHAL_CB_MARSHALL:
4596 case USER_MARSHAL_CB_UNMARSHALL:
4598 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4599 unsigned char *buffer_start = msg->Buffer;
4600 unsigned char *buffer_end =
4601 (unsigned char *)msg->Buffer + msg->BufferLength;
4603 if (umcb->pStubMsg->Buffer < buffer_start ||
4604 umcb->pStubMsg->Buffer > buffer_end)
4605 return ERROR_INVALID_USER_BUFFER;
4607 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4608 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4609 break;
4611 case USER_MARSHAL_CB_BUFFER_SIZE:
4612 case USER_MARSHAL_CB_FREE:
4613 break;
4614 default:
4615 WARN("unrecognised CBType %d\n", umcb->CBType);
4618 return RPC_S_OK;
4621 /***********************************************************************
4622 * NdrClearOutParameters [RPCRT4.@]
4624 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4625 PFORMAT_STRING pFormat,
4626 void *ArgAddr)
4628 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4631 /***********************************************************************
4632 * NdrConvert [RPCRT4.@]
4634 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4636 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4637 /* FIXME: since this stub doesn't do any converting, the proper behavior
4638 is to raise an exception */
4641 /***********************************************************************
4642 * NdrConvert2 [RPCRT4.@]
4644 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4646 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4647 pStubMsg, pFormat, NumberParams);
4648 /* FIXME: since this stub doesn't do any converting, the proper behavior
4649 is to raise an exception */
4652 #include "pshpack1.h"
4653 typedef struct _NDR_CSTRUCT_FORMAT
4655 unsigned char type;
4656 unsigned char alignment;
4657 unsigned short memory_size;
4658 short offset_to_array_description;
4659 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4660 #include "poppack.h"
4662 /***********************************************************************
4663 * NdrConformantStructMarshall [RPCRT4.@]
4665 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4666 unsigned char *pMemory,
4667 PFORMAT_STRING pFormat)
4669 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4670 PFORMAT_STRING pCArrayFormat;
4671 ULONG esize, bufsize;
4673 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4675 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4676 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4678 ERR("invalid format type %x\n", pCStructFormat->type);
4679 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4680 return NULL;
4683 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4684 pCStructFormat->offset_to_array_description;
4685 if (*pCArrayFormat != RPC_FC_CARRAY)
4687 ERR("invalid array format type %x\n", pCStructFormat->type);
4688 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4689 return NULL;
4691 esize = *(const WORD*)(pCArrayFormat+2);
4693 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4694 pCArrayFormat + 4, 0);
4696 WriteConformance(pStubMsg);
4698 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4700 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4702 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4703 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4705 ERR("integer overflow of memory_size %u with bufsize %u\n",
4706 pCStructFormat->memory_size, bufsize);
4707 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4709 /* copy constant sized part of struct */
4710 pStubMsg->BufferMark = pStubMsg->Buffer;
4711 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4713 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4714 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4716 return NULL;
4719 /***********************************************************************
4720 * NdrConformantStructUnmarshall [RPCRT4.@]
4722 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4723 unsigned char **ppMemory,
4724 PFORMAT_STRING pFormat,
4725 unsigned char fMustAlloc)
4727 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4728 PFORMAT_STRING pCArrayFormat;
4729 ULONG esize, bufsize;
4730 unsigned char *saved_buffer;
4732 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4734 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4735 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4737 ERR("invalid format type %x\n", pCStructFormat->type);
4738 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4739 return NULL;
4741 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4742 pCStructFormat->offset_to_array_description;
4743 if (*pCArrayFormat != RPC_FC_CARRAY)
4745 ERR("invalid array format type %x\n", pCStructFormat->type);
4746 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4747 return NULL;
4749 esize = *(const WORD*)(pCArrayFormat+2);
4751 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4753 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4755 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4757 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4758 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4760 ERR("integer overflow of memory_size %u with bufsize %u\n",
4761 pCStructFormat->memory_size, bufsize);
4762 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4765 if (fMustAlloc)
4767 SIZE_T size = pCStructFormat->memory_size + bufsize;
4768 *ppMemory = NdrAllocate(pStubMsg, size);
4770 else
4772 if (!pStubMsg->IsClient && !*ppMemory)
4773 /* for servers, we just point straight into the RPC buffer */
4774 *ppMemory = pStubMsg->Buffer;
4777 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4778 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4779 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4780 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4782 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4783 if (*ppMemory != saved_buffer)
4784 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4786 return NULL;
4789 /***********************************************************************
4790 * NdrConformantStructBufferSize [RPCRT4.@]
4792 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4793 unsigned char *pMemory,
4794 PFORMAT_STRING pFormat)
4796 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4797 PFORMAT_STRING pCArrayFormat;
4798 ULONG esize;
4800 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4802 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4803 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4805 ERR("invalid format type %x\n", pCStructFormat->type);
4806 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4807 return;
4809 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4810 pCStructFormat->offset_to_array_description;
4811 if (*pCArrayFormat != RPC_FC_CARRAY)
4813 ERR("invalid array format type %x\n", pCStructFormat->type);
4814 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4815 return;
4817 esize = *(const WORD*)(pCArrayFormat+2);
4819 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4820 SizeConformance(pStubMsg);
4822 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4824 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4826 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4827 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4829 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4830 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4833 /***********************************************************************
4834 * NdrConformantStructMemorySize [RPCRT4.@]
4836 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4837 PFORMAT_STRING pFormat)
4839 FIXME("stub\n");
4840 return 0;
4843 /***********************************************************************
4844 * NdrConformantStructFree [RPCRT4.@]
4846 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4847 unsigned char *pMemory,
4848 PFORMAT_STRING pFormat)
4850 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4851 PFORMAT_STRING pCArrayFormat;
4853 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4855 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4856 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4858 ERR("invalid format type %x\n", pCStructFormat->type);
4859 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4860 return;
4863 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4864 pCStructFormat->offset_to_array_description;
4865 if (*pCArrayFormat != RPC_FC_CARRAY)
4867 ERR("invalid array format type %x\n", pCStructFormat->type);
4868 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4869 return;
4872 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4873 pCArrayFormat + 4, 0);
4875 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4877 /* copy constant sized part of struct */
4878 pStubMsg->BufferMark = pStubMsg->Buffer;
4880 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4881 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4884 /***********************************************************************
4885 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4887 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4888 unsigned char *pMemory,
4889 PFORMAT_STRING pFormat)
4891 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4892 PFORMAT_STRING pCVArrayFormat;
4894 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4896 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4897 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4899 ERR("invalid format type %x\n", pCVStructFormat->type);
4900 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4901 return NULL;
4904 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4905 pCVStructFormat->offset_to_array_description;
4907 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4908 pMemory + pCVStructFormat->memory_size,
4909 pCVArrayFormat);
4911 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4913 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4915 /* write constant sized part */
4916 pStubMsg->BufferMark = pStubMsg->Buffer;
4917 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4919 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4920 pMemory + pCVStructFormat->memory_size,
4921 pCVArrayFormat, FALSE /* fHasPointers */);
4923 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4925 return NULL;
4928 /***********************************************************************
4929 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4931 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4932 unsigned char **ppMemory,
4933 PFORMAT_STRING pFormat,
4934 unsigned char fMustAlloc)
4936 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4937 PFORMAT_STRING pCVArrayFormat;
4938 ULONG memsize, bufsize;
4939 unsigned char *saved_buffer, *saved_array_buffer;
4940 ULONG offset;
4941 unsigned char *array_memory;
4943 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4945 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4946 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4948 ERR("invalid format type %x\n", pCVStructFormat->type);
4949 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4950 return NULL;
4953 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4954 pCVStructFormat->offset_to_array_description;
4956 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4957 pCVArrayFormat);
4959 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4961 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4963 /* work out how much memory to allocate if we need to do so */
4964 if (!fMustAlloc && !*ppMemory)
4965 fMustAlloc = TRUE;
4966 if (fMustAlloc)
4968 SIZE_T size = pCVStructFormat->memory_size + memsize;
4969 *ppMemory = NdrAllocate(pStubMsg, size);
4972 /* mark the start of the constant data */
4973 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4974 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4976 array_memory = *ppMemory + pCVStructFormat->memory_size;
4977 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4978 &array_memory, pCVArrayFormat,
4979 FALSE /* fMustAlloc */,
4980 FALSE /* fUseServerBufferMemory */,
4981 FALSE /* fUnmarshall */);
4983 /* save offset in case unmarshalling pointers changes it */
4984 offset = pStubMsg->Offset;
4986 /* mark the start of the array data */
4987 saved_array_buffer = pStubMsg->Buffer;
4988 safe_buffer_increment(pStubMsg, bufsize);
4990 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4992 /* copy the constant data */
4993 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4994 /* copy the array data */
4995 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4996 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4997 saved_array_buffer, bufsize);
4999 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
5000 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5001 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
5002 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5004 return NULL;
5007 /***********************************************************************
5008 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5010 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5011 unsigned char *pMemory,
5012 PFORMAT_STRING pFormat)
5014 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5015 PFORMAT_STRING pCVArrayFormat;
5017 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5019 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5020 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5022 ERR("invalid format type %x\n", pCVStructFormat->type);
5023 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5024 return;
5027 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5028 pCVStructFormat->offset_to_array_description;
5029 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5030 pMemory + pCVStructFormat->memory_size,
5031 pCVArrayFormat);
5033 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5035 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5037 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5039 array_buffer_size(*pCVArrayFormat, pStubMsg,
5040 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5041 FALSE /* fHasPointers */);
5043 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5046 /***********************************************************************
5047 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5049 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5050 PFORMAT_STRING pFormat)
5052 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5053 PFORMAT_STRING pCVArrayFormat;
5055 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5057 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5058 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5060 ERR("invalid format type %x\n", pCVStructFormat->type);
5061 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5062 return 0;
5065 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5066 pCVStructFormat->offset_to_array_description;
5067 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5069 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5071 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5073 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5074 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5075 FALSE /* fHasPointers */);
5077 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5079 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5081 return pStubMsg->MemorySize;
5084 /***********************************************************************
5085 * NdrConformantVaryingStructFree [RPCRT4.@]
5087 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5088 unsigned char *pMemory,
5089 PFORMAT_STRING pFormat)
5091 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5092 PFORMAT_STRING pCVArrayFormat;
5094 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5096 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5097 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5099 ERR("invalid format type %x\n", pCVStructFormat->type);
5100 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5101 return;
5104 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5105 pCVStructFormat->offset_to_array_description;
5106 array_free(*pCVArrayFormat, pStubMsg,
5107 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5108 FALSE /* fHasPointers */);
5110 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5112 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5115 #include "pshpack1.h"
5116 typedef struct
5118 unsigned char type;
5119 unsigned char alignment;
5120 unsigned short total_size;
5121 } NDR_SMFARRAY_FORMAT;
5123 typedef struct
5125 unsigned char type;
5126 unsigned char alignment;
5127 ULONG total_size;
5128 } NDR_LGFARRAY_FORMAT;
5129 #include "poppack.h"
5131 /***********************************************************************
5132 * NdrFixedArrayMarshall [RPCRT4.@]
5134 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5135 unsigned char *pMemory,
5136 PFORMAT_STRING pFormat)
5138 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5139 ULONG total_size;
5141 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5143 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5144 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5146 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5147 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5148 return NULL;
5151 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5153 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5155 total_size = pSmFArrayFormat->total_size;
5156 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5158 else
5160 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5161 total_size = pLgFArrayFormat->total_size;
5162 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5165 pStubMsg->BufferMark = pStubMsg->Buffer;
5166 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5168 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5170 return NULL;
5173 /***********************************************************************
5174 * NdrFixedArrayUnmarshall [RPCRT4.@]
5176 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5177 unsigned char **ppMemory,
5178 PFORMAT_STRING pFormat,
5179 unsigned char fMustAlloc)
5181 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5182 ULONG total_size;
5183 unsigned char *saved_buffer;
5185 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5187 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5188 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5190 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5191 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5192 return NULL;
5195 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5197 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5199 total_size = pSmFArrayFormat->total_size;
5200 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5202 else
5204 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5205 total_size = pLgFArrayFormat->total_size;
5206 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5209 if (fMustAlloc)
5210 *ppMemory = NdrAllocate(pStubMsg, total_size);
5211 else
5213 if (!pStubMsg->IsClient && !*ppMemory)
5214 /* for servers, we just point straight into the RPC buffer */
5215 *ppMemory = pStubMsg->Buffer;
5218 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5219 safe_buffer_increment(pStubMsg, total_size);
5220 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5222 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5223 if (*ppMemory != saved_buffer)
5224 memcpy(*ppMemory, saved_buffer, total_size);
5226 return NULL;
5229 /***********************************************************************
5230 * NdrFixedArrayBufferSize [RPCRT4.@]
5232 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5233 unsigned char *pMemory,
5234 PFORMAT_STRING pFormat)
5236 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5237 ULONG total_size;
5239 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5241 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5242 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5244 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5245 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5246 return;
5249 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5251 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5253 total_size = pSmFArrayFormat->total_size;
5254 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5256 else
5258 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5259 total_size = pLgFArrayFormat->total_size;
5260 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5262 safe_buffer_length_increment(pStubMsg, total_size);
5264 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5267 /***********************************************************************
5268 * NdrFixedArrayMemorySize [RPCRT4.@]
5270 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5271 PFORMAT_STRING pFormat)
5273 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5274 ULONG total_size;
5276 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5278 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5279 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5281 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5282 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5283 return 0;
5286 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5288 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5290 total_size = pSmFArrayFormat->total_size;
5291 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5293 else
5295 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5296 total_size = pLgFArrayFormat->total_size;
5297 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5299 pStubMsg->BufferMark = pStubMsg->Buffer;
5300 safe_buffer_increment(pStubMsg, total_size);
5301 pStubMsg->MemorySize += total_size;
5303 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5305 return total_size;
5308 /***********************************************************************
5309 * NdrFixedArrayFree [RPCRT4.@]
5311 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5312 unsigned char *pMemory,
5313 PFORMAT_STRING pFormat)
5315 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5317 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5319 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5320 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5322 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5323 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5324 return;
5327 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5328 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5329 else
5331 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5332 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5335 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5338 /***********************************************************************
5339 * NdrVaryingArrayMarshall [RPCRT4.@]
5341 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5342 unsigned char *pMemory,
5343 PFORMAT_STRING pFormat)
5345 unsigned char alignment;
5346 DWORD elements, esize;
5347 ULONG bufsize;
5349 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5351 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5352 (pFormat[0] != RPC_FC_LGVARRAY))
5354 ERR("invalid format type %x\n", pFormat[0]);
5355 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5356 return NULL;
5359 alignment = pFormat[1] + 1;
5361 if (pFormat[0] == RPC_FC_SMVARRAY)
5363 pFormat += 2;
5364 pFormat += sizeof(WORD);
5365 elements = *(const WORD*)pFormat;
5366 pFormat += sizeof(WORD);
5368 else
5370 pFormat += 2;
5371 pFormat += sizeof(DWORD);
5372 elements = *(const DWORD*)pFormat;
5373 pFormat += sizeof(DWORD);
5376 esize = *(const WORD*)pFormat;
5377 pFormat += sizeof(WORD);
5379 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5380 if ((pStubMsg->ActualCount > elements) ||
5381 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5383 RpcRaiseException(RPC_S_INVALID_BOUND);
5384 return NULL;
5387 WriteVariance(pStubMsg);
5389 align_pointer_clear(&pStubMsg->Buffer, alignment);
5391 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5392 pStubMsg->BufferMark = pStubMsg->Buffer;
5393 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5395 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5397 return NULL;
5400 /***********************************************************************
5401 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5403 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5404 unsigned char **ppMemory,
5405 PFORMAT_STRING pFormat,
5406 unsigned char fMustAlloc)
5408 unsigned char alignment;
5409 DWORD size, elements, esize;
5410 ULONG bufsize;
5411 unsigned char *saved_buffer;
5412 ULONG offset;
5414 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5416 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5417 (pFormat[0] != RPC_FC_LGVARRAY))
5419 ERR("invalid format type %x\n", pFormat[0]);
5420 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5421 return NULL;
5424 alignment = pFormat[1] + 1;
5426 if (pFormat[0] == RPC_FC_SMVARRAY)
5428 pFormat += 2;
5429 size = *(const WORD*)pFormat;
5430 pFormat += sizeof(WORD);
5431 elements = *(const WORD*)pFormat;
5432 pFormat += sizeof(WORD);
5434 else
5436 pFormat += 2;
5437 size = *(const DWORD*)pFormat;
5438 pFormat += sizeof(DWORD);
5439 elements = *(const DWORD*)pFormat;
5440 pFormat += sizeof(DWORD);
5443 esize = *(const WORD*)pFormat;
5444 pFormat += sizeof(WORD);
5446 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5448 align_pointer(&pStubMsg->Buffer, alignment);
5450 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5451 offset = pStubMsg->Offset;
5453 if (!fMustAlloc && !*ppMemory)
5454 fMustAlloc = TRUE;
5455 if (fMustAlloc)
5456 *ppMemory = NdrAllocate(pStubMsg, size);
5457 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5458 safe_buffer_increment(pStubMsg, bufsize);
5460 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5462 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5464 return NULL;
5467 /***********************************************************************
5468 * NdrVaryingArrayBufferSize [RPCRT4.@]
5470 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5471 unsigned char *pMemory,
5472 PFORMAT_STRING pFormat)
5474 unsigned char alignment;
5475 DWORD elements, esize;
5477 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5479 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5480 (pFormat[0] != RPC_FC_LGVARRAY))
5482 ERR("invalid format type %x\n", pFormat[0]);
5483 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5484 return;
5487 alignment = pFormat[1] + 1;
5489 if (pFormat[0] == RPC_FC_SMVARRAY)
5491 pFormat += 2;
5492 pFormat += sizeof(WORD);
5493 elements = *(const WORD*)pFormat;
5494 pFormat += sizeof(WORD);
5496 else
5498 pFormat += 2;
5499 pFormat += sizeof(DWORD);
5500 elements = *(const DWORD*)pFormat;
5501 pFormat += sizeof(DWORD);
5504 esize = *(const WORD*)pFormat;
5505 pFormat += sizeof(WORD);
5507 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5508 if ((pStubMsg->ActualCount > elements) ||
5509 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5511 RpcRaiseException(RPC_S_INVALID_BOUND);
5512 return;
5515 SizeVariance(pStubMsg);
5517 align_length(&pStubMsg->BufferLength, alignment);
5519 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5521 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5524 /***********************************************************************
5525 * NdrVaryingArrayMemorySize [RPCRT4.@]
5527 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5528 PFORMAT_STRING pFormat)
5530 unsigned char alignment;
5531 DWORD size, elements, esize;
5533 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5535 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5536 (pFormat[0] != RPC_FC_LGVARRAY))
5538 ERR("invalid format type %x\n", pFormat[0]);
5539 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5540 return 0;
5543 alignment = pFormat[1] + 1;
5545 if (pFormat[0] == RPC_FC_SMVARRAY)
5547 pFormat += 2;
5548 size = *(const WORD*)pFormat;
5549 pFormat += sizeof(WORD);
5550 elements = *(const WORD*)pFormat;
5551 pFormat += sizeof(WORD);
5553 else
5555 pFormat += 2;
5556 size = *(const DWORD*)pFormat;
5557 pFormat += sizeof(DWORD);
5558 elements = *(const DWORD*)pFormat;
5559 pFormat += sizeof(DWORD);
5562 esize = *(const WORD*)pFormat;
5563 pFormat += sizeof(WORD);
5565 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5567 align_pointer(&pStubMsg->Buffer, alignment);
5569 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5570 pStubMsg->MemorySize += size;
5572 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5574 return pStubMsg->MemorySize;
5577 /***********************************************************************
5578 * NdrVaryingArrayFree [RPCRT4.@]
5580 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5581 unsigned char *pMemory,
5582 PFORMAT_STRING pFormat)
5584 DWORD elements;
5586 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5588 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5589 (pFormat[0] != RPC_FC_LGVARRAY))
5591 ERR("invalid format type %x\n", pFormat[0]);
5592 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5593 return;
5596 if (pFormat[0] == RPC_FC_SMVARRAY)
5598 pFormat += 2;
5599 pFormat += sizeof(WORD);
5600 elements = *(const WORD*)pFormat;
5601 pFormat += sizeof(WORD);
5603 else
5605 pFormat += 2;
5606 pFormat += sizeof(DWORD);
5607 elements = *(const DWORD*)pFormat;
5608 pFormat += sizeof(DWORD);
5611 pFormat += sizeof(WORD);
5613 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5614 if ((pStubMsg->ActualCount > elements) ||
5615 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5617 RpcRaiseException(RPC_S_INVALID_BOUND);
5618 return;
5621 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5624 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5626 switch (fc)
5628 case RPC_FC_BYTE:
5629 case RPC_FC_CHAR:
5630 case RPC_FC_SMALL:
5631 case RPC_FC_USMALL:
5632 return *pMemory;
5633 case RPC_FC_WCHAR:
5634 case RPC_FC_SHORT:
5635 case RPC_FC_USHORT:
5636 case RPC_FC_ENUM16:
5637 return *(const USHORT *)pMemory;
5638 case RPC_FC_LONG:
5639 case RPC_FC_ULONG:
5640 case RPC_FC_ENUM32:
5641 return *(const ULONG *)pMemory;
5642 case RPC_FC_INT3264:
5643 case RPC_FC_UINT3264:
5644 return *(const ULONG_PTR *)pMemory;
5645 default:
5646 FIXME("Unhandled base type: 0x%02x\n", fc);
5647 return 0;
5651 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5652 ULONG discriminant,
5653 PFORMAT_STRING pFormat)
5655 unsigned short num_arms, arm, type;
5657 num_arms = *(const SHORT*)pFormat & 0x0fff;
5658 pFormat += 2;
5659 for(arm = 0; arm < num_arms; arm++)
5661 if(discriminant == *(const ULONG*)pFormat)
5663 pFormat += 4;
5664 break;
5666 pFormat += 6;
5669 type = *(const unsigned short*)pFormat;
5670 TRACE("type %04x\n", type);
5671 if(arm == num_arms) /* default arm extras */
5673 if(type == 0xffff)
5675 ERR("no arm for 0x%x and no default case\n", discriminant);
5676 RpcRaiseException(RPC_S_INVALID_TAG);
5677 return NULL;
5679 if(type == 0)
5681 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5682 return NULL;
5685 return pFormat;
5688 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5690 unsigned short type;
5692 pFormat += 2;
5694 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5695 if(!pFormat)
5696 return NULL;
5698 type = *(const unsigned short*)pFormat;
5699 if((type & 0xff00) == 0x8000)
5701 unsigned char basetype = LOBYTE(type);
5702 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5704 else
5706 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5707 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5708 if (m)
5710 unsigned char *saved_buffer = NULL;
5711 int pointer_buffer_mark_set = 0;
5712 switch(*desc)
5714 case RPC_FC_RP:
5715 case RPC_FC_UP:
5716 case RPC_FC_OP:
5717 case RPC_FC_FP:
5718 align_pointer_clear(&pStubMsg->Buffer, 4);
5719 saved_buffer = pStubMsg->Buffer;
5720 if (pStubMsg->PointerBufferMark)
5722 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5723 pStubMsg->PointerBufferMark = NULL;
5724 pointer_buffer_mark_set = 1;
5726 else
5727 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5729 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5730 if (pointer_buffer_mark_set)
5732 STD_OVERFLOW_CHECK(pStubMsg);
5733 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5734 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5736 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5737 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5738 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5740 pStubMsg->Buffer = saved_buffer + 4;
5742 break;
5743 default:
5744 m(pStubMsg, pMemory, desc);
5747 else FIXME("no marshaller for embedded type %02x\n", *desc);
5749 return NULL;
5752 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5753 unsigned char **ppMemory,
5754 ULONG discriminant,
5755 PFORMAT_STRING pFormat,
5756 unsigned char fMustAlloc)
5758 unsigned short type;
5760 pFormat += 2;
5762 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5763 if(!pFormat)
5764 return NULL;
5766 type = *(const unsigned short*)pFormat;
5767 if((type & 0xff00) == 0x8000)
5769 unsigned char basetype = LOBYTE(type);
5770 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5772 else
5774 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5775 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5776 if (m)
5778 unsigned char *saved_buffer = NULL;
5779 int pointer_buffer_mark_set = 0;
5780 switch(*desc)
5782 case RPC_FC_RP:
5783 case RPC_FC_UP:
5784 case RPC_FC_OP:
5785 case RPC_FC_FP:
5786 align_pointer(&pStubMsg->Buffer, 4);
5787 saved_buffer = pStubMsg->Buffer;
5788 if (pStubMsg->PointerBufferMark)
5790 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5791 pStubMsg->PointerBufferMark = NULL;
5792 pointer_buffer_mark_set = 1;
5794 else
5795 pStubMsg->Buffer += 4; /* for pointer ID */
5797 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5799 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5800 saved_buffer, pStubMsg->BufferEnd);
5801 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5804 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5805 if (pointer_buffer_mark_set)
5807 STD_OVERFLOW_CHECK(pStubMsg);
5808 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5809 pStubMsg->Buffer = saved_buffer + 4;
5811 break;
5812 default:
5813 m(pStubMsg, ppMemory, desc, fMustAlloc);
5816 else FIXME("no marshaller for embedded type %02x\n", *desc);
5818 return NULL;
5821 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5822 unsigned char *pMemory,
5823 ULONG discriminant,
5824 PFORMAT_STRING pFormat)
5826 unsigned short type;
5828 pFormat += 2;
5830 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5831 if(!pFormat)
5832 return;
5834 type = *(const unsigned short*)pFormat;
5835 if((type & 0xff00) == 0x8000)
5837 unsigned char basetype = LOBYTE(type);
5838 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5840 else
5842 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5843 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5844 if (m)
5846 switch(*desc)
5848 case RPC_FC_RP:
5849 case RPC_FC_UP:
5850 case RPC_FC_OP:
5851 case RPC_FC_FP:
5852 align_length(&pStubMsg->BufferLength, 4);
5853 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5854 if (!pStubMsg->IgnoreEmbeddedPointers)
5856 int saved_buffer_length = pStubMsg->BufferLength;
5857 pStubMsg->BufferLength = pStubMsg->PointerLength;
5858 pStubMsg->PointerLength = 0;
5859 if(!pStubMsg->BufferLength)
5860 ERR("BufferLength == 0??\n");
5861 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5862 pStubMsg->PointerLength = pStubMsg->BufferLength;
5863 pStubMsg->BufferLength = saved_buffer_length;
5865 break;
5866 default:
5867 m(pStubMsg, pMemory, desc);
5870 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5874 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5875 ULONG discriminant,
5876 PFORMAT_STRING pFormat)
5878 unsigned short type, size;
5880 size = *(const unsigned short*)pFormat;
5881 pStubMsg->Memory += size;
5882 pFormat += 2;
5884 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5885 if(!pFormat)
5886 return 0;
5888 type = *(const unsigned short*)pFormat;
5889 if((type & 0xff00) == 0x8000)
5891 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5893 else
5895 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5896 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5897 unsigned char *saved_buffer;
5898 if (m)
5900 switch(*desc)
5902 case RPC_FC_RP:
5903 case RPC_FC_UP:
5904 case RPC_FC_OP:
5905 case RPC_FC_FP:
5906 align_pointer(&pStubMsg->Buffer, 4);
5907 saved_buffer = pStubMsg->Buffer;
5908 safe_buffer_increment(pStubMsg, 4);
5909 align_length(&pStubMsg->MemorySize, sizeof(void *));
5910 pStubMsg->MemorySize += sizeof(void *);
5911 if (!pStubMsg->IgnoreEmbeddedPointers)
5912 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5913 break;
5914 default:
5915 return m(pStubMsg, desc);
5918 else FIXME("no marshaller for embedded type %02x\n", *desc);
5921 TRACE("size %d\n", size);
5922 return size;
5925 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5926 unsigned char *pMemory,
5927 ULONG discriminant,
5928 PFORMAT_STRING pFormat)
5930 unsigned short type;
5932 pFormat += 2;
5934 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5935 if(!pFormat)
5936 return;
5938 type = *(const unsigned short*)pFormat;
5939 if((type & 0xff00) != 0x8000)
5941 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5942 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5943 if (m)
5945 switch(*desc)
5947 case RPC_FC_RP:
5948 case RPC_FC_UP:
5949 case RPC_FC_OP:
5950 case RPC_FC_FP:
5951 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5952 break;
5953 default:
5954 m(pStubMsg, pMemory, desc);
5960 /***********************************************************************
5961 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5963 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5964 unsigned char *pMemory,
5965 PFORMAT_STRING pFormat)
5967 unsigned char switch_type;
5968 unsigned char increment;
5969 ULONG switch_value;
5971 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5972 pFormat++;
5974 switch_type = *pFormat & 0xf;
5975 increment = (*pFormat & 0xf0) >> 4;
5976 pFormat++;
5978 align_pointer_clear(&pStubMsg->Buffer, increment);
5980 switch_value = get_discriminant(switch_type, pMemory);
5981 TRACE("got switch value 0x%x\n", switch_value);
5983 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5984 pMemory += increment;
5986 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5989 /***********************************************************************
5990 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5992 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5993 unsigned char **ppMemory,
5994 PFORMAT_STRING pFormat,
5995 unsigned char fMustAlloc)
5997 unsigned char switch_type;
5998 unsigned char increment;
5999 ULONG switch_value;
6000 unsigned short size;
6001 unsigned char *pMemoryArm;
6003 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6004 pFormat++;
6006 switch_type = *pFormat & 0xf;
6007 increment = (*pFormat & 0xf0) >> 4;
6008 pFormat++;
6010 align_pointer(&pStubMsg->Buffer, increment);
6011 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6012 TRACE("got switch value 0x%x\n", switch_value);
6014 size = *(const unsigned short*)pFormat + increment;
6015 if (!fMustAlloc && !*ppMemory)
6016 fMustAlloc = TRUE;
6017 if (fMustAlloc)
6018 *ppMemory = NdrAllocate(pStubMsg, size);
6020 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6021 * since the arm is part of the memory block that is encompassed by
6022 * the whole union. Memory is forced to allocate when pointers
6023 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6024 * clearing the memory we pass in to the unmarshaller */
6025 if (fMustAlloc)
6026 memset(*ppMemory, 0, size);
6028 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6029 pMemoryArm = *ppMemory + increment;
6031 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6034 /***********************************************************************
6035 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6037 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6038 unsigned char *pMemory,
6039 PFORMAT_STRING pFormat)
6041 unsigned char switch_type;
6042 unsigned char increment;
6043 ULONG switch_value;
6045 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6046 pFormat++;
6048 switch_type = *pFormat & 0xf;
6049 increment = (*pFormat & 0xf0) >> 4;
6050 pFormat++;
6052 align_length(&pStubMsg->BufferLength, increment);
6053 switch_value = get_discriminant(switch_type, pMemory);
6054 TRACE("got switch value 0x%x\n", switch_value);
6056 /* Add discriminant size */
6057 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6058 pMemory += increment;
6060 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6063 /***********************************************************************
6064 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6066 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6067 PFORMAT_STRING pFormat)
6069 unsigned char switch_type;
6070 unsigned char increment;
6071 ULONG switch_value;
6073 switch_type = *pFormat & 0xf;
6074 increment = (*pFormat & 0xf0) >> 4;
6075 pFormat++;
6077 align_pointer(&pStubMsg->Buffer, increment);
6078 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6079 TRACE("got switch value 0x%x\n", switch_value);
6081 pStubMsg->Memory += increment;
6083 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6086 /***********************************************************************
6087 * NdrEncapsulatedUnionFree [RPCRT4.@]
6089 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6090 unsigned char *pMemory,
6091 PFORMAT_STRING pFormat)
6093 unsigned char switch_type;
6094 unsigned char increment;
6095 ULONG switch_value;
6097 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6098 pFormat++;
6100 switch_type = *pFormat & 0xf;
6101 increment = (*pFormat & 0xf0) >> 4;
6102 pFormat++;
6104 switch_value = get_discriminant(switch_type, pMemory);
6105 TRACE("got switch value 0x%x\n", switch_value);
6107 pMemory += increment;
6109 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6112 /***********************************************************************
6113 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6115 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6116 unsigned char *pMemory,
6117 PFORMAT_STRING pFormat)
6119 unsigned char switch_type;
6121 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6122 pFormat++;
6124 switch_type = *pFormat;
6125 pFormat++;
6127 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6128 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6129 /* Marshall discriminant */
6130 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6132 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6135 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6136 PFORMAT_STRING *ppFormat)
6138 LONG discriminant = 0;
6140 switch(**ppFormat)
6142 case RPC_FC_BYTE:
6143 case RPC_FC_CHAR:
6144 case RPC_FC_SMALL:
6145 case RPC_FC_USMALL:
6147 UCHAR d;
6148 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6149 discriminant = d;
6150 break;
6152 case RPC_FC_WCHAR:
6153 case RPC_FC_SHORT:
6154 case RPC_FC_USHORT:
6156 USHORT d;
6157 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6158 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6159 discriminant = d;
6160 break;
6162 case RPC_FC_LONG:
6163 case RPC_FC_ULONG:
6165 ULONG d;
6166 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6167 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6168 discriminant = d;
6169 break;
6171 default:
6172 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6174 (*ppFormat)++;
6176 if (pStubMsg->fHasNewCorrDesc)
6177 *ppFormat += 6;
6178 else
6179 *ppFormat += 4;
6180 return discriminant;
6183 /**********************************************************************
6184 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6186 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6187 unsigned char **ppMemory,
6188 PFORMAT_STRING pFormat,
6189 unsigned char fMustAlloc)
6191 LONG discriminant;
6192 unsigned short size;
6194 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6195 pFormat++;
6197 /* Unmarshall discriminant */
6198 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6199 TRACE("unmarshalled discriminant %x\n", discriminant);
6201 pFormat += *(const SHORT*)pFormat;
6203 size = *(const unsigned short*)pFormat;
6205 if (!fMustAlloc && !*ppMemory)
6206 fMustAlloc = TRUE;
6207 if (fMustAlloc)
6208 *ppMemory = NdrAllocate(pStubMsg, size);
6210 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6211 * since the arm is part of the memory block that is encompassed by
6212 * the whole union. Memory is forced to allocate when pointers
6213 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6214 * clearing the memory we pass in to the unmarshaller */
6215 if (fMustAlloc)
6216 memset(*ppMemory, 0, size);
6218 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6221 /***********************************************************************
6222 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6224 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6225 unsigned char *pMemory,
6226 PFORMAT_STRING pFormat)
6228 unsigned char switch_type;
6230 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6231 pFormat++;
6233 switch_type = *pFormat;
6234 pFormat++;
6236 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6237 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6238 /* Add discriminant size */
6239 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6241 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6244 /***********************************************************************
6245 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6247 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6248 PFORMAT_STRING pFormat)
6250 ULONG discriminant;
6252 pFormat++;
6253 /* Unmarshall discriminant */
6254 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6255 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6257 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6260 /***********************************************************************
6261 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6263 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6264 unsigned char *pMemory,
6265 PFORMAT_STRING pFormat)
6267 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6268 pFormat++;
6269 pFormat++;
6271 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6272 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6274 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6277 /***********************************************************************
6278 * NdrByteCountPointerMarshall [RPCRT4.@]
6280 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6281 unsigned char *pMemory,
6282 PFORMAT_STRING pFormat)
6284 FIXME("stub\n");
6285 return NULL;
6288 /***********************************************************************
6289 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6291 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6292 unsigned char **ppMemory,
6293 PFORMAT_STRING pFormat,
6294 unsigned char fMustAlloc)
6296 FIXME("stub\n");
6297 return NULL;
6300 /***********************************************************************
6301 * NdrByteCountPointerBufferSize [RPCRT4.@]
6303 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6304 unsigned char *pMemory,
6305 PFORMAT_STRING pFormat)
6307 FIXME("stub\n");
6310 /***********************************************************************
6311 * NdrByteCountPointerMemorySize [internal]
6313 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6314 PFORMAT_STRING pFormat)
6316 FIXME("stub\n");
6317 return 0;
6320 /***********************************************************************
6321 * NdrByteCountPointerFree [RPCRT4.@]
6323 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6324 unsigned char *pMemory,
6325 PFORMAT_STRING pFormat)
6327 FIXME("stub\n");
6330 /***********************************************************************
6331 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6333 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6334 unsigned char *pMemory,
6335 PFORMAT_STRING pFormat)
6337 FIXME("stub\n");
6338 return NULL;
6341 /***********************************************************************
6342 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6344 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6345 unsigned char **ppMemory,
6346 PFORMAT_STRING pFormat,
6347 unsigned char fMustAlloc)
6349 FIXME("stub\n");
6350 return NULL;
6353 /***********************************************************************
6354 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6356 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6357 unsigned char *pMemory,
6358 PFORMAT_STRING pFormat)
6360 FIXME("stub\n");
6363 /***********************************************************************
6364 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6366 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6367 PFORMAT_STRING pFormat)
6369 FIXME("stub\n");
6370 return 0;
6373 /***********************************************************************
6374 * NdrXmitOrRepAsFree [RPCRT4.@]
6376 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6377 unsigned char *pMemory,
6378 PFORMAT_STRING pFormat)
6380 FIXME("stub\n");
6383 /***********************************************************************
6384 * NdrRangeMarshall [internal]
6386 static unsigned char *WINAPI NdrRangeMarshall(
6387 PMIDL_STUB_MESSAGE pStubMsg,
6388 unsigned char *pMemory,
6389 PFORMAT_STRING pFormat)
6391 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6392 unsigned char base_type;
6394 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6396 if (pRange->type != RPC_FC_RANGE)
6398 ERR("invalid format type %x\n", pRange->type);
6399 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6400 return NULL;
6403 base_type = pRange->flags_type & 0xf;
6405 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6408 /***********************************************************************
6409 * NdrRangeUnmarshall [RPCRT4.@]
6411 unsigned char *WINAPI NdrRangeUnmarshall(
6412 PMIDL_STUB_MESSAGE pStubMsg,
6413 unsigned char **ppMemory,
6414 PFORMAT_STRING pFormat,
6415 unsigned char fMustAlloc)
6417 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6418 unsigned char base_type;
6420 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6422 if (pRange->type != RPC_FC_RANGE)
6424 ERR("invalid format type %x\n", pRange->type);
6425 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6426 return NULL;
6428 base_type = pRange->flags_type & 0xf;
6430 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6431 base_type, pRange->low_value, pRange->high_value);
6433 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6434 do \
6436 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6437 if (!fMustAlloc && !*ppMemory) \
6438 fMustAlloc = TRUE; \
6439 if (fMustAlloc) \
6440 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6441 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6443 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6444 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6445 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6447 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6448 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6450 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6451 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6452 (mem_type)pRange->high_value); \
6453 RpcRaiseException(RPC_S_INVALID_BOUND); \
6454 return NULL; \
6456 TRACE("*ppMemory: %p\n", *ppMemory); \
6457 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6458 pStubMsg->Buffer += sizeof(wire_type); \
6459 } while (0)
6461 switch(base_type)
6463 case RPC_FC_CHAR:
6464 case RPC_FC_SMALL:
6465 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6466 TRACE("value: 0x%02x\n", **ppMemory);
6467 break;
6468 case RPC_FC_BYTE:
6469 case RPC_FC_USMALL:
6470 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6471 TRACE("value: 0x%02x\n", **ppMemory);
6472 break;
6473 case RPC_FC_WCHAR: /* FIXME: valid? */
6474 case RPC_FC_USHORT:
6475 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6476 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6477 break;
6478 case RPC_FC_SHORT:
6479 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6480 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6481 break;
6482 case RPC_FC_LONG:
6483 case RPC_FC_ENUM32:
6484 RANGE_UNMARSHALL(LONG, LONG, "%d");
6485 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6486 break;
6487 case RPC_FC_ULONG:
6488 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6489 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6490 break;
6491 case RPC_FC_ENUM16:
6492 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6493 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6494 break;
6495 case RPC_FC_FLOAT:
6496 case RPC_FC_DOUBLE:
6497 case RPC_FC_HYPER:
6498 default:
6499 ERR("invalid range base type: 0x%02x\n", base_type);
6500 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6503 return NULL;
6506 /***********************************************************************
6507 * NdrRangeBufferSize [internal]
6509 static void WINAPI NdrRangeBufferSize(
6510 PMIDL_STUB_MESSAGE pStubMsg,
6511 unsigned char *pMemory,
6512 PFORMAT_STRING pFormat)
6514 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6515 unsigned char base_type;
6517 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6519 if (pRange->type != RPC_FC_RANGE)
6521 ERR("invalid format type %x\n", pRange->type);
6522 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6524 base_type = pRange->flags_type & 0xf;
6526 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6529 /***********************************************************************
6530 * NdrRangeMemorySize [internal]
6532 static ULONG WINAPI NdrRangeMemorySize(
6533 PMIDL_STUB_MESSAGE pStubMsg,
6534 PFORMAT_STRING pFormat)
6536 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6537 unsigned char base_type;
6539 if (pRange->type != RPC_FC_RANGE)
6541 ERR("invalid format type %x\n", pRange->type);
6542 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6543 return 0;
6545 base_type = pRange->flags_type & 0xf;
6547 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6550 /***********************************************************************
6551 * NdrRangeFree [internal]
6553 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6554 unsigned char *pMemory,
6555 PFORMAT_STRING pFormat)
6557 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6559 /* nothing to do */
6562 /***********************************************************************
6563 * NdrBaseTypeMarshall [internal]
6565 static unsigned char *WINAPI NdrBaseTypeMarshall(
6566 PMIDL_STUB_MESSAGE pStubMsg,
6567 unsigned char *pMemory,
6568 PFORMAT_STRING pFormat)
6570 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6572 switch(*pFormat)
6574 case RPC_FC_BYTE:
6575 case RPC_FC_CHAR:
6576 case RPC_FC_SMALL:
6577 case RPC_FC_USMALL:
6578 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6579 TRACE("value: 0x%02x\n", *pMemory);
6580 break;
6581 case RPC_FC_WCHAR:
6582 case RPC_FC_SHORT:
6583 case RPC_FC_USHORT:
6584 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6585 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6586 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6587 break;
6588 case RPC_FC_LONG:
6589 case RPC_FC_ULONG:
6590 case RPC_FC_ERROR_STATUS_T:
6591 case RPC_FC_ENUM32:
6592 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6593 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6594 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6595 break;
6596 case RPC_FC_FLOAT:
6597 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6598 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6599 break;
6600 case RPC_FC_DOUBLE:
6601 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6602 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6603 break;
6604 case RPC_FC_HYPER:
6605 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6606 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6607 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6608 break;
6609 case RPC_FC_ENUM16:
6611 USHORT val = *(UINT *)pMemory;
6612 /* only 16-bits on the wire, so do a sanity check */
6613 if (*(UINT *)pMemory > SHRT_MAX)
6614 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6615 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6616 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6617 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6618 break;
6620 case RPC_FC_INT3264:
6621 case RPC_FC_UINT3264:
6623 UINT val = *(UINT_PTR *)pMemory;
6624 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6625 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6626 break;
6628 case RPC_FC_IGNORE:
6629 break;
6630 default:
6631 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6634 /* FIXME: what is the correct return value? */
6635 return NULL;
6638 /***********************************************************************
6639 * NdrBaseTypeUnmarshall [internal]
6641 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6642 PMIDL_STUB_MESSAGE pStubMsg,
6643 unsigned char **ppMemory,
6644 PFORMAT_STRING pFormat,
6645 unsigned char fMustAlloc)
6647 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6649 #define BASE_TYPE_UNMARSHALL(type) do { \
6650 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6651 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6653 *ppMemory = pStubMsg->Buffer; \
6654 TRACE("*ppMemory: %p\n", *ppMemory); \
6655 safe_buffer_increment(pStubMsg, sizeof(type)); \
6657 else \
6659 if (fMustAlloc) \
6660 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6661 TRACE("*ppMemory: %p\n", *ppMemory); \
6662 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6664 } while (0)
6666 switch(*pFormat)
6668 case RPC_FC_BYTE:
6669 case RPC_FC_CHAR:
6670 case RPC_FC_SMALL:
6671 case RPC_FC_USMALL:
6672 BASE_TYPE_UNMARSHALL(UCHAR);
6673 TRACE("value: 0x%02x\n", **ppMemory);
6674 break;
6675 case RPC_FC_WCHAR:
6676 case RPC_FC_SHORT:
6677 case RPC_FC_USHORT:
6678 BASE_TYPE_UNMARSHALL(USHORT);
6679 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6680 break;
6681 case RPC_FC_LONG:
6682 case RPC_FC_ULONG:
6683 case RPC_FC_ERROR_STATUS_T:
6684 case RPC_FC_ENUM32:
6685 BASE_TYPE_UNMARSHALL(ULONG);
6686 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6687 break;
6688 case RPC_FC_FLOAT:
6689 BASE_TYPE_UNMARSHALL(float);
6690 TRACE("value: %f\n", **(float **)ppMemory);
6691 break;
6692 case RPC_FC_DOUBLE:
6693 BASE_TYPE_UNMARSHALL(double);
6694 TRACE("value: %f\n", **(double **)ppMemory);
6695 break;
6696 case RPC_FC_HYPER:
6697 BASE_TYPE_UNMARSHALL(ULONGLONG);
6698 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6699 break;
6700 case RPC_FC_ENUM16:
6702 USHORT val;
6703 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6704 if (!fMustAlloc && !*ppMemory)
6705 fMustAlloc = TRUE;
6706 if (fMustAlloc)
6707 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6708 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6709 /* 16-bits on the wire, but int in memory */
6710 **(UINT **)ppMemory = val;
6711 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6712 break;
6714 case RPC_FC_INT3264:
6715 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6716 else
6718 INT val;
6719 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6720 if (!fMustAlloc && !*ppMemory)
6721 fMustAlloc = TRUE;
6722 if (fMustAlloc)
6723 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6724 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6725 **(INT_PTR **)ppMemory = val;
6726 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6728 break;
6729 case RPC_FC_UINT3264:
6730 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6731 else
6733 UINT val;
6734 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6735 if (!fMustAlloc && !*ppMemory)
6736 fMustAlloc = TRUE;
6737 if (fMustAlloc)
6738 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6739 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6740 **(UINT_PTR **)ppMemory = val;
6741 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6743 break;
6744 case RPC_FC_IGNORE:
6745 break;
6746 default:
6747 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6749 #undef BASE_TYPE_UNMARSHALL
6751 /* FIXME: what is the correct return value? */
6753 return NULL;
6756 /***********************************************************************
6757 * NdrBaseTypeBufferSize [internal]
6759 static void WINAPI NdrBaseTypeBufferSize(
6760 PMIDL_STUB_MESSAGE pStubMsg,
6761 unsigned char *pMemory,
6762 PFORMAT_STRING pFormat)
6764 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6766 switch(*pFormat)
6768 case RPC_FC_BYTE:
6769 case RPC_FC_CHAR:
6770 case RPC_FC_SMALL:
6771 case RPC_FC_USMALL:
6772 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6773 break;
6774 case RPC_FC_WCHAR:
6775 case RPC_FC_SHORT:
6776 case RPC_FC_USHORT:
6777 case RPC_FC_ENUM16:
6778 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6779 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6780 break;
6781 case RPC_FC_LONG:
6782 case RPC_FC_ULONG:
6783 case RPC_FC_ENUM32:
6784 case RPC_FC_INT3264:
6785 case RPC_FC_UINT3264:
6786 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6787 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6788 break;
6789 case RPC_FC_FLOAT:
6790 align_length(&pStubMsg->BufferLength, sizeof(float));
6791 safe_buffer_length_increment(pStubMsg, sizeof(float));
6792 break;
6793 case RPC_FC_DOUBLE:
6794 align_length(&pStubMsg->BufferLength, sizeof(double));
6795 safe_buffer_length_increment(pStubMsg, sizeof(double));
6796 break;
6797 case RPC_FC_HYPER:
6798 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6799 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6800 break;
6801 case RPC_FC_ERROR_STATUS_T:
6802 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6803 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6804 break;
6805 case RPC_FC_IGNORE:
6806 break;
6807 default:
6808 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6812 /***********************************************************************
6813 * NdrBaseTypeMemorySize [internal]
6815 static ULONG WINAPI NdrBaseTypeMemorySize(
6816 PMIDL_STUB_MESSAGE pStubMsg,
6817 PFORMAT_STRING pFormat)
6819 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6821 switch(*pFormat)
6823 case RPC_FC_BYTE:
6824 case RPC_FC_CHAR:
6825 case RPC_FC_SMALL:
6826 case RPC_FC_USMALL:
6827 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6828 pStubMsg->MemorySize += sizeof(UCHAR);
6829 return sizeof(UCHAR);
6830 case RPC_FC_WCHAR:
6831 case RPC_FC_SHORT:
6832 case RPC_FC_USHORT:
6833 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6834 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6835 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6836 pStubMsg->MemorySize += sizeof(USHORT);
6837 return sizeof(USHORT);
6838 case RPC_FC_LONG:
6839 case RPC_FC_ULONG:
6840 case RPC_FC_ENUM32:
6841 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6842 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6843 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6844 pStubMsg->MemorySize += sizeof(ULONG);
6845 return sizeof(ULONG);
6846 case RPC_FC_FLOAT:
6847 align_pointer(&pStubMsg->Buffer, sizeof(float));
6848 safe_buffer_increment(pStubMsg, sizeof(float));
6849 align_length(&pStubMsg->MemorySize, sizeof(float));
6850 pStubMsg->MemorySize += sizeof(float);
6851 return sizeof(float);
6852 case RPC_FC_DOUBLE:
6853 align_pointer(&pStubMsg->Buffer, sizeof(double));
6854 safe_buffer_increment(pStubMsg, sizeof(double));
6855 align_length(&pStubMsg->MemorySize, sizeof(double));
6856 pStubMsg->MemorySize += sizeof(double);
6857 return sizeof(double);
6858 case RPC_FC_HYPER:
6859 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6860 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6861 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6862 pStubMsg->MemorySize += sizeof(ULONGLONG);
6863 return sizeof(ULONGLONG);
6864 case RPC_FC_ERROR_STATUS_T:
6865 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6866 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6867 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6868 pStubMsg->MemorySize += sizeof(error_status_t);
6869 return sizeof(error_status_t);
6870 case RPC_FC_ENUM16:
6871 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6872 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6873 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6874 pStubMsg->MemorySize += sizeof(UINT);
6875 return sizeof(UINT);
6876 case RPC_FC_INT3264:
6877 case RPC_FC_UINT3264:
6878 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6879 safe_buffer_increment(pStubMsg, sizeof(UINT));
6880 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6881 pStubMsg->MemorySize += sizeof(UINT_PTR);
6882 return sizeof(UINT_PTR);
6883 case RPC_FC_IGNORE:
6884 align_length(&pStubMsg->MemorySize, sizeof(void *));
6885 pStubMsg->MemorySize += sizeof(void *);
6886 return sizeof(void *);
6887 default:
6888 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6889 return 0;
6893 /***********************************************************************
6894 * NdrBaseTypeFree [internal]
6896 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6897 unsigned char *pMemory,
6898 PFORMAT_STRING pFormat)
6900 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6902 /* nothing to do */
6905 /***********************************************************************
6906 * NdrContextHandleBufferSize [internal]
6908 static void WINAPI NdrContextHandleBufferSize(
6909 PMIDL_STUB_MESSAGE pStubMsg,
6910 unsigned char *pMemory,
6911 PFORMAT_STRING pFormat)
6913 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6915 if (*pFormat != RPC_FC_BIND_CONTEXT)
6917 ERR("invalid format type %x\n", *pFormat);
6918 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6920 align_length(&pStubMsg->BufferLength, 4);
6921 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6924 /***********************************************************************
6925 * NdrContextHandleMarshall [internal]
6927 static unsigned char *WINAPI NdrContextHandleMarshall(
6928 PMIDL_STUB_MESSAGE pStubMsg,
6929 unsigned char *pMemory,
6930 PFORMAT_STRING pFormat)
6932 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6934 if (*pFormat != RPC_FC_BIND_CONTEXT)
6936 ERR("invalid format type %x\n", *pFormat);
6937 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6939 TRACE("flags: 0x%02x\n", pFormat[1]);
6941 if (pStubMsg->IsClient)
6943 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6944 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6945 else
6946 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6948 else
6950 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6951 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6952 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6955 return NULL;
6958 /***********************************************************************
6959 * NdrContextHandleUnmarshall [internal]
6961 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6962 PMIDL_STUB_MESSAGE pStubMsg,
6963 unsigned char **ppMemory,
6964 PFORMAT_STRING pFormat,
6965 unsigned char fMustAlloc)
6967 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6968 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6970 if (*pFormat != RPC_FC_BIND_CONTEXT)
6972 ERR("invalid format type %x\n", *pFormat);
6973 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6975 TRACE("flags: 0x%02x\n", pFormat[1]);
6977 if (pStubMsg->IsClient)
6979 /* [out]-only or [ret] param */
6980 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6981 **(NDR_CCONTEXT **)ppMemory = NULL;
6982 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6984 else
6986 NDR_SCONTEXT ctxt;
6987 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6988 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6989 *(void **)ppMemory = NDRSContextValue(ctxt);
6990 else
6991 *(void **)ppMemory = *NDRSContextValue(ctxt);
6994 return NULL;
6997 /***********************************************************************
6998 * NdrClientContextMarshall [RPCRT4.@]
7000 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7001 NDR_CCONTEXT ContextHandle,
7002 int fCheck)
7004 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7006 align_pointer_clear(&pStubMsg->Buffer, 4);
7008 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7010 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7011 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7012 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7015 /* FIXME: what does fCheck do? */
7016 NDRCContextMarshall(ContextHandle,
7017 pStubMsg->Buffer);
7019 pStubMsg->Buffer += cbNDRContext;
7022 /***********************************************************************
7023 * NdrClientContextUnmarshall [RPCRT4.@]
7025 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7026 NDR_CCONTEXT * pContextHandle,
7027 RPC_BINDING_HANDLE BindHandle)
7029 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7031 align_pointer(&pStubMsg->Buffer, 4);
7033 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7034 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7036 NDRCContextUnmarshall(pContextHandle,
7037 BindHandle,
7038 pStubMsg->Buffer,
7039 pStubMsg->RpcMsg->DataRepresentation);
7041 pStubMsg->Buffer += cbNDRContext;
7044 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7045 NDR_SCONTEXT ContextHandle,
7046 NDR_RUNDOWN RundownRoutine )
7048 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7050 align_pointer(&pStubMsg->Buffer, 4);
7052 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7054 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7055 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7056 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7059 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7060 pStubMsg->Buffer, RundownRoutine, NULL,
7061 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7062 pStubMsg->Buffer += cbNDRContext;
7065 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7067 NDR_SCONTEXT ContextHandle;
7069 TRACE("(%p)\n", pStubMsg);
7071 align_pointer(&pStubMsg->Buffer, 4);
7073 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7075 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7076 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7077 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7080 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7081 pStubMsg->Buffer,
7082 pStubMsg->RpcMsg->DataRepresentation,
7083 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7084 pStubMsg->Buffer += cbNDRContext;
7086 return ContextHandle;
7089 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7090 unsigned char* pMemory,
7091 PFORMAT_STRING pFormat)
7093 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7096 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7097 PFORMAT_STRING pFormat)
7099 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7100 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7102 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7104 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7105 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7106 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7107 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7108 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7110 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7111 if_id = &sif->InterfaceId;
7114 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7115 pStubMsg->RpcMsg->DataRepresentation, if_id,
7116 flags);
7119 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7120 NDR_SCONTEXT ContextHandle,
7121 NDR_RUNDOWN RundownRoutine,
7122 PFORMAT_STRING pFormat)
7124 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7125 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7127 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7129 align_pointer(&pStubMsg->Buffer, 4);
7131 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7133 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7134 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7135 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7138 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7139 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7140 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7141 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7142 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7144 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7145 if_id = &sif->InterfaceId;
7148 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7149 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7150 pStubMsg->Buffer += cbNDRContext;
7153 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7154 PFORMAT_STRING pFormat)
7156 NDR_SCONTEXT ContextHandle;
7157 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7158 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7160 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7162 align_pointer(&pStubMsg->Buffer, 4);
7164 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7166 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7167 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7168 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7171 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7172 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7173 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7174 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7175 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7177 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7178 if_id = &sif->InterfaceId;
7181 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7182 pStubMsg->Buffer,
7183 pStubMsg->RpcMsg->DataRepresentation,
7184 if_id, flags);
7185 pStubMsg->Buffer += cbNDRContext;
7187 return ContextHandle;
7190 /***********************************************************************
7191 * NdrCorrelationInitialize [RPCRT4.@]
7193 * Initializes correlation validity checking.
7195 * PARAMS
7196 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7197 * pMemory [I] Pointer to memory to use as a cache.
7198 * CacheSize [I] Size of the memory pointed to by pMemory.
7199 * Flags [I] Reserved. Set to zero.
7201 * RETURNS
7202 * Nothing.
7204 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7206 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
7207 pStubMsg->fHasNewCorrDesc = TRUE;
7210 /***********************************************************************
7211 * NdrCorrelationPass [RPCRT4.@]
7213 * Performs correlation validity checking.
7215 * PARAMS
7216 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7218 * RETURNS
7219 * Nothing.
7221 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7223 FIXME("(%p): stub\n", pStubMsg);
7226 /***********************************************************************
7227 * NdrCorrelationFree [RPCRT4.@]
7229 * Frees any resources used while unmarshalling parameters that need
7230 * correlation validity checking.
7232 * PARAMS
7233 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7235 * RETURNS
7236 * Nothing.
7238 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7240 FIXME("(%p): stub\n", pStubMsg);