d3d8/tests: Use wine_dbgstr_rect() to print RECTs.
[wine.git] / dlls / rpcrt4 / ndr_marshall.c
blob5414329edd547f85df722482e80d0d8596a17556
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,
205 NdrBaseTypeMarshall,
206 NdrBaseTypeMarshall
208 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
210 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
211 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
212 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
213 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
214 /* 0x10 */
215 NdrBaseTypeUnmarshall,
216 /* 0x11 */
217 NdrPointerUnmarshall, NdrPointerUnmarshall,
218 NdrPointerUnmarshall, NdrPointerUnmarshall,
219 /* 0x15 */
220 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
221 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
222 NdrConformantVaryingStructUnmarshall,
223 NdrComplexStructUnmarshall,
224 /* 0x1b */
225 NdrConformantArrayUnmarshall,
226 NdrConformantVaryingArrayUnmarshall,
227 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
228 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
229 NdrComplexArrayUnmarshall,
230 /* 0x22 */
231 NdrConformantStringUnmarshall, 0, 0,
232 NdrConformantStringUnmarshall,
233 NdrNonConformantStringUnmarshall, 0, 0, 0,
234 /* 0x2a */
235 NdrEncapsulatedUnionUnmarshall,
236 NdrNonEncapsulatedUnionUnmarshall,
237 NdrByteCountPointerUnmarshall,
238 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
239 /* 0x2f */
240 NdrInterfacePointerUnmarshall,
241 /* 0x30 */
242 NdrContextHandleUnmarshall,
243 /* 0xb1 */
244 0, 0, 0,
245 NdrUserMarshalUnmarshall,
246 0, 0,
247 /* 0xb7 */
248 NdrRangeUnmarshall,
249 NdrBaseTypeUnmarshall,
250 NdrBaseTypeUnmarshall
252 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
254 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
255 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
256 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
257 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
258 /* 0x10 */
259 NdrBaseTypeBufferSize,
260 /* 0x11 */
261 NdrPointerBufferSize, NdrPointerBufferSize,
262 NdrPointerBufferSize, NdrPointerBufferSize,
263 /* 0x15 */
264 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
265 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
266 NdrConformantVaryingStructBufferSize,
267 NdrComplexStructBufferSize,
268 /* 0x1b */
269 NdrConformantArrayBufferSize,
270 NdrConformantVaryingArrayBufferSize,
271 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
272 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
273 NdrComplexArrayBufferSize,
274 /* 0x22 */
275 NdrConformantStringBufferSize, 0, 0,
276 NdrConformantStringBufferSize,
277 NdrNonConformantStringBufferSize, 0, 0, 0,
278 /* 0x2a */
279 NdrEncapsulatedUnionBufferSize,
280 NdrNonEncapsulatedUnionBufferSize,
281 NdrByteCountPointerBufferSize,
282 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
283 /* 0x2f */
284 NdrInterfacePointerBufferSize,
285 /* 0x30 */
286 NdrContextHandleBufferSize,
287 /* 0xb1 */
288 0, 0, 0,
289 NdrUserMarshalBufferSize,
290 0, 0,
291 /* 0xb7 */
292 NdrRangeBufferSize,
293 NdrBaseTypeBufferSize,
294 NdrBaseTypeBufferSize
296 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
298 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
299 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
300 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
301 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
302 /* 0x10 */
303 NdrBaseTypeMemorySize,
304 /* 0x11 */
305 NdrPointerMemorySize, NdrPointerMemorySize,
306 NdrPointerMemorySize, NdrPointerMemorySize,
307 /* 0x15 */
308 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
309 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
310 NdrConformantVaryingStructMemorySize,
311 NdrComplexStructMemorySize,
312 /* 0x1b */
313 NdrConformantArrayMemorySize,
314 NdrConformantVaryingArrayMemorySize,
315 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
316 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
317 NdrComplexArrayMemorySize,
318 /* 0x22 */
319 NdrConformantStringMemorySize, 0, 0,
320 NdrConformantStringMemorySize,
321 NdrNonConformantStringMemorySize, 0, 0, 0,
322 /* 0x2a */
323 NdrEncapsulatedUnionMemorySize,
324 NdrNonEncapsulatedUnionMemorySize,
325 NdrByteCountPointerMemorySize,
326 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
327 /* 0x2f */
328 NdrInterfacePointerMemorySize,
329 /* 0x30 */
331 /* 0xb1 */
332 0, 0, 0,
333 NdrUserMarshalMemorySize,
334 0, 0,
335 /* 0xb7 */
336 NdrRangeMemorySize,
337 NdrBaseTypeMemorySize,
338 NdrBaseTypeMemorySize
340 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
342 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
343 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
344 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
345 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
346 /* 0x10 */
347 NdrBaseTypeFree,
348 /* 0x11 */
349 NdrPointerFree, NdrPointerFree,
350 NdrPointerFree, NdrPointerFree,
351 /* 0x15 */
352 NdrSimpleStructFree, NdrSimpleStructFree,
353 NdrConformantStructFree, NdrConformantStructFree,
354 NdrConformantVaryingStructFree,
355 NdrComplexStructFree,
356 /* 0x1b */
357 NdrConformantArrayFree,
358 NdrConformantVaryingArrayFree,
359 NdrFixedArrayFree, NdrFixedArrayFree,
360 NdrVaryingArrayFree, NdrVaryingArrayFree,
361 NdrComplexArrayFree,
362 /* 0x22 */
363 0, 0, 0,
364 0, 0, 0, 0, 0,
365 /* 0x2a */
366 NdrEncapsulatedUnionFree,
367 NdrNonEncapsulatedUnionFree,
369 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
370 /* 0x2f */
371 NdrInterfacePointerFree,
372 /* 0x30 */
374 /* 0xb1 */
375 0, 0, 0,
376 NdrUserMarshalFree,
377 0, 0,
378 /* 0xb7 */
379 NdrRangeFree,
380 NdrBaseTypeFree,
381 NdrBaseTypeFree
384 typedef struct _NDR_MEMORY_LIST
386 ULONG magic;
387 ULONG size;
388 ULONG reserved;
389 struct _NDR_MEMORY_LIST *next;
390 } NDR_MEMORY_LIST;
392 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
394 /***********************************************************************
395 * NdrAllocate [RPCRT4.@]
397 * Allocates a block of memory using pStubMsg->pfnAllocate.
399 * PARAMS
400 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
401 * len [I] Size of memory block to allocate.
403 * RETURNS
404 * The memory block of size len that was allocated.
406 * NOTES
407 * The memory block is always 8-byte aligned.
408 * If the function is unable to allocate memory an RPC_X_NO_MEMORY
409 * exception is raised.
411 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
413 SIZE_T aligned_len;
414 SIZE_T adjusted_len;
415 void *p;
416 NDR_MEMORY_LIST *mem_list;
418 aligned_len = (len + 7) & ~7;
419 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
420 /* check for overflow */
421 if (adjusted_len < len)
423 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
424 RpcRaiseException(RPC_X_BAD_STUB_DATA);
427 p = pStubMsg->pfnAllocate(adjusted_len);
428 if (!p) RpcRaiseException(RPC_X_NO_MEMORY);
430 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
431 mem_list->magic = MEML_MAGIC;
432 mem_list->size = aligned_len;
433 mem_list->reserved = 0;
434 mem_list->next = pStubMsg->pMemoryList;
435 pStubMsg->pMemoryList = mem_list;
437 TRACE("-- %p\n", p);
438 return p;
441 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
443 TRACE("(%p, %p)\n", pStubMsg, Pointer);
445 pStubMsg->pfnFree(Pointer);
448 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
450 return (*(const ULONG *)pFormat != -1);
453 static inline PFORMAT_STRING SkipConformance(const PMIDL_STUB_MESSAGE pStubMsg, const PFORMAT_STRING pFormat)
455 return pFormat + 4 + pStubMsg->CorrDespIncrement;
458 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
460 align_pointer(&pStubMsg->Buffer, 4);
461 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
462 RpcRaiseException(RPC_X_BAD_STUB_DATA);
463 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
464 pStubMsg->Buffer += 4;
465 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
466 return SkipConformance(pStubMsg, pFormat);
469 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
471 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
473 pStubMsg->Offset = 0;
474 pStubMsg->ActualCount = pStubMsg->MaxCount;
475 goto done;
478 align_pointer(&pStubMsg->Buffer, 4);
479 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
480 RpcRaiseException(RPC_X_BAD_STUB_DATA);
481 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
482 pStubMsg->Buffer += 4;
483 TRACE("offset is %d\n", pStubMsg->Offset);
484 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
485 pStubMsg->Buffer += 4;
486 TRACE("variance is %d\n", pStubMsg->ActualCount);
488 if ((pStubMsg->ActualCount > MaxValue) ||
489 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
491 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
492 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
493 RpcRaiseException(RPC_S_INVALID_BOUND);
494 return NULL;
497 done:
498 return SkipConformance(pStubMsg, pFormat);
501 /* writes the conformance value to the buffer */
502 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
504 align_pointer_clear(&pStubMsg->Buffer, 4);
505 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
506 RpcRaiseException(RPC_X_BAD_STUB_DATA);
507 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
508 pStubMsg->Buffer += 4;
511 /* writes the variance values to the buffer */
512 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
514 align_pointer_clear(&pStubMsg->Buffer, 4);
515 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
516 RpcRaiseException(RPC_X_BAD_STUB_DATA);
517 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
518 pStubMsg->Buffer += 4;
519 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
520 pStubMsg->Buffer += 4;
523 /* requests buffer space for the conformance value */
524 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
526 align_length(&pStubMsg->BufferLength, 4);
527 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
528 RpcRaiseException(RPC_X_BAD_STUB_DATA);
529 pStubMsg->BufferLength += 4;
532 /* requests buffer space for the variance values */
533 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
535 align_length(&pStubMsg->BufferLength, 4);
536 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
537 RpcRaiseException(RPC_X_BAD_STUB_DATA);
538 pStubMsg->BufferLength += 8;
541 PFORMAT_STRING ComputeConformanceOrVariance(
542 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
543 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
545 BYTE dtype = pFormat[0] & 0xf;
546 short ofs = *(const short *)&pFormat[2];
547 LPVOID ptr = NULL;
548 ULONG_PTR data = 0;
550 if (!IsConformanceOrVariancePresent(pFormat)) {
551 /* null descriptor */
552 *pCount = def;
553 goto finish_conf;
556 switch (pFormat[0] & 0xf0) {
557 case RPC_FC_NORMAL_CONFORMANCE:
558 TRACE("normal conformance, ofs=%d\n", ofs);
559 ptr = pMemory;
560 break;
561 case RPC_FC_POINTER_CONFORMANCE:
562 TRACE("pointer conformance, ofs=%d\n", ofs);
563 ptr = pStubMsg->Memory;
564 break;
565 case RPC_FC_TOP_LEVEL_CONFORMANCE:
566 TRACE("toplevel conformance, ofs=%d\n", ofs);
567 if (pStubMsg->StackTop) {
568 ptr = pStubMsg->StackTop;
570 else {
571 /* -Os mode, *pCount is already set */
572 goto finish_conf;
574 break;
575 case RPC_FC_CONSTANT_CONFORMANCE:
576 data = ofs | ((DWORD)pFormat[1] << 16);
577 TRACE("constant conformance, val=%ld\n", data);
578 *pCount = data;
579 goto finish_conf;
580 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
581 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
582 if (pStubMsg->StackTop) {
583 ptr = pStubMsg->StackTop;
585 else {
586 /* ? */
587 goto done_conf_grab;
589 break;
590 default:
591 FIXME("unknown conformance type %x, expect crash.\n", pFormat[0] & 0xf0);
592 goto finish_conf;
595 switch (pFormat[1]) {
596 case RPC_FC_DEREFERENCE:
597 ptr = *(LPVOID*)((char *)ptr + ofs);
598 break;
599 case RPC_FC_CALLBACK:
601 unsigned char *old_stack_top = pStubMsg->StackTop;
602 ULONG_PTR max_count, old_max_count = pStubMsg->MaxCount;
604 pStubMsg->StackTop = ptr;
606 /* ofs is index into StubDesc->apfnExprEval */
607 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
608 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
610 pStubMsg->StackTop = old_stack_top;
612 /* the callback function always stores the computed value in MaxCount */
613 max_count = pStubMsg->MaxCount;
614 pStubMsg->MaxCount = old_max_count;
615 *pCount = max_count;
616 goto finish_conf;
618 default:
619 ptr = (char *)ptr + ofs;
620 break;
623 switch (dtype) {
624 case RPC_FC_LONG:
625 case RPC_FC_ULONG:
626 data = *(DWORD*)ptr;
627 break;
628 case RPC_FC_SHORT:
629 data = *(SHORT*)ptr;
630 break;
631 case RPC_FC_USHORT:
632 data = *(USHORT*)ptr;
633 break;
634 case RPC_FC_CHAR:
635 case RPC_FC_SMALL:
636 data = *(CHAR*)ptr;
637 break;
638 case RPC_FC_BYTE:
639 case RPC_FC_USMALL:
640 data = *(UCHAR*)ptr;
641 break;
642 case RPC_FC_HYPER:
643 data = *(ULONGLONG *)ptr;
644 break;
645 default:
646 FIXME("unknown conformance data type %x\n", dtype);
647 goto done_conf_grab;
649 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
651 done_conf_grab:
652 switch (pFormat[1]) {
653 case RPC_FC_DEREFERENCE: /* already handled */
654 case 0: /* no op */
655 *pCount = data;
656 break;
657 case RPC_FC_ADD_1:
658 *pCount = data + 1;
659 break;
660 case RPC_FC_SUB_1:
661 *pCount = data - 1;
662 break;
663 case RPC_FC_MULT_2:
664 *pCount = data * 2;
665 break;
666 case RPC_FC_DIV_2:
667 *pCount = data / 2;
668 break;
669 default:
670 FIXME("unknown conformance op %d\n", pFormat[1]);
671 goto finish_conf;
674 finish_conf:
675 TRACE("resulting conformance is %ld\n", *pCount);
677 return SkipConformance(pStubMsg, pFormat);
680 static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
682 return SkipConformance( pStubMsg, pFormat );
685 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
686 * the result overflows 32-bits */
687 static inline ULONG safe_multiply(ULONG a, ULONG b)
689 ULONGLONG ret = (ULONGLONG)a * b;
690 if (ret > 0xffffffff)
692 RpcRaiseException(RPC_S_INVALID_BOUND);
693 return 0;
695 return ret;
698 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
700 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
701 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
702 RpcRaiseException(RPC_X_BAD_STUB_DATA);
703 pStubMsg->Buffer += size;
706 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
708 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
710 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
711 pStubMsg->BufferLength, size);
712 RpcRaiseException(RPC_X_BAD_STUB_DATA);
714 pStubMsg->BufferLength += size;
717 /* copies data from the buffer, checking that there is enough data in the buffer
718 * to do so */
719 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
721 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
722 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
724 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
725 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
726 RpcRaiseException(RPC_X_BAD_STUB_DATA);
728 if (p == pStubMsg->Buffer)
729 ERR("pointer is the same as the buffer\n");
730 memcpy(p, pStubMsg->Buffer, size);
731 pStubMsg->Buffer += size;
734 /* copies data to the buffer, checking that there is enough space to do so */
735 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
737 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
738 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
740 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
741 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
742 size);
743 RpcRaiseException(RPC_X_BAD_STUB_DATA);
745 memcpy(pStubMsg->Buffer, p, size);
746 pStubMsg->Buffer += size;
749 /* verify that string data sitting in the buffer is valid and safe to
750 * unmarshall */
751 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
753 ULONG i;
755 /* verify the buffer is safe to access */
756 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
757 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
759 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
760 pStubMsg->BufferEnd, pStubMsg->Buffer);
761 RpcRaiseException(RPC_X_BAD_STUB_DATA);
764 /* strings must always have null terminating bytes */
765 if (bufsize < esize)
767 ERR("invalid string length of %d\n", bufsize / esize);
768 RpcRaiseException(RPC_S_INVALID_BOUND);
771 for (i = bufsize - esize; i < bufsize; i++)
772 if (pStubMsg->Buffer[i] != 0)
774 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
775 i, pStubMsg->Buffer[i]);
776 RpcRaiseException(RPC_S_INVALID_BOUND);
780 static inline void dump_pointer_attr(unsigned char attr)
782 if (attr & RPC_FC_P_ALLOCALLNODES)
783 TRACE(" RPC_FC_P_ALLOCALLNODES");
784 if (attr & RPC_FC_P_DONTFREE)
785 TRACE(" RPC_FC_P_DONTFREE");
786 if (attr & RPC_FC_P_ONSTACK)
787 TRACE(" RPC_FC_P_ONSTACK");
788 if (attr & RPC_FC_P_SIMPLEPOINTER)
789 TRACE(" RPC_FC_P_SIMPLEPOINTER");
790 if (attr & RPC_FC_P_DEREF)
791 TRACE(" RPC_FC_P_DEREF");
792 TRACE("\n");
795 /***********************************************************************
796 * PointerMarshall [internal]
798 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
799 unsigned char *Buffer,
800 unsigned char *Pointer,
801 PFORMAT_STRING pFormat)
803 unsigned type = pFormat[0], attr = pFormat[1];
804 PFORMAT_STRING desc;
805 NDR_MARSHALL m;
806 ULONG pointer_id;
807 BOOL pointer_needs_marshaling;
809 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
810 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
811 pFormat += 2;
812 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
813 else desc = pFormat + *(const SHORT*)pFormat;
815 switch (type) {
816 case RPC_FC_RP: /* ref pointer (always non-null) */
817 if (!Pointer)
819 ERR("NULL ref pointer is not allowed\n");
820 RpcRaiseException(RPC_X_NULL_REF_POINTER);
822 pointer_needs_marshaling = TRUE;
823 break;
824 case RPC_FC_UP: /* unique pointer */
825 case RPC_FC_OP: /* object pointer - same as unique here */
826 if (Pointer)
827 pointer_needs_marshaling = TRUE;
828 else
829 pointer_needs_marshaling = FALSE;
830 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
831 TRACE("writing 0x%08x to buffer\n", pointer_id);
832 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
833 break;
834 case RPC_FC_FP:
835 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
836 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
837 TRACE("writing 0x%08x to buffer\n", pointer_id);
838 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
839 break;
840 default:
841 FIXME("unhandled ptr type=%02x\n", type);
842 RpcRaiseException(RPC_X_BAD_STUB_DATA);
843 return;
846 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
848 if (pointer_needs_marshaling) {
849 if (attr & RPC_FC_P_DEREF) {
850 Pointer = *(unsigned char**)Pointer;
851 TRACE("deref => %p\n", Pointer);
853 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
854 if (m) m(pStubMsg, Pointer, desc);
855 else FIXME("no marshaller for data type=%02x\n", *desc);
858 STD_OVERFLOW_CHECK(pStubMsg);
861 /***********************************************************************
862 * PointerUnmarshall [internal]
864 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
865 unsigned char *Buffer,
866 unsigned char **pPointer,
867 unsigned char *pSrcPointer,
868 PFORMAT_STRING pFormat,
869 unsigned char fMustAlloc)
871 unsigned type = pFormat[0], attr = pFormat[1];
872 PFORMAT_STRING desc;
873 NDR_UNMARSHALL m;
874 DWORD pointer_id = 0;
875 BOOL pointer_needs_unmarshaling;
877 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
878 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
879 pFormat += 2;
880 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
881 else desc = pFormat + *(const SHORT*)pFormat;
883 switch (type) {
884 case RPC_FC_RP: /* ref pointer (always non-null) */
885 pointer_needs_unmarshaling = TRUE;
886 break;
887 case RPC_FC_UP: /* unique pointer */
888 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
889 TRACE("pointer_id is 0x%08x\n", pointer_id);
890 if (pointer_id)
891 pointer_needs_unmarshaling = TRUE;
892 else {
893 *pPointer = NULL;
894 pointer_needs_unmarshaling = FALSE;
896 break;
897 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
898 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
899 TRACE("pointer_id is 0x%08x\n", pointer_id);
900 if (!fMustAlloc && pSrcPointer)
902 FIXME("free object pointer %p\n", pSrcPointer);
903 fMustAlloc = TRUE;
905 if (pointer_id)
906 pointer_needs_unmarshaling = TRUE;
907 else
909 *pPointer = NULL;
910 pointer_needs_unmarshaling = FALSE;
912 break;
913 case RPC_FC_FP:
914 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
915 TRACE("pointer_id is 0x%08x\n", pointer_id);
916 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
917 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
918 break;
919 default:
920 FIXME("unhandled ptr type=%02x\n", type);
921 RpcRaiseException(RPC_X_BAD_STUB_DATA);
922 return;
925 if (pointer_needs_unmarshaling) {
926 unsigned char **current_ptr = pPointer;
927 if (pStubMsg->IsClient) {
928 TRACE("client\n");
929 /* if we aren't forcing allocation of memory then try to use the existing
930 * (source) pointer to unmarshall the data into so that [in,out]
931 * parameters behave correctly. it doesn't matter if the parameter is
932 * [out] only since in that case the pointer will be NULL. we force
933 * allocation when the source pointer is NULL here instead of in the type
934 * unmarshalling routine for the benefit of the deref code below */
935 if (!fMustAlloc) {
936 if (pSrcPointer) {
937 TRACE("setting *pPointer to %p\n", pSrcPointer);
938 *pPointer = pSrcPointer;
939 } else
940 fMustAlloc = TRUE;
942 } else {
943 TRACE("server\n");
944 /* the memory in a stub is never initialised, so we have to work out here
945 * whether we have to initialise it so we can use the optimisation of
946 * setting the pointer to the buffer, if possible, or set fMustAlloc to
947 * TRUE. */
948 if (attr & RPC_FC_P_DEREF) {
949 fMustAlloc = TRUE;
950 } else {
951 *current_ptr = NULL;
955 if (attr & RPC_FC_P_ALLOCALLNODES)
956 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
958 if (attr & RPC_FC_P_DEREF) {
959 if (fMustAlloc) {
960 unsigned char *base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
961 *pPointer = base_ptr_val;
962 current_ptr = (unsigned char **)base_ptr_val;
963 } else
964 current_ptr = *(unsigned char***)current_ptr;
965 TRACE("deref => %p\n", current_ptr);
966 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
968 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
969 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
970 else FIXME("no unmarshaller for data type=%02x\n", *desc);
972 if (type == RPC_FC_FP)
973 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
974 *pPointer);
977 TRACE("pointer=%p\n", *pPointer);
980 /***********************************************************************
981 * PointerBufferSize [internal]
983 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
984 unsigned char *Pointer,
985 PFORMAT_STRING pFormat)
987 unsigned type = pFormat[0], attr = pFormat[1];
988 PFORMAT_STRING desc;
989 NDR_BUFFERSIZE m;
990 BOOL pointer_needs_sizing;
991 ULONG pointer_id;
993 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
994 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
995 pFormat += 2;
996 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
997 else desc = pFormat + *(const SHORT*)pFormat;
999 switch (type) {
1000 case RPC_FC_RP: /* ref pointer (always non-null) */
1001 if (!Pointer)
1003 ERR("NULL ref pointer is not allowed\n");
1004 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1006 break;
1007 case RPC_FC_OP:
1008 case RPC_FC_UP:
1009 /* NULL pointer has no further representation */
1010 if (!Pointer)
1011 return;
1012 break;
1013 case RPC_FC_FP:
1014 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1015 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1016 if (!pointer_needs_sizing)
1017 return;
1018 break;
1019 default:
1020 FIXME("unhandled ptr type=%02x\n", type);
1021 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1022 return;
1025 if (attr & RPC_FC_P_DEREF) {
1026 Pointer = *(unsigned char**)Pointer;
1027 TRACE("deref => %p\n", Pointer);
1030 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1031 if (m) m(pStubMsg, Pointer, desc);
1032 else FIXME("no buffersizer for data type=%02x\n", *desc);
1035 /***********************************************************************
1036 * PointerMemorySize [internal]
1038 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1039 unsigned char *Buffer, PFORMAT_STRING pFormat)
1041 unsigned type = pFormat[0], attr = pFormat[1];
1042 PFORMAT_STRING desc;
1043 NDR_MEMORYSIZE m;
1044 DWORD pointer_id = 0;
1045 BOOL pointer_needs_sizing;
1047 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1048 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1049 pFormat += 2;
1050 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1051 else desc = pFormat + *(const SHORT*)pFormat;
1053 switch (type) {
1054 case RPC_FC_RP: /* ref pointer (always non-null) */
1055 pointer_needs_sizing = TRUE;
1056 break;
1057 case RPC_FC_UP: /* unique pointer */
1058 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1059 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1060 TRACE("pointer_id is 0x%08x\n", pointer_id);
1061 if (pointer_id)
1062 pointer_needs_sizing = TRUE;
1063 else
1064 pointer_needs_sizing = FALSE;
1065 break;
1066 case RPC_FC_FP:
1068 void *pointer;
1069 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1070 TRACE("pointer_id is 0x%08x\n", pointer_id);
1071 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1072 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1073 break;
1075 default:
1076 FIXME("unhandled ptr type=%02x\n", type);
1077 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1078 return 0;
1081 if (attr & RPC_FC_P_DEREF) {
1082 align_length(&pStubMsg->MemorySize, sizeof(void*));
1083 pStubMsg->MemorySize += sizeof(void*);
1084 TRACE("deref\n");
1087 if (pointer_needs_sizing) {
1088 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1089 if (m) m(pStubMsg, desc);
1090 else FIXME("no memorysizer for data type=%02x\n", *desc);
1093 return pStubMsg->MemorySize;
1096 /***********************************************************************
1097 * PointerFree [internal]
1099 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1100 unsigned char *Pointer,
1101 PFORMAT_STRING pFormat)
1103 unsigned type = pFormat[0], attr = pFormat[1];
1104 PFORMAT_STRING desc;
1105 NDR_FREE m;
1106 unsigned char *current_pointer = Pointer;
1108 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1109 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1110 if (attr & RPC_FC_P_DONTFREE) return;
1111 pFormat += 2;
1112 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1113 else desc = pFormat + *(const SHORT*)pFormat;
1115 if (!Pointer) return;
1117 if (type == RPC_FC_FP) {
1118 int pointer_needs_freeing = NdrFullPointerFree(
1119 pStubMsg->FullPtrXlatTables, Pointer);
1120 if (!pointer_needs_freeing)
1121 return;
1124 if (attr & RPC_FC_P_DEREF) {
1125 current_pointer = *(unsigned char**)Pointer;
1126 TRACE("deref => %p\n", current_pointer);
1129 m = NdrFreer[*desc & NDR_TABLE_MASK];
1130 if (m) m(pStubMsg, current_pointer, desc);
1132 /* this check stops us from trying to free buffer memory. we don't have to
1133 * worry about clients, since they won't call this function.
1134 * we don't have to check for the buffer being reallocated because
1135 * BufferStart and BufferEnd won't be reset when allocating memory for
1136 * sending the response. we don't have to check for the new buffer here as
1137 * it won't be used a type memory, only for buffer memory */
1138 if (Pointer >= pStubMsg->BufferStart && Pointer <= pStubMsg->BufferEnd)
1139 goto notfree;
1141 if (attr & RPC_FC_P_ONSTACK) {
1142 TRACE("not freeing stack ptr %p\n", Pointer);
1143 return;
1145 TRACE("freeing %p\n", Pointer);
1146 NdrFree(pStubMsg, Pointer);
1147 return;
1148 notfree:
1149 TRACE("not freeing %p\n", Pointer);
1152 /***********************************************************************
1153 * EmbeddedPointerMarshall
1155 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1156 unsigned char *pMemory,
1157 PFORMAT_STRING pFormat)
1159 unsigned char *Mark = pStubMsg->BufferMark;
1160 unsigned rep, count, stride;
1161 unsigned i;
1162 unsigned char *saved_buffer = NULL;
1164 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1166 if (*pFormat != RPC_FC_PP) return NULL;
1167 pFormat += 2;
1169 if (pStubMsg->PointerBufferMark)
1171 saved_buffer = pStubMsg->Buffer;
1172 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1173 pStubMsg->PointerBufferMark = NULL;
1176 while (pFormat[0] != RPC_FC_END) {
1177 switch (pFormat[0]) {
1178 default:
1179 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1180 /* fallthrough */
1181 case RPC_FC_NO_REPEAT:
1182 rep = 1;
1183 stride = 0;
1184 count = 1;
1185 pFormat += 2;
1186 break;
1187 case RPC_FC_FIXED_REPEAT:
1188 rep = *(const WORD*)&pFormat[2];
1189 stride = *(const WORD*)&pFormat[4];
1190 count = *(const WORD*)&pFormat[8];
1191 pFormat += 10;
1192 break;
1193 case RPC_FC_VARIABLE_REPEAT:
1194 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1195 stride = *(const WORD*)&pFormat[2];
1196 count = *(const WORD*)&pFormat[6];
1197 pFormat += 8;
1198 break;
1200 for (i = 0; i < rep; i++) {
1201 PFORMAT_STRING info = pFormat;
1202 unsigned char *membase = pMemory + (i * stride);
1203 unsigned char *bufbase = Mark + (i * stride);
1204 unsigned u;
1206 for (u=0; u<count; u++,info+=8) {
1207 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1208 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1209 unsigned char *saved_memory = pStubMsg->Memory;
1211 pStubMsg->Memory = membase;
1212 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1213 pStubMsg->Memory = saved_memory;
1216 pFormat += 8 * count;
1219 if (saved_buffer)
1221 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1222 pStubMsg->Buffer = saved_buffer;
1225 STD_OVERFLOW_CHECK(pStubMsg);
1227 return NULL;
1230 /***********************************************************************
1231 * EmbeddedPointerUnmarshall
1233 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1234 unsigned char *pDstBuffer,
1235 unsigned char *pSrcMemoryPtrs,
1236 PFORMAT_STRING pFormat,
1237 unsigned char fMustAlloc)
1239 unsigned char *Mark = pStubMsg->BufferMark;
1240 unsigned rep, count, stride;
1241 unsigned i;
1242 unsigned char *saved_buffer = NULL;
1244 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1246 if (*pFormat != RPC_FC_PP) return NULL;
1247 pFormat += 2;
1249 if (pStubMsg->PointerBufferMark)
1251 saved_buffer = pStubMsg->Buffer;
1252 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1253 pStubMsg->PointerBufferMark = NULL;
1256 while (pFormat[0] != RPC_FC_END) {
1257 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1258 switch (pFormat[0]) {
1259 default:
1260 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1261 /* fallthrough */
1262 case RPC_FC_NO_REPEAT:
1263 rep = 1;
1264 stride = 0;
1265 count = 1;
1266 pFormat += 2;
1267 break;
1268 case RPC_FC_FIXED_REPEAT:
1269 rep = *(const WORD*)&pFormat[2];
1270 stride = *(const WORD*)&pFormat[4];
1271 count = *(const WORD*)&pFormat[8];
1272 pFormat += 10;
1273 break;
1274 case RPC_FC_VARIABLE_REPEAT:
1275 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1276 stride = *(const WORD*)&pFormat[2];
1277 count = *(const WORD*)&pFormat[6];
1278 pFormat += 8;
1279 break;
1281 for (i = 0; i < rep; i++) {
1282 PFORMAT_STRING info = pFormat;
1283 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1284 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1285 unsigned char *bufbase = Mark + (i * stride);
1286 unsigned u;
1288 for (u=0; u<count; u++,info+=8) {
1289 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1290 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1291 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1292 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1295 pFormat += 8 * count;
1298 if (saved_buffer)
1300 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1301 pStubMsg->Buffer = saved_buffer;
1304 return NULL;
1307 /***********************************************************************
1308 * EmbeddedPointerBufferSize
1310 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1311 unsigned char *pMemory,
1312 PFORMAT_STRING pFormat)
1314 unsigned rep, count, stride;
1315 unsigned i;
1316 ULONG saved_buffer_length = 0;
1318 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1320 if (pStubMsg->IgnoreEmbeddedPointers) return;
1322 if (*pFormat != RPC_FC_PP) return;
1323 pFormat += 2;
1325 if (pStubMsg->PointerLength)
1327 saved_buffer_length = pStubMsg->BufferLength;
1328 pStubMsg->BufferLength = pStubMsg->PointerLength;
1329 pStubMsg->PointerLength = 0;
1332 while (pFormat[0] != RPC_FC_END) {
1333 switch (pFormat[0]) {
1334 default:
1335 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1336 /* fallthrough */
1337 case RPC_FC_NO_REPEAT:
1338 rep = 1;
1339 stride = 0;
1340 count = 1;
1341 pFormat += 2;
1342 break;
1343 case RPC_FC_FIXED_REPEAT:
1344 rep = *(const WORD*)&pFormat[2];
1345 stride = *(const WORD*)&pFormat[4];
1346 count = *(const WORD*)&pFormat[8];
1347 pFormat += 10;
1348 break;
1349 case RPC_FC_VARIABLE_REPEAT:
1350 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1351 stride = *(const WORD*)&pFormat[2];
1352 count = *(const WORD*)&pFormat[6];
1353 pFormat += 8;
1354 break;
1356 for (i = 0; i < rep; i++) {
1357 PFORMAT_STRING info = pFormat;
1358 unsigned char *membase = pMemory + (i * stride);
1359 unsigned u;
1361 for (u=0; u<count; u++,info+=8) {
1362 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1363 unsigned char *saved_memory = pStubMsg->Memory;
1365 pStubMsg->Memory = membase;
1366 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1367 pStubMsg->Memory = saved_memory;
1370 pFormat += 8 * count;
1373 if (saved_buffer_length)
1375 pStubMsg->PointerLength = pStubMsg->BufferLength;
1376 pStubMsg->BufferLength = saved_buffer_length;
1380 /***********************************************************************
1381 * EmbeddedPointerMemorySize [internal]
1383 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1384 PFORMAT_STRING pFormat)
1386 unsigned char *Mark = pStubMsg->BufferMark;
1387 unsigned rep, count, stride;
1388 unsigned i;
1389 unsigned char *saved_buffer = NULL;
1391 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1393 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1395 if (pStubMsg->PointerBufferMark)
1397 saved_buffer = pStubMsg->Buffer;
1398 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1399 pStubMsg->PointerBufferMark = NULL;
1402 if (*pFormat != RPC_FC_PP) return 0;
1403 pFormat += 2;
1405 while (pFormat[0] != RPC_FC_END) {
1406 switch (pFormat[0]) {
1407 default:
1408 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1409 /* fallthrough */
1410 case RPC_FC_NO_REPEAT:
1411 rep = 1;
1412 stride = 0;
1413 count = 1;
1414 pFormat += 2;
1415 break;
1416 case RPC_FC_FIXED_REPEAT:
1417 rep = *(const WORD*)&pFormat[2];
1418 stride = *(const WORD*)&pFormat[4];
1419 count = *(const WORD*)&pFormat[8];
1420 pFormat += 10;
1421 break;
1422 case RPC_FC_VARIABLE_REPEAT:
1423 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1424 stride = *(const WORD*)&pFormat[2];
1425 count = *(const WORD*)&pFormat[6];
1426 pFormat += 8;
1427 break;
1429 for (i = 0; i < rep; i++) {
1430 PFORMAT_STRING info = pFormat;
1431 unsigned char *bufbase = Mark + (i * stride);
1432 unsigned u;
1433 for (u=0; u<count; u++,info+=8) {
1434 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1435 PointerMemorySize(pStubMsg, bufptr, info+4);
1438 pFormat += 8 * count;
1441 if (saved_buffer)
1443 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1444 pStubMsg->Buffer = saved_buffer;
1447 return 0;
1450 /***********************************************************************
1451 * EmbeddedPointerFree [internal]
1453 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1454 unsigned char *pMemory,
1455 PFORMAT_STRING pFormat)
1457 unsigned rep, count, stride;
1458 unsigned i;
1460 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1461 if (*pFormat != RPC_FC_PP) return;
1462 pFormat += 2;
1464 while (pFormat[0] != RPC_FC_END) {
1465 switch (pFormat[0]) {
1466 default:
1467 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat[0]);
1468 /* fallthrough */
1469 case RPC_FC_NO_REPEAT:
1470 rep = 1;
1471 stride = 0;
1472 count = 1;
1473 pFormat += 2;
1474 break;
1475 case RPC_FC_FIXED_REPEAT:
1476 rep = *(const WORD*)&pFormat[2];
1477 stride = *(const WORD*)&pFormat[4];
1478 count = *(const WORD*)&pFormat[8];
1479 pFormat += 10;
1480 break;
1481 case RPC_FC_VARIABLE_REPEAT:
1482 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1483 stride = *(const WORD*)&pFormat[2];
1484 count = *(const WORD*)&pFormat[6];
1485 pFormat += 8;
1486 break;
1488 for (i = 0; i < rep; i++) {
1489 PFORMAT_STRING info = pFormat;
1490 unsigned char *membase = pMemory + (i * stride);
1491 unsigned u;
1493 for (u=0; u<count; u++,info+=8) {
1494 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1495 unsigned char *saved_memory = pStubMsg->Memory;
1497 pStubMsg->Memory = membase;
1498 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1499 pStubMsg->Memory = saved_memory;
1502 pFormat += 8 * count;
1506 /***********************************************************************
1507 * NdrPointerMarshall [RPCRT4.@]
1509 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1510 unsigned char *pMemory,
1511 PFORMAT_STRING pFormat)
1513 unsigned char *Buffer;
1515 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1517 /* Increment the buffer here instead of in PointerMarshall,
1518 * as that is used by embedded pointers which already handle the incrementing
1519 * the buffer, and shouldn't write any additional pointer data to the wire */
1520 if (*pFormat != RPC_FC_RP)
1522 align_pointer_clear(&pStubMsg->Buffer, 4);
1523 Buffer = pStubMsg->Buffer;
1524 safe_buffer_increment(pStubMsg, 4);
1526 else
1527 Buffer = pStubMsg->Buffer;
1529 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1531 return NULL;
1534 /***********************************************************************
1535 * NdrPointerUnmarshall [RPCRT4.@]
1537 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1538 unsigned char **ppMemory,
1539 PFORMAT_STRING pFormat,
1540 unsigned char fMustAlloc)
1542 unsigned char *Buffer;
1544 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1546 if (*pFormat == RPC_FC_RP)
1548 Buffer = pStubMsg->Buffer;
1549 /* Do the NULL ref pointer check here because embedded pointers can be
1550 * NULL if the type the pointer is embedded in was allocated rather than
1551 * being passed in by the client */
1552 if (pStubMsg->IsClient && !*ppMemory)
1554 ERR("NULL ref pointer is not allowed\n");
1555 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1558 else
1560 /* Increment the buffer here instead of in PointerUnmarshall,
1561 * as that is used by embedded pointers which already handle the incrementing
1562 * the buffer, and shouldn't read any additional pointer data from the
1563 * buffer */
1564 align_pointer(&pStubMsg->Buffer, 4);
1565 Buffer = pStubMsg->Buffer;
1566 safe_buffer_increment(pStubMsg, 4);
1569 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1571 return NULL;
1574 /***********************************************************************
1575 * NdrPointerBufferSize [RPCRT4.@]
1577 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1578 unsigned char *pMemory,
1579 PFORMAT_STRING pFormat)
1581 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1583 /* Increment the buffer length here instead of in PointerBufferSize,
1584 * as that is used by embedded pointers which already handle the buffer
1585 * length, and shouldn't write anything more to the wire */
1586 if (*pFormat != RPC_FC_RP)
1588 align_length(&pStubMsg->BufferLength, 4);
1589 safe_buffer_length_increment(pStubMsg, 4);
1592 PointerBufferSize(pStubMsg, pMemory, pFormat);
1595 /***********************************************************************
1596 * NdrPointerMemorySize [RPCRT4.@]
1598 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1599 PFORMAT_STRING pFormat)
1601 unsigned char *Buffer = pStubMsg->Buffer;
1602 if (*pFormat != RPC_FC_RP)
1604 align_pointer(&pStubMsg->Buffer, 4);
1605 safe_buffer_increment(pStubMsg, 4);
1607 align_length(&pStubMsg->MemorySize, sizeof(void *));
1608 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1611 /***********************************************************************
1612 * NdrPointerFree [RPCRT4.@]
1614 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1615 unsigned char *pMemory,
1616 PFORMAT_STRING pFormat)
1618 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1619 PointerFree(pStubMsg, pMemory, pFormat);
1622 /***********************************************************************
1623 * NdrSimpleTypeMarshall [RPCRT4.@]
1625 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1626 unsigned char FormatChar )
1628 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1631 /***********************************************************************
1632 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1634 * Unmarshall a base type.
1636 * NOTES
1637 * Doesn't check that the buffer is long enough before copying, so the caller
1638 * should do this.
1640 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1641 unsigned char FormatChar )
1643 #define BASE_TYPE_UNMARSHALL(type) \
1644 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1645 TRACE("pMemory: %p\n", pMemory); \
1646 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1647 pStubMsg->Buffer += sizeof(type);
1649 switch(FormatChar)
1651 case RPC_FC_BYTE:
1652 case RPC_FC_CHAR:
1653 case RPC_FC_SMALL:
1654 case RPC_FC_USMALL:
1655 BASE_TYPE_UNMARSHALL(UCHAR);
1656 TRACE("value: 0x%02x\n", *pMemory);
1657 break;
1658 case RPC_FC_WCHAR:
1659 case RPC_FC_SHORT:
1660 case RPC_FC_USHORT:
1661 BASE_TYPE_UNMARSHALL(USHORT);
1662 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1663 break;
1664 case RPC_FC_LONG:
1665 case RPC_FC_ULONG:
1666 case RPC_FC_ERROR_STATUS_T:
1667 case RPC_FC_ENUM32:
1668 BASE_TYPE_UNMARSHALL(ULONG);
1669 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1670 break;
1671 case RPC_FC_FLOAT:
1672 BASE_TYPE_UNMARSHALL(float);
1673 TRACE("value: %f\n", *(float *)pMemory);
1674 break;
1675 case RPC_FC_DOUBLE:
1676 BASE_TYPE_UNMARSHALL(double);
1677 TRACE("value: %f\n", *(double *)pMemory);
1678 break;
1679 case RPC_FC_HYPER:
1680 BASE_TYPE_UNMARSHALL(ULONGLONG);
1681 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1682 break;
1683 case RPC_FC_ENUM16:
1684 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
1685 TRACE("pMemory: %p\n", pMemory);
1686 /* 16-bits on the wire, but int in memory */
1687 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1688 pStubMsg->Buffer += sizeof(USHORT);
1689 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1690 break;
1691 case RPC_FC_INT3264:
1692 align_pointer(&pStubMsg->Buffer, sizeof(INT));
1693 /* 32-bits on the wire, but int_ptr in memory */
1694 *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer;
1695 pStubMsg->Buffer += sizeof(INT);
1696 TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory);
1697 break;
1698 case RPC_FC_UINT3264:
1699 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
1700 /* 32-bits on the wire, but int_ptr in memory */
1701 *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer;
1702 pStubMsg->Buffer += sizeof(UINT);
1703 TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory);
1704 break;
1705 case RPC_FC_IGNORE:
1706 break;
1707 default:
1708 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1710 #undef BASE_TYPE_UNMARSHALL
1713 /***********************************************************************
1714 * NdrSimpleStructMarshall [RPCRT4.@]
1716 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1717 unsigned char *pMemory,
1718 PFORMAT_STRING pFormat)
1720 unsigned size = *(const WORD*)(pFormat+2);
1721 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1723 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
1725 pStubMsg->BufferMark = pStubMsg->Buffer;
1726 safe_copy_to_buffer(pStubMsg, pMemory, size);
1728 if (pFormat[0] != RPC_FC_STRUCT)
1729 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1731 return NULL;
1734 /***********************************************************************
1735 * NdrSimpleStructUnmarshall [RPCRT4.@]
1737 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1738 unsigned char **ppMemory,
1739 PFORMAT_STRING pFormat,
1740 unsigned char fMustAlloc)
1742 unsigned size = *(const WORD*)(pFormat+2);
1743 unsigned char *saved_buffer;
1744 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1746 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1748 if (fMustAlloc)
1749 *ppMemory = NdrAllocate(pStubMsg, size);
1750 else
1752 if (!pStubMsg->IsClient && !*ppMemory)
1753 /* for servers, we just point straight into the RPC buffer */
1754 *ppMemory = pStubMsg->Buffer;
1757 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1758 safe_buffer_increment(pStubMsg, size);
1759 if (pFormat[0] == RPC_FC_PSTRUCT)
1760 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1762 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1763 if (*ppMemory != saved_buffer)
1764 memcpy(*ppMemory, saved_buffer, size);
1766 return NULL;
1769 /***********************************************************************
1770 * NdrSimpleStructBufferSize [RPCRT4.@]
1772 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1773 unsigned char *pMemory,
1774 PFORMAT_STRING pFormat)
1776 unsigned size = *(const WORD*)(pFormat+2);
1777 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1779 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
1781 safe_buffer_length_increment(pStubMsg, size);
1782 if (pFormat[0] != RPC_FC_STRUCT)
1783 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1786 /***********************************************************************
1787 * NdrSimpleStructMemorySize [RPCRT4.@]
1789 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1790 PFORMAT_STRING pFormat)
1792 unsigned short size = *(const WORD *)(pFormat+2);
1794 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1796 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
1797 pStubMsg->MemorySize += size;
1798 safe_buffer_increment(pStubMsg, size);
1800 if (pFormat[0] != RPC_FC_STRUCT)
1801 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1802 return pStubMsg->MemorySize;
1805 /***********************************************************************
1806 * NdrSimpleStructFree [RPCRT4.@]
1808 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1809 unsigned char *pMemory,
1810 PFORMAT_STRING pFormat)
1812 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1813 if (pFormat[0] != RPC_FC_STRUCT)
1814 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1817 /* Array helpers */
1819 static inline void array_compute_and_size_conformance(
1820 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1821 PFORMAT_STRING pFormat)
1823 DWORD count;
1825 switch (fc)
1827 case RPC_FC_CARRAY:
1828 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1829 SizeConformance(pStubMsg);
1830 break;
1831 case RPC_FC_CVARRAY:
1832 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1833 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1834 SizeConformance(pStubMsg);
1835 break;
1836 case RPC_FC_C_CSTRING:
1837 case RPC_FC_C_WSTRING:
1838 if (fc == RPC_FC_C_CSTRING)
1840 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1841 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1843 else
1845 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1846 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1849 if (pFormat[1] == RPC_FC_STRING_SIZED)
1850 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1851 else
1852 pStubMsg->MaxCount = pStubMsg->ActualCount;
1854 SizeConformance(pStubMsg);
1855 break;
1856 case RPC_FC_BOGUS_ARRAY:
1857 count = *(const WORD *)(pFormat + 2);
1858 pFormat += 4;
1859 if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg);
1860 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count);
1861 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1862 break;
1863 default:
1864 ERR("unknown array format 0x%x\n", fc);
1865 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1869 static inline void array_buffer_size(
1870 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1871 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1873 DWORD i, size;
1874 DWORD esize;
1875 unsigned char alignment;
1877 switch (fc)
1879 case RPC_FC_CARRAY:
1880 esize = *(const WORD*)(pFormat+2);
1881 alignment = pFormat[1] + 1;
1883 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1885 align_length(&pStubMsg->BufferLength, alignment);
1887 size = safe_multiply(esize, pStubMsg->MaxCount);
1888 /* conformance value plus array */
1889 safe_buffer_length_increment(pStubMsg, size);
1891 if (fHasPointers)
1892 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1893 break;
1894 case RPC_FC_CVARRAY:
1895 esize = *(const WORD*)(pFormat+2);
1896 alignment = pFormat[1] + 1;
1898 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1899 pFormat = SkipVariance(pStubMsg, pFormat);
1901 SizeVariance(pStubMsg);
1903 align_length(&pStubMsg->BufferLength, alignment);
1905 size = safe_multiply(esize, pStubMsg->ActualCount);
1906 safe_buffer_length_increment(pStubMsg, size);
1908 if (fHasPointers)
1909 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1910 break;
1911 case RPC_FC_C_CSTRING:
1912 case RPC_FC_C_WSTRING:
1913 if (fc == RPC_FC_C_CSTRING)
1914 esize = 1;
1915 else
1916 esize = 2;
1918 SizeVariance(pStubMsg);
1920 size = safe_multiply(esize, pStubMsg->ActualCount);
1921 safe_buffer_length_increment(pStubMsg, size);
1922 break;
1923 case RPC_FC_BOGUS_ARRAY:
1924 alignment = pFormat[1] + 1;
1925 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1926 if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg);
1927 pFormat = SkipVariance(pStubMsg, pFormat);
1929 align_length(&pStubMsg->BufferLength, alignment);
1931 size = pStubMsg->ActualCount;
1932 for (i = 0; i < size; i++)
1933 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1934 break;
1935 default:
1936 ERR("unknown array format 0x%x\n", fc);
1937 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1941 static inline void array_compute_and_write_conformance(
1942 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1943 PFORMAT_STRING pFormat)
1945 ULONG def;
1946 BOOL conformance_present;
1948 switch (fc)
1950 case RPC_FC_CARRAY:
1951 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1952 WriteConformance(pStubMsg);
1953 break;
1954 case RPC_FC_CVARRAY:
1955 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1956 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1957 WriteConformance(pStubMsg);
1958 break;
1959 case RPC_FC_C_CSTRING:
1960 case RPC_FC_C_WSTRING:
1961 if (fc == RPC_FC_C_CSTRING)
1963 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1964 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1966 else
1968 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1969 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1971 if (pFormat[1] == RPC_FC_STRING_SIZED)
1972 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1973 else
1974 pStubMsg->MaxCount = pStubMsg->ActualCount;
1975 pStubMsg->Offset = 0;
1976 WriteConformance(pStubMsg);
1977 break;
1978 case RPC_FC_BOGUS_ARRAY:
1979 def = *(const WORD *)(pFormat + 2);
1980 pFormat += 4;
1981 conformance_present = IsConformanceOrVariancePresent(pFormat);
1982 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1983 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
1984 if (conformance_present) WriteConformance(pStubMsg);
1985 break;
1986 default:
1987 ERR("unknown array format 0x%x\n", fc);
1988 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1992 static inline void array_write_variance_and_marshall(
1993 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1994 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1996 DWORD i, size;
1997 DWORD esize;
1998 unsigned char alignment;
2000 switch (fc)
2002 case RPC_FC_CARRAY:
2003 esize = *(const WORD*)(pFormat+2);
2004 alignment = pFormat[1] + 1;
2006 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2008 align_pointer_clear(&pStubMsg->Buffer, alignment);
2010 size = safe_multiply(esize, pStubMsg->MaxCount);
2011 if (fHasPointers)
2012 pStubMsg->BufferMark = pStubMsg->Buffer;
2013 safe_copy_to_buffer(pStubMsg, pMemory, size);
2015 if (fHasPointers)
2016 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2017 break;
2018 case RPC_FC_CVARRAY:
2019 esize = *(const WORD*)(pFormat+2);
2020 alignment = pFormat[1] + 1;
2022 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2023 pFormat = SkipVariance(pStubMsg, pFormat);
2025 WriteVariance(pStubMsg);
2027 align_pointer_clear(&pStubMsg->Buffer, alignment);
2029 size = safe_multiply(esize, pStubMsg->ActualCount);
2031 if (fHasPointers)
2032 pStubMsg->BufferMark = pStubMsg->Buffer;
2033 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
2035 if (fHasPointers)
2036 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2037 break;
2038 case RPC_FC_C_CSTRING:
2039 case RPC_FC_C_WSTRING:
2040 if (fc == RPC_FC_C_CSTRING)
2041 esize = 1;
2042 else
2043 esize = 2;
2045 WriteVariance(pStubMsg);
2047 size = safe_multiply(esize, pStubMsg->ActualCount);
2048 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2049 break;
2050 case RPC_FC_BOGUS_ARRAY:
2051 alignment = pFormat[1] + 1;
2052 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2053 if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg);
2054 pFormat = SkipVariance(pStubMsg, pFormat);
2056 align_pointer_clear(&pStubMsg->Buffer, alignment);
2058 size = pStubMsg->ActualCount;
2059 for (i = 0; i < size; i++)
2060 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2061 break;
2062 default:
2063 ERR("unknown array format 0x%x\n", fc);
2064 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2068 static inline ULONG array_read_conformance(
2069 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
2071 DWORD def, esize;
2073 switch (fc)
2075 case RPC_FC_CARRAY:
2076 esize = *(const WORD*)(pFormat+2);
2077 pFormat = ReadConformance(pStubMsg, pFormat+4);
2078 return safe_multiply(esize, pStubMsg->MaxCount);
2079 case RPC_FC_CVARRAY:
2080 esize = *(const WORD*)(pFormat+2);
2081 pFormat = ReadConformance(pStubMsg, pFormat+4);
2082 return safe_multiply(esize, pStubMsg->MaxCount);
2083 case RPC_FC_C_CSTRING:
2084 case RPC_FC_C_WSTRING:
2085 if (fc == RPC_FC_C_CSTRING)
2086 esize = 1;
2087 else
2088 esize = 2;
2090 if (pFormat[1] == RPC_FC_STRING_SIZED)
2091 ReadConformance(pStubMsg, pFormat + 2);
2092 else
2093 ReadConformance(pStubMsg, NULL);
2094 return safe_multiply(esize, pStubMsg->MaxCount);
2095 case RPC_FC_BOGUS_ARRAY:
2096 def = *(const WORD *)(pFormat + 2);
2097 pFormat += 4;
2098 if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
2099 else
2101 pStubMsg->MaxCount = def;
2102 pFormat = SkipConformance( pStubMsg, pFormat );
2104 pFormat = SkipVariance( pStubMsg, pFormat );
2106 esize = ComplexStructSize(pStubMsg, pFormat);
2107 return safe_multiply(pStubMsg->MaxCount, esize);
2108 default:
2109 ERR("unknown array format 0x%x\n", fc);
2110 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2114 static inline ULONG array_read_variance_and_unmarshall(
2115 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2116 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2117 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2119 ULONG bufsize, memsize;
2120 WORD esize;
2121 unsigned char alignment;
2122 unsigned char *saved_buffer, *pMemory;
2123 ULONG i, offset, count;
2125 switch (fc)
2127 case RPC_FC_CARRAY:
2128 esize = *(const WORD*)(pFormat+2);
2129 alignment = pFormat[1] + 1;
2131 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2133 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2135 align_pointer(&pStubMsg->Buffer, alignment);
2137 if (fUnmarshall)
2139 if (fMustAlloc)
2140 *ppMemory = NdrAllocate(pStubMsg, memsize);
2141 else
2143 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2144 /* for servers, we just point straight into the RPC buffer */
2145 *ppMemory = pStubMsg->Buffer;
2148 saved_buffer = pStubMsg->Buffer;
2149 safe_buffer_increment(pStubMsg, bufsize);
2151 pStubMsg->BufferMark = saved_buffer;
2152 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2154 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2155 if (*ppMemory != saved_buffer)
2156 memcpy(*ppMemory, saved_buffer, bufsize);
2158 return bufsize;
2159 case RPC_FC_CVARRAY:
2160 esize = *(const WORD*)(pFormat+2);
2161 alignment = pFormat[1] + 1;
2163 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2165 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2167 align_pointer(&pStubMsg->Buffer, alignment);
2169 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2170 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2172 if (fUnmarshall)
2174 offset = pStubMsg->Offset;
2176 if (!fMustAlloc && !*ppMemory)
2177 fMustAlloc = TRUE;
2178 if (fMustAlloc)
2179 *ppMemory = NdrAllocate(pStubMsg, memsize);
2180 saved_buffer = pStubMsg->Buffer;
2181 safe_buffer_increment(pStubMsg, bufsize);
2183 pStubMsg->BufferMark = saved_buffer;
2184 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2185 fMustAlloc);
2187 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2189 return bufsize;
2190 case RPC_FC_C_CSTRING:
2191 case RPC_FC_C_WSTRING:
2192 if (fc == RPC_FC_C_CSTRING)
2193 esize = 1;
2194 else
2195 esize = 2;
2197 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2199 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2201 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2202 pStubMsg->ActualCount, pStubMsg->MaxCount);
2203 RpcRaiseException(RPC_S_INVALID_BOUND);
2205 if (pStubMsg->Offset)
2207 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2208 RpcRaiseException(RPC_S_INVALID_BOUND);
2211 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2212 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2214 validate_string_data(pStubMsg, bufsize, esize);
2216 if (fUnmarshall)
2218 if (fMustAlloc)
2219 *ppMemory = NdrAllocate(pStubMsg, memsize);
2220 else
2222 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2223 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2224 /* if the data in the RPC buffer is big enough, we just point
2225 * straight into it */
2226 *ppMemory = pStubMsg->Buffer;
2227 else if (!*ppMemory)
2228 *ppMemory = NdrAllocate(pStubMsg, memsize);
2231 if (*ppMemory == pStubMsg->Buffer)
2232 safe_buffer_increment(pStubMsg, bufsize);
2233 else
2234 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2236 if (*pFormat == RPC_FC_C_CSTRING)
2237 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2238 else
2239 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2241 return bufsize;
2243 case RPC_FC_BOGUS_ARRAY:
2244 alignment = pFormat[1] + 1;
2245 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2246 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2248 esize = ComplexStructSize(pStubMsg, pFormat);
2249 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2251 assert( fUnmarshall );
2253 if (!fMustAlloc && !*ppMemory)
2254 fMustAlloc = TRUE;
2255 if (fMustAlloc)
2256 *ppMemory = NdrAllocate(pStubMsg, memsize);
2258 align_pointer(&pStubMsg->Buffer, alignment);
2259 saved_buffer = pStubMsg->Buffer;
2261 pMemory = *ppMemory;
2262 count = pStubMsg->ActualCount;
2263 for (i = 0; i < count; i++)
2264 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2265 return pStubMsg->Buffer - saved_buffer;
2267 default:
2268 ERR("unknown array format 0x%x\n", fc);
2269 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2273 static inline void array_memory_size(
2274 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2275 unsigned char fHasPointers)
2277 ULONG i, count, SavedMemorySize;
2278 ULONG bufsize, memsize;
2279 DWORD esize;
2280 unsigned char alignment;
2282 switch (fc)
2284 case RPC_FC_CARRAY:
2285 esize = *(const WORD*)(pFormat+2);
2286 alignment = pFormat[1] + 1;
2288 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2290 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2291 pStubMsg->MemorySize += memsize;
2293 align_pointer(&pStubMsg->Buffer, alignment);
2294 if (fHasPointers)
2295 pStubMsg->BufferMark = pStubMsg->Buffer;
2296 safe_buffer_increment(pStubMsg, bufsize);
2298 if (fHasPointers)
2299 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2300 break;
2301 case RPC_FC_CVARRAY:
2302 esize = *(const WORD*)(pFormat+2);
2303 alignment = pFormat[1] + 1;
2305 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2307 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2309 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2310 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2311 pStubMsg->MemorySize += memsize;
2313 align_pointer(&pStubMsg->Buffer, alignment);
2314 if (fHasPointers)
2315 pStubMsg->BufferMark = pStubMsg->Buffer;
2316 safe_buffer_increment(pStubMsg, bufsize);
2318 if (fHasPointers)
2319 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2320 break;
2321 case RPC_FC_C_CSTRING:
2322 case RPC_FC_C_WSTRING:
2323 if (fc == RPC_FC_C_CSTRING)
2324 esize = 1;
2325 else
2326 esize = 2;
2328 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2330 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2332 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2333 pStubMsg->ActualCount, pStubMsg->MaxCount);
2334 RpcRaiseException(RPC_S_INVALID_BOUND);
2336 if (pStubMsg->Offset)
2338 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2339 RpcRaiseException(RPC_S_INVALID_BOUND);
2342 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2343 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2345 validate_string_data(pStubMsg, bufsize, esize);
2347 safe_buffer_increment(pStubMsg, bufsize);
2348 pStubMsg->MemorySize += memsize;
2349 break;
2350 case RPC_FC_BOGUS_ARRAY:
2351 alignment = pFormat[1] + 1;
2352 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2353 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2355 align_pointer(&pStubMsg->Buffer, alignment);
2357 SavedMemorySize = pStubMsg->MemorySize;
2359 esize = ComplexStructSize(pStubMsg, pFormat);
2360 memsize = safe_multiply(pStubMsg->MaxCount, esize);
2362 count = pStubMsg->ActualCount;
2363 for (i = 0; i < count; i++)
2364 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
2366 pStubMsg->MemorySize = SavedMemorySize + memsize;
2367 break;
2368 default:
2369 ERR("unknown array format 0x%x\n", fc);
2370 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2374 static inline void array_free(
2375 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2376 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2378 DWORD i, count;
2380 switch (fc)
2382 case RPC_FC_CARRAY:
2383 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2384 if (fHasPointers)
2385 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2386 break;
2387 case RPC_FC_CVARRAY:
2388 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2389 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2390 if (fHasPointers)
2391 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2392 break;
2393 case RPC_FC_C_CSTRING:
2394 case RPC_FC_C_WSTRING:
2395 /* No embedded pointers so nothing to do */
2396 break;
2397 case RPC_FC_BOGUS_ARRAY:
2398 count = *(const WORD *)(pFormat + 2);
2399 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
2400 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2402 count = pStubMsg->ActualCount;
2403 for (i = 0; i < count; i++)
2404 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2405 break;
2406 default:
2407 ERR("unknown array format 0x%x\n", fc);
2408 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2413 * NdrConformantString:
2415 * What MS calls a ConformantString is, in DCE terminology,
2416 * a Varying-Conformant String.
2418 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2419 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2420 * into unmarshalled string)
2421 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2423 * data: CHARTYPE[maxlen]
2425 * ], where CHARTYPE is the appropriate character type (specified externally)
2429 /***********************************************************************
2430 * NdrConformantStringMarshall [RPCRT4.@]
2432 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2433 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2435 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2437 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2438 ERR("Unhandled string type: %#x\n", pFormat[0]);
2439 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2442 /* allow compiler to optimise inline function by passing constant into
2443 * these functions */
2444 if (pFormat[0] == RPC_FC_C_CSTRING) {
2445 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2446 pFormat);
2447 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2448 pFormat, TRUE /* fHasPointers */);
2449 } else {
2450 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2451 pFormat);
2452 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2453 pFormat, TRUE /* fHasPointers */);
2456 return NULL;
2459 /***********************************************************************
2460 * NdrConformantStringBufferSize [RPCRT4.@]
2462 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2463 unsigned char* pMemory, PFORMAT_STRING pFormat)
2465 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2467 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2468 ERR("Unhandled string type: %#x\n", pFormat[0]);
2469 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2472 /* allow compiler to optimise inline function by passing constant into
2473 * these functions */
2474 if (pFormat[0] == RPC_FC_C_CSTRING) {
2475 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2476 pFormat);
2477 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2478 TRUE /* fHasPointers */);
2479 } else {
2480 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2481 pFormat);
2482 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2483 TRUE /* fHasPointers */);
2487 /************************************************************************
2488 * NdrConformantStringMemorySize [RPCRT4.@]
2490 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2491 PFORMAT_STRING pFormat )
2493 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2495 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2496 ERR("Unhandled string type: %#x\n", pFormat[0]);
2497 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2500 /* allow compiler to optimise inline function by passing constant into
2501 * these functions */
2502 if (pFormat[0] == RPC_FC_C_CSTRING) {
2503 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2504 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2505 TRUE /* fHasPointers */);
2506 } else {
2507 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2508 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2509 TRUE /* fHasPointers */);
2512 return pStubMsg->MemorySize;
2515 /************************************************************************
2516 * NdrConformantStringUnmarshall [RPCRT4.@]
2518 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2519 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2521 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2522 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2524 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2525 ERR("Unhandled string type: %#x\n", *pFormat);
2526 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2529 /* allow compiler to optimise inline function by passing constant into
2530 * these functions */
2531 if (pFormat[0] == RPC_FC_C_CSTRING) {
2532 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2533 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2534 pFormat, fMustAlloc,
2535 TRUE /* fUseBufferMemoryServer */,
2536 TRUE /* fUnmarshall */);
2537 } else {
2538 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2539 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2540 pFormat, fMustAlloc,
2541 TRUE /* fUseBufferMemoryServer */,
2542 TRUE /* fUnmarshall */);
2545 return NULL;
2548 /***********************************************************************
2549 * NdrNonConformantStringMarshall [RPCRT4.@]
2551 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2552 unsigned char *pMemory,
2553 PFORMAT_STRING pFormat)
2555 ULONG esize, size, maxsize;
2557 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2559 maxsize = *(const USHORT *)&pFormat[2];
2561 if (*pFormat == RPC_FC_CSTRING)
2563 ULONG i = 0;
2564 const char *str = (const char *)pMemory;
2565 while (i < maxsize && str[i]) i++;
2566 TRACE("string=%s\n", debugstr_an(str, i));
2567 pStubMsg->ActualCount = i + 1;
2568 esize = 1;
2570 else if (*pFormat == RPC_FC_WSTRING)
2572 ULONG i = 0;
2573 const WCHAR *str = (const WCHAR *)pMemory;
2574 while (i < maxsize && str[i]) i++;
2575 TRACE("string=%s\n", debugstr_wn(str, i));
2576 pStubMsg->ActualCount = i + 1;
2577 esize = 2;
2579 else
2581 ERR("Unhandled string type: %#x\n", *pFormat);
2582 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2585 pStubMsg->Offset = 0;
2586 WriteVariance(pStubMsg);
2588 size = safe_multiply(esize, pStubMsg->ActualCount);
2589 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2591 return NULL;
2594 /***********************************************************************
2595 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2597 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2598 unsigned char **ppMemory,
2599 PFORMAT_STRING pFormat,
2600 unsigned char fMustAlloc)
2602 ULONG bufsize, memsize, esize, maxsize;
2604 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2605 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2607 maxsize = *(const USHORT *)&pFormat[2];
2609 ReadVariance(pStubMsg, NULL, maxsize);
2610 if (pStubMsg->Offset)
2612 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2613 RpcRaiseException(RPC_S_INVALID_BOUND);
2616 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2617 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2618 else
2620 ERR("Unhandled string type: %#x\n", *pFormat);
2621 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2624 memsize = esize * maxsize;
2625 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2627 validate_string_data(pStubMsg, bufsize, esize);
2629 if (!fMustAlloc && !*ppMemory)
2630 fMustAlloc = TRUE;
2631 if (fMustAlloc)
2632 *ppMemory = NdrAllocate(pStubMsg, memsize);
2634 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2636 if (*pFormat == RPC_FC_CSTRING) {
2637 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2639 else if (*pFormat == RPC_FC_WSTRING) {
2640 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2643 return NULL;
2646 /***********************************************************************
2647 * NdrNonConformantStringBufferSize [RPCRT4.@]
2649 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2650 unsigned char *pMemory,
2651 PFORMAT_STRING pFormat)
2653 ULONG esize, maxsize;
2655 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2657 maxsize = *(const USHORT *)&pFormat[2];
2659 SizeVariance(pStubMsg);
2661 if (*pFormat == RPC_FC_CSTRING)
2663 ULONG i = 0;
2664 const char *str = (const char *)pMemory;
2665 while (i < maxsize && str[i]) i++;
2666 TRACE("string=%s\n", debugstr_an(str, i));
2667 pStubMsg->ActualCount = i + 1;
2668 esize = 1;
2670 else if (*pFormat == RPC_FC_WSTRING)
2672 ULONG i = 0;
2673 const WCHAR *str = (const WCHAR *)pMemory;
2674 while (i < maxsize && str[i]) i++;
2675 TRACE("string=%s\n", debugstr_wn(str, i));
2676 pStubMsg->ActualCount = i + 1;
2677 esize = 2;
2679 else
2681 ERR("Unhandled string type: %#x\n", *pFormat);
2682 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2685 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2688 /***********************************************************************
2689 * NdrNonConformantStringMemorySize [RPCRT4.@]
2691 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2692 PFORMAT_STRING pFormat)
2694 ULONG bufsize, memsize, esize, maxsize;
2696 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2698 maxsize = *(const USHORT *)&pFormat[2];
2700 ReadVariance(pStubMsg, NULL, maxsize);
2702 if (pStubMsg->Offset)
2704 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2705 RpcRaiseException(RPC_S_INVALID_BOUND);
2708 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2709 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2710 else
2712 ERR("Unhandled string type: %#x\n", *pFormat);
2713 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2716 memsize = esize * maxsize;
2717 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2719 validate_string_data(pStubMsg, bufsize, esize);
2721 safe_buffer_increment(pStubMsg, bufsize);
2722 pStubMsg->MemorySize += memsize;
2724 return pStubMsg->MemorySize;
2727 /* Complex types */
2729 #include "pshpack1.h"
2730 typedef struct
2732 unsigned char type;
2733 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2734 ULONG low_value;
2735 ULONG high_value;
2736 } NDR_RANGE;
2737 #include "poppack.h"
2739 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2740 PFORMAT_STRING pFormat)
2742 switch (*pFormat) {
2743 case RPC_FC_STRUCT:
2744 case RPC_FC_PSTRUCT:
2745 case RPC_FC_CSTRUCT:
2746 case RPC_FC_BOGUS_STRUCT:
2747 case RPC_FC_SMFARRAY:
2748 case RPC_FC_SMVARRAY:
2749 case RPC_FC_CSTRING:
2750 return *(const WORD*)&pFormat[2];
2751 case RPC_FC_USER_MARSHAL:
2752 return *(const WORD*)&pFormat[4];
2753 case RPC_FC_RANGE: {
2754 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2755 case RPC_FC_BYTE:
2756 case RPC_FC_CHAR:
2757 case RPC_FC_SMALL:
2758 case RPC_FC_USMALL:
2759 return sizeof(UCHAR);
2760 case RPC_FC_WCHAR:
2761 case RPC_FC_SHORT:
2762 case RPC_FC_USHORT:
2763 return sizeof(USHORT);
2764 case RPC_FC_LONG:
2765 case RPC_FC_ULONG:
2766 case RPC_FC_ENUM32:
2767 case RPC_FC_INT3264:
2768 case RPC_FC_UINT3264:
2769 return sizeof(ULONG);
2770 case RPC_FC_FLOAT:
2771 return sizeof(float);
2772 case RPC_FC_DOUBLE:
2773 return sizeof(double);
2774 case RPC_FC_HYPER:
2775 return sizeof(ULONGLONG);
2776 case RPC_FC_ENUM16:
2777 return sizeof(UINT);
2778 default:
2779 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2780 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2783 case RPC_FC_NON_ENCAPSULATED_UNION:
2784 pFormat += 2;
2785 pFormat = SkipConformance(pStubMsg, pFormat);
2786 pFormat += *(const SHORT*)pFormat;
2787 return *(const SHORT*)pFormat;
2788 case RPC_FC_IP:
2789 return sizeof(void *);
2790 case RPC_FC_WSTRING:
2791 return *(const WORD*)&pFormat[2] * 2;
2792 default:
2793 FIXME("unhandled embedded type %02x\n", *pFormat);
2795 return 0;
2799 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2800 PFORMAT_STRING pFormat)
2802 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2804 if (!m)
2806 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2807 return 0;
2810 return m(pStubMsg, pFormat);
2814 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2815 unsigned char *pMemory,
2816 PFORMAT_STRING pFormat,
2817 PFORMAT_STRING pPointer)
2819 PFORMAT_STRING desc;
2820 NDR_MARSHALL m;
2821 ULONG size;
2823 while (*pFormat != RPC_FC_END) {
2824 switch (*pFormat) {
2825 case RPC_FC_BYTE:
2826 case RPC_FC_CHAR:
2827 case RPC_FC_SMALL:
2828 case RPC_FC_USMALL:
2829 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2830 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2831 pMemory += 1;
2832 break;
2833 case RPC_FC_WCHAR:
2834 case RPC_FC_SHORT:
2835 case RPC_FC_USHORT:
2836 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2837 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2838 pMemory += 2;
2839 break;
2840 case RPC_FC_ENUM16:
2842 USHORT val = *(DWORD *)pMemory;
2843 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2844 if (32767 < *(DWORD*)pMemory)
2845 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2846 safe_copy_to_buffer(pStubMsg, &val, 2);
2847 pMemory += 4;
2848 break;
2850 case RPC_FC_LONG:
2851 case RPC_FC_ULONG:
2852 case RPC_FC_ENUM32:
2853 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2854 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2855 pMemory += 4;
2856 break;
2857 case RPC_FC_INT3264:
2858 case RPC_FC_UINT3264:
2860 UINT val = *(UINT_PTR *)pMemory;
2861 TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
2862 safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
2863 pMemory += sizeof(UINT_PTR);
2864 break;
2866 case RPC_FC_FLOAT:
2867 TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
2868 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
2869 pMemory += sizeof(float);
2870 break;
2871 case RPC_FC_HYPER:
2872 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2873 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2874 pMemory += 8;
2875 break;
2876 case RPC_FC_DOUBLE:
2877 TRACE("double=%f <= %p\n", *(double*)pMemory, pMemory);
2878 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
2879 pMemory += sizeof(double);
2880 break;
2881 case RPC_FC_RP:
2882 case RPC_FC_UP:
2883 case RPC_FC_OP:
2884 case RPC_FC_FP:
2885 case RPC_FC_POINTER:
2887 unsigned char *saved_buffer;
2888 BOOL pointer_buffer_mark_set = FALSE;
2889 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2890 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2891 if (*pFormat != RPC_FC_POINTER)
2892 pPointer = pFormat;
2893 if (*pPointer != RPC_FC_RP)
2894 align_pointer_clear(&pStubMsg->Buffer, 4);
2895 saved_buffer = pStubMsg->Buffer;
2896 if (pStubMsg->PointerBufferMark)
2898 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2899 pStubMsg->PointerBufferMark = NULL;
2900 pointer_buffer_mark_set = TRUE;
2902 else if (*pPointer != RPC_FC_RP)
2903 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2904 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2905 if (pointer_buffer_mark_set)
2907 STD_OVERFLOW_CHECK(pStubMsg);
2908 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2909 pStubMsg->Buffer = saved_buffer;
2910 if (*pPointer != RPC_FC_RP)
2911 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2913 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2914 if (*pFormat == RPC_FC_POINTER)
2915 pPointer += 4;
2916 else
2917 pFormat += 4;
2918 pMemory += sizeof(void *);
2919 break;
2921 case RPC_FC_ALIGNM2:
2922 align_pointer(&pMemory, 2);
2923 break;
2924 case RPC_FC_ALIGNM4:
2925 align_pointer(&pMemory, 4);
2926 break;
2927 case RPC_FC_ALIGNM8:
2928 align_pointer(&pMemory, 8);
2929 break;
2930 case RPC_FC_STRUCTPAD1:
2931 case RPC_FC_STRUCTPAD2:
2932 case RPC_FC_STRUCTPAD3:
2933 case RPC_FC_STRUCTPAD4:
2934 case RPC_FC_STRUCTPAD5:
2935 case RPC_FC_STRUCTPAD6:
2936 case RPC_FC_STRUCTPAD7:
2937 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2938 break;
2939 case RPC_FC_EMBEDDED_COMPLEX:
2940 pMemory += pFormat[1];
2941 pFormat += 2;
2942 desc = pFormat + *(const SHORT*)pFormat;
2943 size = EmbeddedComplexSize(pStubMsg, desc);
2944 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2945 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2946 if (m)
2948 /* for some reason interface pointers aren't generated as
2949 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2950 * they still need the derefencing treatment that pointers are
2951 * given */
2952 if (*desc == RPC_FC_IP)
2953 m(pStubMsg, *(unsigned char **)pMemory, desc);
2954 else
2955 m(pStubMsg, pMemory, desc);
2957 else FIXME("no marshaller for embedded type %02x\n", *desc);
2958 pMemory += size;
2959 pFormat += 2;
2960 continue;
2961 case RPC_FC_PAD:
2962 break;
2963 default:
2964 FIXME("unhandled format 0x%02x\n", *pFormat);
2966 pFormat++;
2969 return pMemory;
2972 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2973 unsigned char *pMemory,
2974 PFORMAT_STRING pFormat,
2975 PFORMAT_STRING pPointer,
2976 unsigned char fMustAlloc)
2978 PFORMAT_STRING desc;
2979 NDR_UNMARSHALL m;
2980 ULONG size;
2982 while (*pFormat != RPC_FC_END) {
2983 switch (*pFormat) {
2984 case RPC_FC_BYTE:
2985 case RPC_FC_CHAR:
2986 case RPC_FC_SMALL:
2987 case RPC_FC_USMALL:
2988 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2989 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2990 pMemory += 1;
2991 break;
2992 case RPC_FC_WCHAR:
2993 case RPC_FC_SHORT:
2994 case RPC_FC_USHORT:
2995 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2996 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2997 pMemory += 2;
2998 break;
2999 case RPC_FC_ENUM16:
3001 WORD val;
3002 safe_copy_from_buffer(pStubMsg, &val, 2);
3003 *(DWORD*)pMemory = val;
3004 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
3005 if (32767 < *(DWORD*)pMemory)
3006 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3007 pMemory += 4;
3008 break;
3010 case RPC_FC_LONG:
3011 case RPC_FC_ULONG:
3012 case RPC_FC_ENUM32:
3013 safe_copy_from_buffer(pStubMsg, pMemory, 4);
3014 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
3015 pMemory += 4;
3016 break;
3017 case RPC_FC_INT3264:
3019 INT val;
3020 safe_copy_from_buffer(pStubMsg, &val, 4);
3021 *(INT_PTR *)pMemory = val;
3022 TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
3023 pMemory += sizeof(INT_PTR);
3024 break;
3026 case RPC_FC_UINT3264:
3028 UINT val;
3029 safe_copy_from_buffer(pStubMsg, &val, 4);
3030 *(UINT_PTR *)pMemory = val;
3031 TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
3032 pMemory += sizeof(UINT_PTR);
3033 break;
3035 case RPC_FC_FLOAT:
3036 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
3037 TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
3038 pMemory += sizeof(float);
3039 break;
3040 case RPC_FC_HYPER:
3041 safe_copy_from_buffer(pStubMsg, pMemory, 8);
3042 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
3043 pMemory += 8;
3044 break;
3045 case RPC_FC_DOUBLE:
3046 safe_copy_from_buffer(pStubMsg, pMemory, sizeof(double));
3047 TRACE("double=%f => %p\n", *(double*)pMemory, pMemory);
3048 pMemory += sizeof(double);
3049 break;
3050 case RPC_FC_RP:
3051 case RPC_FC_UP:
3052 case RPC_FC_OP:
3053 case RPC_FC_FP:
3054 case RPC_FC_POINTER:
3056 unsigned char *saved_buffer;
3057 BOOL pointer_buffer_mark_set = FALSE;
3058 TRACE("pointer => %p\n", pMemory);
3059 if (*pFormat != RPC_FC_POINTER)
3060 pPointer = pFormat;
3061 if (*pPointer != RPC_FC_RP)
3062 align_pointer(&pStubMsg->Buffer, 4);
3063 saved_buffer = pStubMsg->Buffer;
3064 if (pStubMsg->PointerBufferMark)
3066 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3067 pStubMsg->PointerBufferMark = NULL;
3068 pointer_buffer_mark_set = TRUE;
3070 else if (*pPointer != RPC_FC_RP)
3071 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3073 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
3074 if (pointer_buffer_mark_set)
3076 STD_OVERFLOW_CHECK(pStubMsg);
3077 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3078 pStubMsg->Buffer = saved_buffer;
3079 if (*pPointer != RPC_FC_RP)
3080 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3082 if (*pFormat == RPC_FC_POINTER)
3083 pPointer += 4;
3084 else
3085 pFormat += 4;
3086 pMemory += sizeof(void *);
3087 break;
3089 case RPC_FC_ALIGNM2:
3090 align_pointer_clear(&pMemory, 2);
3091 break;
3092 case RPC_FC_ALIGNM4:
3093 align_pointer_clear(&pMemory, 4);
3094 break;
3095 case RPC_FC_ALIGNM8:
3096 align_pointer_clear(&pMemory, 8);
3097 break;
3098 case RPC_FC_STRUCTPAD1:
3099 case RPC_FC_STRUCTPAD2:
3100 case RPC_FC_STRUCTPAD3:
3101 case RPC_FC_STRUCTPAD4:
3102 case RPC_FC_STRUCTPAD5:
3103 case RPC_FC_STRUCTPAD6:
3104 case RPC_FC_STRUCTPAD7:
3105 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
3106 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3107 break;
3108 case RPC_FC_EMBEDDED_COMPLEX:
3109 pMemory += pFormat[1];
3110 pFormat += 2;
3111 desc = pFormat + *(const SHORT*)pFormat;
3112 size = EmbeddedComplexSize(pStubMsg, desc);
3113 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
3114 if (fMustAlloc)
3115 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3116 * since the type is part of the memory block that is encompassed by
3117 * the whole complex type. Memory is forced to allocate when pointers
3118 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3119 * clearing the memory we pass in to the unmarshaller */
3120 memset(pMemory, 0, size);
3121 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3122 if (m)
3124 /* for some reason interface pointers aren't generated as
3125 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3126 * they still need the derefencing treatment that pointers are
3127 * given */
3128 if (*desc == RPC_FC_IP)
3129 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
3130 else
3131 m(pStubMsg, &pMemory, desc, FALSE);
3133 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
3134 pMemory += size;
3135 pFormat += 2;
3136 continue;
3137 case RPC_FC_PAD:
3138 break;
3139 default:
3140 FIXME("unhandled format %d\n", *pFormat);
3142 pFormat++;
3145 return pMemory;
3148 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3149 unsigned char *pMemory,
3150 PFORMAT_STRING pFormat,
3151 PFORMAT_STRING pPointer)
3153 PFORMAT_STRING desc;
3154 NDR_BUFFERSIZE m;
3155 ULONG size;
3157 while (*pFormat != RPC_FC_END) {
3158 switch (*pFormat) {
3159 case RPC_FC_BYTE:
3160 case RPC_FC_CHAR:
3161 case RPC_FC_SMALL:
3162 case RPC_FC_USMALL:
3163 safe_buffer_length_increment(pStubMsg, 1);
3164 pMemory += 1;
3165 break;
3166 case RPC_FC_WCHAR:
3167 case RPC_FC_SHORT:
3168 case RPC_FC_USHORT:
3169 safe_buffer_length_increment(pStubMsg, 2);
3170 pMemory += 2;
3171 break;
3172 case RPC_FC_ENUM16:
3173 safe_buffer_length_increment(pStubMsg, 2);
3174 pMemory += 4;
3175 break;
3176 case RPC_FC_LONG:
3177 case RPC_FC_ULONG:
3178 case RPC_FC_ENUM32:
3179 case RPC_FC_FLOAT:
3180 safe_buffer_length_increment(pStubMsg, 4);
3181 pMemory += 4;
3182 break;
3183 case RPC_FC_INT3264:
3184 case RPC_FC_UINT3264:
3185 safe_buffer_length_increment(pStubMsg, 4);
3186 pMemory += sizeof(INT_PTR);
3187 break;
3188 case RPC_FC_HYPER:
3189 case RPC_FC_DOUBLE:
3190 safe_buffer_length_increment(pStubMsg, 8);
3191 pMemory += 8;
3192 break;
3193 case RPC_FC_RP:
3194 case RPC_FC_UP:
3195 case RPC_FC_OP:
3196 case RPC_FC_FP:
3197 case RPC_FC_POINTER:
3198 if (*pFormat != RPC_FC_POINTER)
3199 pPointer = pFormat;
3200 if (!pStubMsg->IgnoreEmbeddedPointers)
3202 int saved_buffer_length = pStubMsg->BufferLength;
3203 pStubMsg->BufferLength = pStubMsg->PointerLength;
3204 pStubMsg->PointerLength = 0;
3205 if(!pStubMsg->BufferLength)
3206 ERR("BufferLength == 0??\n");
3207 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
3208 pStubMsg->PointerLength = pStubMsg->BufferLength;
3209 pStubMsg->BufferLength = saved_buffer_length;
3211 if (*pPointer != RPC_FC_RP)
3213 align_length(&pStubMsg->BufferLength, 4);
3214 safe_buffer_length_increment(pStubMsg, 4);
3216 if (*pFormat == RPC_FC_POINTER)
3217 pPointer += 4;
3218 else
3219 pFormat += 4;
3220 pMemory += sizeof(void*);
3221 break;
3222 case RPC_FC_ALIGNM2:
3223 align_pointer(&pMemory, 2);
3224 break;
3225 case RPC_FC_ALIGNM4:
3226 align_pointer(&pMemory, 4);
3227 break;
3228 case RPC_FC_ALIGNM8:
3229 align_pointer(&pMemory, 8);
3230 break;
3231 case RPC_FC_STRUCTPAD1:
3232 case RPC_FC_STRUCTPAD2:
3233 case RPC_FC_STRUCTPAD3:
3234 case RPC_FC_STRUCTPAD4:
3235 case RPC_FC_STRUCTPAD5:
3236 case RPC_FC_STRUCTPAD6:
3237 case RPC_FC_STRUCTPAD7:
3238 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3239 break;
3240 case RPC_FC_EMBEDDED_COMPLEX:
3241 pMemory += pFormat[1];
3242 pFormat += 2;
3243 desc = pFormat + *(const SHORT*)pFormat;
3244 size = EmbeddedComplexSize(pStubMsg, desc);
3245 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3246 if (m)
3248 /* for some reason interface pointers aren't generated as
3249 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3250 * they still need the derefencing treatment that pointers are
3251 * given */
3252 if (*desc == RPC_FC_IP)
3253 m(pStubMsg, *(unsigned char **)pMemory, desc);
3254 else
3255 m(pStubMsg, pMemory, desc);
3257 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3258 pMemory += size;
3259 pFormat += 2;
3260 continue;
3261 case RPC_FC_PAD:
3262 break;
3263 default:
3264 FIXME("unhandled format 0x%02x\n", *pFormat);
3266 pFormat++;
3269 return pMemory;
3272 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3273 unsigned char *pMemory,
3274 PFORMAT_STRING pFormat,
3275 PFORMAT_STRING pPointer)
3277 PFORMAT_STRING desc;
3278 NDR_FREE m;
3279 ULONG size;
3281 while (*pFormat != RPC_FC_END) {
3282 switch (*pFormat) {
3283 case RPC_FC_BYTE:
3284 case RPC_FC_CHAR:
3285 case RPC_FC_SMALL:
3286 case RPC_FC_USMALL:
3287 pMemory += 1;
3288 break;
3289 case RPC_FC_WCHAR:
3290 case RPC_FC_SHORT:
3291 case RPC_FC_USHORT:
3292 pMemory += 2;
3293 break;
3294 case RPC_FC_LONG:
3295 case RPC_FC_ULONG:
3296 case RPC_FC_ENUM16:
3297 case RPC_FC_ENUM32:
3298 case RPC_FC_FLOAT:
3299 pMemory += 4;
3300 break;
3301 case RPC_FC_INT3264:
3302 case RPC_FC_UINT3264:
3303 pMemory += sizeof(INT_PTR);
3304 break;
3305 case RPC_FC_HYPER:
3306 case RPC_FC_DOUBLE:
3307 pMemory += 8;
3308 break;
3309 case RPC_FC_RP:
3310 case RPC_FC_UP:
3311 case RPC_FC_OP:
3312 case RPC_FC_FP:
3313 case RPC_FC_POINTER:
3314 if (*pFormat != RPC_FC_POINTER)
3315 pPointer = pFormat;
3316 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3317 if (*pFormat == RPC_FC_POINTER)
3318 pPointer += 4;
3319 else
3320 pFormat += 4;
3321 pMemory += sizeof(void *);
3322 break;
3323 case RPC_FC_ALIGNM2:
3324 align_pointer(&pMemory, 2);
3325 break;
3326 case RPC_FC_ALIGNM4:
3327 align_pointer(&pMemory, 4);
3328 break;
3329 case RPC_FC_ALIGNM8:
3330 align_pointer(&pMemory, 8);
3331 break;
3332 case RPC_FC_STRUCTPAD1:
3333 case RPC_FC_STRUCTPAD2:
3334 case RPC_FC_STRUCTPAD3:
3335 case RPC_FC_STRUCTPAD4:
3336 case RPC_FC_STRUCTPAD5:
3337 case RPC_FC_STRUCTPAD6:
3338 case RPC_FC_STRUCTPAD7:
3339 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3340 break;
3341 case RPC_FC_EMBEDDED_COMPLEX:
3342 pMemory += pFormat[1];
3343 pFormat += 2;
3344 desc = pFormat + *(const SHORT*)pFormat;
3345 size = EmbeddedComplexSize(pStubMsg, desc);
3346 m = NdrFreer[*desc & NDR_TABLE_MASK];
3347 if (m)
3349 /* for some reason interface pointers aren't generated as
3350 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3351 * they still need the derefencing treatment that pointers are
3352 * given */
3353 if (*desc == RPC_FC_IP)
3354 m(pStubMsg, *(unsigned char **)pMemory, desc);
3355 else
3356 m(pStubMsg, pMemory, desc);
3358 pMemory += size;
3359 pFormat += 2;
3360 continue;
3361 case RPC_FC_PAD:
3362 break;
3363 default:
3364 FIXME("unhandled format 0x%02x\n", *pFormat);
3366 pFormat++;
3369 return pMemory;
3372 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3373 PFORMAT_STRING pFormat,
3374 PFORMAT_STRING pPointer)
3376 PFORMAT_STRING desc;
3377 ULONG size = 0;
3379 while (*pFormat != RPC_FC_END) {
3380 switch (*pFormat) {
3381 case RPC_FC_BYTE:
3382 case RPC_FC_CHAR:
3383 case RPC_FC_SMALL:
3384 case RPC_FC_USMALL:
3385 size += 1;
3386 safe_buffer_increment(pStubMsg, 1);
3387 break;
3388 case RPC_FC_WCHAR:
3389 case RPC_FC_SHORT:
3390 case RPC_FC_USHORT:
3391 size += 2;
3392 safe_buffer_increment(pStubMsg, 2);
3393 break;
3394 case RPC_FC_ENUM16:
3395 size += 4;
3396 safe_buffer_increment(pStubMsg, 2);
3397 break;
3398 case RPC_FC_LONG:
3399 case RPC_FC_ULONG:
3400 case RPC_FC_ENUM32:
3401 case RPC_FC_FLOAT:
3402 size += 4;
3403 safe_buffer_increment(pStubMsg, 4);
3404 break;
3405 case RPC_FC_INT3264:
3406 case RPC_FC_UINT3264:
3407 size += sizeof(INT_PTR);
3408 safe_buffer_increment(pStubMsg, 4);
3409 break;
3410 case RPC_FC_HYPER:
3411 case RPC_FC_DOUBLE:
3412 size += 8;
3413 safe_buffer_increment(pStubMsg, 8);
3414 break;
3415 case RPC_FC_RP:
3416 case RPC_FC_UP:
3417 case RPC_FC_OP:
3418 case RPC_FC_FP:
3419 case RPC_FC_POINTER:
3421 unsigned char *saved_buffer;
3422 BOOL pointer_buffer_mark_set = FALSE;
3423 if (*pFormat != RPC_FC_POINTER)
3424 pPointer = pFormat;
3425 if (*pPointer != RPC_FC_RP)
3426 align_pointer(&pStubMsg->Buffer, 4);
3427 saved_buffer = pStubMsg->Buffer;
3428 if (pStubMsg->PointerBufferMark)
3430 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3431 pStubMsg->PointerBufferMark = NULL;
3432 pointer_buffer_mark_set = TRUE;
3434 else if (*pPointer != RPC_FC_RP)
3435 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3437 if (!pStubMsg->IgnoreEmbeddedPointers)
3438 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3439 if (pointer_buffer_mark_set)
3441 STD_OVERFLOW_CHECK(pStubMsg);
3442 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3443 pStubMsg->Buffer = saved_buffer;
3444 if (*pPointer != RPC_FC_RP)
3445 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3447 if (*pFormat == RPC_FC_POINTER)
3448 pPointer += 4;
3449 else
3450 pFormat += 4;
3451 size += sizeof(void *);
3452 break;
3454 case RPC_FC_ALIGNM2:
3455 align_length(&size, 2);
3456 break;
3457 case RPC_FC_ALIGNM4:
3458 align_length(&size, 4);
3459 break;
3460 case RPC_FC_ALIGNM8:
3461 align_length(&size, 8);
3462 break;
3463 case RPC_FC_STRUCTPAD1:
3464 case RPC_FC_STRUCTPAD2:
3465 case RPC_FC_STRUCTPAD3:
3466 case RPC_FC_STRUCTPAD4:
3467 case RPC_FC_STRUCTPAD5:
3468 case RPC_FC_STRUCTPAD6:
3469 case RPC_FC_STRUCTPAD7:
3470 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3471 break;
3472 case RPC_FC_EMBEDDED_COMPLEX:
3473 size += pFormat[1];
3474 pFormat += 2;
3475 desc = pFormat + *(const SHORT*)pFormat;
3476 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3477 pFormat += 2;
3478 continue;
3479 case RPC_FC_PAD:
3480 break;
3481 default:
3482 FIXME("unhandled format 0x%02x\n", *pFormat);
3484 pFormat++;
3487 return size;
3490 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3492 PFORMAT_STRING desc;
3493 ULONG size = 0;
3495 while (*pFormat != RPC_FC_END) {
3496 switch (*pFormat) {
3497 case RPC_FC_BYTE:
3498 case RPC_FC_CHAR:
3499 case RPC_FC_SMALL:
3500 case RPC_FC_USMALL:
3501 size += 1;
3502 break;
3503 case RPC_FC_WCHAR:
3504 case RPC_FC_SHORT:
3505 case RPC_FC_USHORT:
3506 size += 2;
3507 break;
3508 case RPC_FC_LONG:
3509 case RPC_FC_ULONG:
3510 case RPC_FC_ENUM16:
3511 case RPC_FC_ENUM32:
3512 case RPC_FC_FLOAT:
3513 size += 4;
3514 break;
3515 case RPC_FC_INT3264:
3516 case RPC_FC_UINT3264:
3517 size += sizeof(INT_PTR);
3518 break;
3519 case RPC_FC_HYPER:
3520 case RPC_FC_DOUBLE:
3521 size += 8;
3522 break;
3523 case RPC_FC_RP:
3524 case RPC_FC_UP:
3525 case RPC_FC_OP:
3526 case RPC_FC_FP:
3527 case RPC_FC_POINTER:
3528 size += sizeof(void *);
3529 if (*pFormat != RPC_FC_POINTER)
3530 pFormat += 4;
3531 break;
3532 case RPC_FC_ALIGNM2:
3533 align_length(&size, 2);
3534 break;
3535 case RPC_FC_ALIGNM4:
3536 align_length(&size, 4);
3537 break;
3538 case RPC_FC_ALIGNM8:
3539 align_length(&size, 8);
3540 break;
3541 case RPC_FC_STRUCTPAD1:
3542 case RPC_FC_STRUCTPAD2:
3543 case RPC_FC_STRUCTPAD3:
3544 case RPC_FC_STRUCTPAD4:
3545 case RPC_FC_STRUCTPAD5:
3546 case RPC_FC_STRUCTPAD6:
3547 case RPC_FC_STRUCTPAD7:
3548 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3549 break;
3550 case RPC_FC_EMBEDDED_COMPLEX:
3551 size += pFormat[1];
3552 pFormat += 2;
3553 desc = pFormat + *(const SHORT*)pFormat;
3554 size += EmbeddedComplexSize(pStubMsg, desc);
3555 pFormat += 2;
3556 continue;
3557 case RPC_FC_PAD:
3558 break;
3559 default:
3560 FIXME("unhandled format 0x%02x\n", *pFormat);
3562 pFormat++;
3565 return size;
3568 /***********************************************************************
3569 * NdrComplexStructMarshall [RPCRT4.@]
3571 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3572 unsigned char *pMemory,
3573 PFORMAT_STRING pFormat)
3575 PFORMAT_STRING conf_array = NULL;
3576 PFORMAT_STRING pointer_desc = NULL;
3577 unsigned char *OldMemory = pStubMsg->Memory;
3578 BOOL pointer_buffer_mark_set = FALSE;
3579 ULONG count = 0;
3580 ULONG max_count = 0;
3581 ULONG offset = 0;
3583 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3585 if (!pStubMsg->PointerBufferMark)
3587 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3588 /* save buffer length */
3589 ULONG saved_buffer_length = pStubMsg->BufferLength;
3591 /* get the buffer pointer after complex array data, but before
3592 * pointer data */
3593 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3594 pStubMsg->IgnoreEmbeddedPointers = 1;
3595 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3596 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3598 /* save it for use by embedded pointer code later */
3599 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3600 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3601 pointer_buffer_mark_set = TRUE;
3603 /* restore the original buffer length */
3604 pStubMsg->BufferLength = saved_buffer_length;
3607 align_pointer_clear(&pStubMsg->Buffer, pFormat[1] + 1);
3609 pFormat += 4;
3610 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3611 pFormat += 2;
3612 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3613 pFormat += 2;
3615 pStubMsg->Memory = pMemory;
3617 if (conf_array)
3619 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3620 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3621 pMemory + struct_size, conf_array);
3622 /* these could be changed in ComplexMarshall so save them for later */
3623 max_count = pStubMsg->MaxCount;
3624 count = pStubMsg->ActualCount;
3625 offset = pStubMsg->Offset;
3628 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3630 if (conf_array)
3632 pStubMsg->MaxCount = max_count;
3633 pStubMsg->ActualCount = count;
3634 pStubMsg->Offset = offset;
3635 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3636 conf_array, TRUE /* fHasPointers */);
3639 pStubMsg->Memory = OldMemory;
3641 if (pointer_buffer_mark_set)
3643 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3644 pStubMsg->PointerBufferMark = NULL;
3647 STD_OVERFLOW_CHECK(pStubMsg);
3649 return NULL;
3652 /***********************************************************************
3653 * NdrComplexStructUnmarshall [RPCRT4.@]
3655 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3656 unsigned char **ppMemory,
3657 PFORMAT_STRING pFormat,
3658 unsigned char fMustAlloc)
3660 unsigned size = *(const WORD*)(pFormat+2);
3661 PFORMAT_STRING conf_array = NULL;
3662 PFORMAT_STRING pointer_desc = NULL;
3663 unsigned char *pMemory;
3664 BOOL pointer_buffer_mark_set = FALSE;
3665 ULONG count = 0;
3666 ULONG max_count = 0;
3667 ULONG offset = 0;
3668 ULONG array_size = 0;
3670 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3672 if (!pStubMsg->PointerBufferMark)
3674 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3675 /* save buffer pointer */
3676 unsigned char *saved_buffer = pStubMsg->Buffer;
3678 /* get the buffer pointer after complex array data, but before
3679 * pointer data */
3680 pStubMsg->IgnoreEmbeddedPointers = 1;
3681 NdrComplexStructMemorySize(pStubMsg, pFormat);
3682 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3684 /* save it for use by embedded pointer code later */
3685 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3686 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3687 pointer_buffer_mark_set = TRUE;
3689 /* restore the original buffer */
3690 pStubMsg->Buffer = saved_buffer;
3693 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3695 pFormat += 4;
3696 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3697 pFormat += 2;
3698 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3699 pFormat += 2;
3701 if (conf_array)
3703 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3704 size += array_size;
3706 /* these could be changed in ComplexMarshall so save them for later */
3707 max_count = pStubMsg->MaxCount;
3708 count = pStubMsg->ActualCount;
3709 offset = pStubMsg->Offset;
3712 if (!fMustAlloc && !*ppMemory)
3713 fMustAlloc = TRUE;
3714 if (fMustAlloc)
3715 *ppMemory = NdrAllocate(pStubMsg, size);
3717 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3719 if (conf_array)
3721 pStubMsg->MaxCount = max_count;
3722 pStubMsg->ActualCount = count;
3723 pStubMsg->Offset = offset;
3724 if (fMustAlloc)
3725 memset(pMemory, 0, array_size);
3726 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3727 conf_array, FALSE,
3728 FALSE /* fUseBufferMemoryServer */,
3729 TRUE /* fUnmarshall */);
3732 if (pointer_buffer_mark_set)
3734 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3735 pStubMsg->PointerBufferMark = NULL;
3738 return NULL;
3741 /***********************************************************************
3742 * NdrComplexStructBufferSize [RPCRT4.@]
3744 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3745 unsigned char *pMemory,
3746 PFORMAT_STRING pFormat)
3748 PFORMAT_STRING conf_array = NULL;
3749 PFORMAT_STRING pointer_desc = NULL;
3750 unsigned char *OldMemory = pStubMsg->Memory;
3751 int pointer_length_set = 0;
3752 ULONG count = 0;
3753 ULONG max_count = 0;
3754 ULONG offset = 0;
3756 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3758 align_length(&pStubMsg->BufferLength, pFormat[1] + 1);
3760 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3762 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3763 ULONG saved_buffer_length = pStubMsg->BufferLength;
3765 /* get the buffer length after complex struct data, but before
3766 * pointer data */
3767 pStubMsg->IgnoreEmbeddedPointers = 1;
3768 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3769 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3771 /* save it for use by embedded pointer code later */
3772 pStubMsg->PointerLength = pStubMsg->BufferLength;
3773 pointer_length_set = 1;
3774 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3776 /* restore the original buffer length */
3777 pStubMsg->BufferLength = saved_buffer_length;
3780 pFormat += 4;
3781 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3782 pFormat += 2;
3783 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3784 pFormat += 2;
3786 pStubMsg->Memory = pMemory;
3788 if (conf_array)
3790 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3791 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3792 conf_array);
3794 /* these could be changed in ComplexMarshall so save them for later */
3795 max_count = pStubMsg->MaxCount;
3796 count = pStubMsg->ActualCount;
3797 offset = pStubMsg->Offset;
3800 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3802 if (conf_array)
3804 pStubMsg->MaxCount = max_count;
3805 pStubMsg->ActualCount = count;
3806 pStubMsg->Offset = offset;
3807 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3808 TRUE /* fHasPointers */);
3811 pStubMsg->Memory = OldMemory;
3813 if(pointer_length_set)
3815 pStubMsg->BufferLength = pStubMsg->PointerLength;
3816 pStubMsg->PointerLength = 0;
3821 /***********************************************************************
3822 * NdrComplexStructMemorySize [RPCRT4.@]
3824 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3825 PFORMAT_STRING pFormat)
3827 unsigned size = *(const WORD*)(pFormat+2);
3828 PFORMAT_STRING conf_array = NULL;
3829 PFORMAT_STRING pointer_desc = NULL;
3830 ULONG count = 0;
3831 ULONG max_count = 0;
3832 ULONG offset = 0;
3834 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3836 align_pointer(&pStubMsg->Buffer, pFormat[1] + 1);
3838 pFormat += 4;
3839 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3840 pFormat += 2;
3841 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3842 pFormat += 2;
3844 if (conf_array)
3846 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3848 /* these could be changed in ComplexStructMemorySize so save them for
3849 * later */
3850 max_count = pStubMsg->MaxCount;
3851 count = pStubMsg->ActualCount;
3852 offset = pStubMsg->Offset;
3855 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3857 if (conf_array)
3859 pStubMsg->MaxCount = max_count;
3860 pStubMsg->ActualCount = count;
3861 pStubMsg->Offset = offset;
3862 array_memory_size(conf_array[0], pStubMsg, conf_array,
3863 TRUE /* fHasPointers */);
3866 return size;
3869 /***********************************************************************
3870 * NdrComplexStructFree [RPCRT4.@]
3872 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3873 unsigned char *pMemory,
3874 PFORMAT_STRING pFormat)
3876 PFORMAT_STRING conf_array = NULL;
3877 PFORMAT_STRING pointer_desc = NULL;
3878 unsigned char *OldMemory = pStubMsg->Memory;
3880 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3882 pFormat += 4;
3883 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3884 pFormat += 2;
3885 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3886 pFormat += 2;
3888 pStubMsg->Memory = pMemory;
3890 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3892 if (conf_array)
3893 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3894 TRUE /* fHasPointers */);
3896 pStubMsg->Memory = OldMemory;
3899 /***********************************************************************
3900 * NdrConformantArrayMarshall [RPCRT4.@]
3902 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3903 unsigned char *pMemory,
3904 PFORMAT_STRING pFormat)
3906 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3907 if (pFormat[0] != RPC_FC_CARRAY)
3909 ERR("invalid format = 0x%x\n", pFormat[0]);
3910 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3913 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3914 pFormat);
3915 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3916 TRUE /* fHasPointers */);
3918 return NULL;
3921 /***********************************************************************
3922 * NdrConformantArrayUnmarshall [RPCRT4.@]
3924 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3925 unsigned char **ppMemory,
3926 PFORMAT_STRING pFormat,
3927 unsigned char fMustAlloc)
3929 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3930 if (pFormat[0] != RPC_FC_CARRAY)
3932 ERR("invalid format = 0x%x\n", pFormat[0]);
3933 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3936 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3937 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3938 fMustAlloc,
3939 TRUE /* fUseBufferMemoryServer */,
3940 TRUE /* fUnmarshall */);
3942 return NULL;
3945 /***********************************************************************
3946 * NdrConformantArrayBufferSize [RPCRT4.@]
3948 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3949 unsigned char *pMemory,
3950 PFORMAT_STRING pFormat)
3952 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3953 if (pFormat[0] != RPC_FC_CARRAY)
3955 ERR("invalid format = 0x%x\n", pFormat[0]);
3956 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3959 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3960 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3961 TRUE /* fHasPointers */);
3964 /***********************************************************************
3965 * NdrConformantArrayMemorySize [RPCRT4.@]
3967 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3968 PFORMAT_STRING pFormat)
3970 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3971 if (pFormat[0] != RPC_FC_CARRAY)
3973 ERR("invalid format = 0x%x\n", pFormat[0]);
3974 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3977 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3978 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3980 return pStubMsg->MemorySize;
3983 /***********************************************************************
3984 * NdrConformantArrayFree [RPCRT4.@]
3986 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3987 unsigned char *pMemory,
3988 PFORMAT_STRING pFormat)
3990 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3991 if (pFormat[0] != RPC_FC_CARRAY)
3993 ERR("invalid format = 0x%x\n", pFormat[0]);
3994 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3997 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3998 TRUE /* fHasPointers */);
4002 /***********************************************************************
4003 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4005 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
4006 unsigned char* pMemory,
4007 PFORMAT_STRING pFormat )
4009 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4011 if (pFormat[0] != RPC_FC_CVARRAY)
4013 ERR("invalid format type %x\n", pFormat[0]);
4014 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4015 return NULL;
4018 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4019 pFormat);
4020 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
4021 pFormat, TRUE /* fHasPointers */);
4023 return NULL;
4027 /***********************************************************************
4028 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4030 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
4031 unsigned char** ppMemory,
4032 PFORMAT_STRING pFormat,
4033 unsigned char fMustAlloc )
4035 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4037 if (pFormat[0] != RPC_FC_CVARRAY)
4039 ERR("invalid format type %x\n", pFormat[0]);
4040 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4041 return NULL;
4044 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4045 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
4046 pFormat, fMustAlloc,
4047 TRUE /* fUseBufferMemoryServer */,
4048 TRUE /* fUnmarshall */);
4050 return NULL;
4054 /***********************************************************************
4055 * NdrConformantVaryingArrayFree [RPCRT4.@]
4057 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
4058 unsigned char* pMemory,
4059 PFORMAT_STRING pFormat )
4061 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4063 if (pFormat[0] != RPC_FC_CVARRAY)
4065 ERR("invalid format type %x\n", pFormat[0]);
4066 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4067 return;
4070 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4071 TRUE /* fHasPointers */);
4075 /***********************************************************************
4076 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4078 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
4079 unsigned char* pMemory, PFORMAT_STRING pFormat )
4081 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4083 if (pFormat[0] != RPC_FC_CVARRAY)
4085 ERR("invalid format type %x\n", pFormat[0]);
4086 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4087 return;
4090 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
4091 pFormat);
4092 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
4093 TRUE /* fHasPointers */);
4097 /***********************************************************************
4098 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4100 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
4101 PFORMAT_STRING pFormat )
4103 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4105 if (pFormat[0] != RPC_FC_CVARRAY)
4107 ERR("invalid format type %x\n", pFormat[0]);
4108 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4109 return pStubMsg->MemorySize;
4112 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
4113 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
4114 TRUE /* fHasPointers */);
4116 return pStubMsg->MemorySize;
4120 /***********************************************************************
4121 * NdrComplexArrayMarshall [RPCRT4.@]
4123 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4124 unsigned char *pMemory,
4125 PFORMAT_STRING pFormat)
4127 BOOL pointer_buffer_mark_set = FALSE;
4129 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4131 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4133 ERR("invalid format type %x\n", pFormat[0]);
4134 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4135 return NULL;
4138 if (!pStubMsg->PointerBufferMark)
4140 /* save buffer fields that may be changed by buffer sizer functions
4141 * and that may be needed later on */
4142 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4143 ULONG saved_buffer_length = pStubMsg->BufferLength;
4144 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4145 ULONG saved_offset = pStubMsg->Offset;
4146 ULONG saved_actual_count = pStubMsg->ActualCount;
4148 /* get the buffer pointer after complex array data, but before
4149 * pointer data */
4150 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
4151 pStubMsg->IgnoreEmbeddedPointers = 1;
4152 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4153 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4155 /* save it for use by embedded pointer code later */
4156 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
4157 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
4158 pointer_buffer_mark_set = TRUE;
4160 /* restore fields */
4161 pStubMsg->ActualCount = saved_actual_count;
4162 pStubMsg->Offset = saved_offset;
4163 pStubMsg->MaxCount = saved_max_count;
4164 pStubMsg->BufferLength = saved_buffer_length;
4167 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4168 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg,
4169 pMemory, pFormat, TRUE /* fHasPointers */);
4171 STD_OVERFLOW_CHECK(pStubMsg);
4173 if (pointer_buffer_mark_set)
4175 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4176 pStubMsg->PointerBufferMark = NULL;
4179 return NULL;
4182 /***********************************************************************
4183 * NdrComplexArrayUnmarshall [RPCRT4.@]
4185 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4186 unsigned char **ppMemory,
4187 PFORMAT_STRING pFormat,
4188 unsigned char fMustAlloc)
4190 unsigned char *saved_buffer;
4191 BOOL pointer_buffer_mark_set = FALSE;
4192 int saved_ignore_embedded;
4194 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4196 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4198 ERR("invalid format type %x\n", pFormat[0]);
4199 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4200 return NULL;
4203 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4204 /* save buffer pointer */
4205 saved_buffer = pStubMsg->Buffer;
4206 /* get the buffer pointer after complex array data, but before
4207 * pointer data */
4208 pStubMsg->IgnoreEmbeddedPointers = 1;
4209 pStubMsg->MemorySize = 0;
4210 NdrComplexArrayMemorySize(pStubMsg, pFormat);
4211 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4213 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
4214 if (!pStubMsg->PointerBufferMark)
4216 /* save it for use by embedded pointer code later */
4217 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4218 pointer_buffer_mark_set = TRUE;
4220 /* restore the original buffer */
4221 pStubMsg->Buffer = saved_buffer;
4223 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4224 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
4225 TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
4227 if (pointer_buffer_mark_set)
4229 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4230 pStubMsg->PointerBufferMark = NULL;
4233 return NULL;
4236 /***********************************************************************
4237 * NdrComplexArrayBufferSize [RPCRT4.@]
4239 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4240 unsigned char *pMemory,
4241 PFORMAT_STRING pFormat)
4243 int pointer_length_set = 0;
4245 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4247 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4249 ERR("invalid format type %x\n", pFormat[0]);
4250 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4251 return;
4254 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
4256 /* save buffer fields that may be changed by buffer sizer functions
4257 * and that may be needed later on */
4258 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
4259 ULONG saved_buffer_length = pStubMsg->BufferLength;
4260 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
4261 ULONG saved_offset = pStubMsg->Offset;
4262 ULONG saved_actual_count = pStubMsg->ActualCount;
4264 /* get the buffer pointer after complex array data, but before
4265 * pointer data */
4266 pStubMsg->IgnoreEmbeddedPointers = 1;
4267 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4268 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4270 /* save it for use by embedded pointer code later */
4271 pStubMsg->PointerLength = pStubMsg->BufferLength;
4272 pointer_length_set = 1;
4274 /* restore fields */
4275 pStubMsg->ActualCount = saved_actual_count;
4276 pStubMsg->Offset = saved_offset;
4277 pStubMsg->MaxCount = saved_max_count;
4278 pStubMsg->BufferLength = saved_buffer_length;
4281 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
4282 array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
4284 if(pointer_length_set)
4286 pStubMsg->BufferLength = pStubMsg->PointerLength;
4287 pStubMsg->PointerLength = 0;
4291 /***********************************************************************
4292 * NdrComplexArrayMemorySize [RPCRT4.@]
4294 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4295 PFORMAT_STRING pFormat)
4297 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4299 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4301 ERR("invalid format type %x\n", pFormat[0]);
4302 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4303 return 0;
4306 array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
4307 array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
4308 return pStubMsg->MemorySize;
4311 /***********************************************************************
4312 * NdrComplexArrayFree [RPCRT4.@]
4314 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4315 unsigned char *pMemory,
4316 PFORMAT_STRING pFormat)
4318 ULONG i, count, def;
4320 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4322 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4324 ERR("invalid format type %x\n", pFormat[0]);
4325 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4326 return;
4329 def = *(const WORD*)&pFormat[2];
4330 pFormat += 4;
4332 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4333 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4335 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4336 TRACE("variance = %d\n", pStubMsg->ActualCount);
4338 count = pStubMsg->ActualCount;
4339 for (i = 0; i < count; i++)
4340 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4343 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4344 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4345 USER_MARSHAL_CB *umcb)
4347 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4348 pStubMsg->RpcMsg->DataRepresentation);
4349 umcb->pStubMsg = pStubMsg;
4350 umcb->pReserve = NULL;
4351 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4352 umcb->CBType = cbtype;
4353 umcb->pFormat = pFormat;
4354 umcb->pTypeFormat = NULL /* FIXME */;
4357 #define USER_MARSHAL_PTR_PREFIX \
4358 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4359 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4361 /***********************************************************************
4362 * NdrUserMarshalMarshall [RPCRT4.@]
4364 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4365 unsigned char *pMemory,
4366 PFORMAT_STRING pFormat)
4368 unsigned flags = pFormat[1];
4369 unsigned index = *(const WORD*)&pFormat[2];
4370 unsigned char *saved_buffer = NULL;
4371 USER_MARSHAL_CB umcb;
4373 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4374 TRACE("index=%d\n", index);
4376 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4378 if (flags & USER_MARSHAL_POINTER)
4380 align_pointer_clear(&pStubMsg->Buffer, 4);
4381 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4382 pStubMsg->Buffer += 4;
4383 if (pStubMsg->PointerBufferMark)
4385 saved_buffer = pStubMsg->Buffer;
4386 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4387 pStubMsg->PointerBufferMark = NULL;
4389 align_pointer_clear(&pStubMsg->Buffer, 8);
4391 else
4392 align_pointer_clear(&pStubMsg->Buffer, (flags & 0xf) + 1);
4394 pStubMsg->Buffer =
4395 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4396 &umcb.Flags, pStubMsg->Buffer, pMemory);
4398 if (saved_buffer)
4400 STD_OVERFLOW_CHECK(pStubMsg);
4401 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4402 pStubMsg->Buffer = saved_buffer;
4405 STD_OVERFLOW_CHECK(pStubMsg);
4407 return NULL;
4410 /***********************************************************************
4411 * NdrUserMarshalUnmarshall [RPCRT4.@]
4413 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4414 unsigned char **ppMemory,
4415 PFORMAT_STRING pFormat,
4416 unsigned char fMustAlloc)
4418 unsigned flags = pFormat[1];
4419 unsigned index = *(const WORD*)&pFormat[2];
4420 DWORD memsize = *(const WORD*)&pFormat[4];
4421 unsigned char *saved_buffer = NULL;
4422 USER_MARSHAL_CB umcb;
4424 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4425 TRACE("index=%d\n", index);
4427 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4429 if (flags & USER_MARSHAL_POINTER)
4431 align_pointer(&pStubMsg->Buffer, 4);
4432 /* skip pointer prefix */
4433 pStubMsg->Buffer += 4;
4434 if (pStubMsg->PointerBufferMark)
4436 saved_buffer = pStubMsg->Buffer;
4437 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4438 pStubMsg->PointerBufferMark = NULL;
4440 align_pointer(&pStubMsg->Buffer, 8);
4442 else
4443 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4445 if (!fMustAlloc && !*ppMemory)
4446 fMustAlloc = TRUE;
4447 if (fMustAlloc)
4449 *ppMemory = NdrAllocate(pStubMsg, memsize);
4450 memset(*ppMemory, 0, memsize);
4453 pStubMsg->Buffer =
4454 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4455 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4457 if (saved_buffer)
4459 STD_OVERFLOW_CHECK(pStubMsg);
4460 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4461 pStubMsg->Buffer = saved_buffer;
4464 return NULL;
4467 /***********************************************************************
4468 * NdrUserMarshalBufferSize [RPCRT4.@]
4470 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4471 unsigned char *pMemory,
4472 PFORMAT_STRING pFormat)
4474 unsigned flags = pFormat[1];
4475 unsigned index = *(const WORD*)&pFormat[2];
4476 DWORD bufsize = *(const WORD*)&pFormat[6];
4477 USER_MARSHAL_CB umcb;
4478 ULONG saved_buffer_length = 0;
4480 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4481 TRACE("index=%d\n", index);
4483 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4485 if (flags & USER_MARSHAL_POINTER)
4487 align_length(&pStubMsg->BufferLength, 4);
4488 /* skip pointer prefix */
4489 safe_buffer_length_increment(pStubMsg, 4);
4490 if (pStubMsg->IgnoreEmbeddedPointers)
4491 return;
4492 if (pStubMsg->PointerLength)
4494 saved_buffer_length = pStubMsg->BufferLength;
4495 pStubMsg->BufferLength = pStubMsg->PointerLength;
4496 pStubMsg->PointerLength = 0;
4498 align_length(&pStubMsg->BufferLength, 8);
4500 else
4501 align_length(&pStubMsg->BufferLength, (flags & 0xf) + 1);
4503 if (bufsize) {
4504 TRACE("size=%d\n", bufsize);
4505 safe_buffer_length_increment(pStubMsg, bufsize);
4507 else
4508 pStubMsg->BufferLength =
4509 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4510 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4512 if (saved_buffer_length)
4514 pStubMsg->PointerLength = pStubMsg->BufferLength;
4515 pStubMsg->BufferLength = saved_buffer_length;
4520 /***********************************************************************
4521 * NdrUserMarshalMemorySize [RPCRT4.@]
4523 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4524 PFORMAT_STRING pFormat)
4526 unsigned flags = pFormat[1];
4527 unsigned index = *(const WORD*)&pFormat[2];
4528 DWORD memsize = *(const WORD*)&pFormat[4];
4529 DWORD bufsize = *(const WORD*)&pFormat[6];
4531 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4532 TRACE("index=%d\n", index);
4534 pStubMsg->MemorySize += memsize;
4536 if (flags & USER_MARSHAL_POINTER)
4538 align_pointer(&pStubMsg->Buffer, 4);
4539 /* skip pointer prefix */
4540 pStubMsg->Buffer += 4;
4541 if (pStubMsg->IgnoreEmbeddedPointers)
4542 return pStubMsg->MemorySize;
4543 align_pointer(&pStubMsg->Buffer, 8);
4545 else
4546 align_pointer(&pStubMsg->Buffer, (flags & 0xf) + 1);
4548 if (!bufsize)
4549 FIXME("not implemented for varying buffer size\n");
4551 pStubMsg->Buffer += bufsize;
4553 return pStubMsg->MemorySize;
4556 /***********************************************************************
4557 * NdrUserMarshalFree [RPCRT4.@]
4559 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4560 unsigned char *pMemory,
4561 PFORMAT_STRING pFormat)
4563 /* unsigned flags = pFormat[1]; */
4564 unsigned index = *(const WORD*)&pFormat[2];
4565 USER_MARSHAL_CB umcb;
4567 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4568 TRACE("index=%d\n", index);
4570 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4572 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4573 &umcb.Flags, pMemory);
4576 /***********************************************************************
4577 * NdrGetUserMarshalInfo [RPCRT4.@]
4579 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4581 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4583 TRACE("(%p,%u,%p)\n", flags, level, umi);
4585 if (level != 1)
4586 return RPC_S_INVALID_ARG;
4588 memset(&umi->u1.Level1, 0, sizeof(umi->u1.Level1));
4589 umi->InformationLevel = level;
4591 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4592 return RPC_S_INVALID_ARG;
4594 umi->u1.Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4595 umi->u1.Level1.pfnFree = umcb->pStubMsg->pfnFree;
4596 umi->u1.Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4598 switch (umcb->CBType)
4600 case USER_MARSHAL_CB_MARSHALL:
4601 case USER_MARSHAL_CB_UNMARSHALL:
4603 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4604 unsigned char *buffer_start = msg->Buffer;
4605 unsigned char *buffer_end =
4606 (unsigned char *)msg->Buffer + msg->BufferLength;
4608 if (umcb->pStubMsg->Buffer < buffer_start ||
4609 umcb->pStubMsg->Buffer > buffer_end)
4610 return RPC_X_INVALID_BUFFER;
4612 umi->u1.Level1.Buffer = umcb->pStubMsg->Buffer;
4613 umi->u1.Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4614 break;
4616 case USER_MARSHAL_CB_BUFFER_SIZE:
4617 case USER_MARSHAL_CB_FREE:
4618 break;
4619 default:
4620 WARN("unrecognised CBType %d\n", umcb->CBType);
4623 return RPC_S_OK;
4626 /***********************************************************************
4627 * NdrClearOutParameters [RPCRT4.@]
4629 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4630 PFORMAT_STRING pFormat,
4631 void *ArgAddr)
4633 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4636 /***********************************************************************
4637 * NdrConvert [RPCRT4.@]
4639 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4641 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4642 /* FIXME: since this stub doesn't do any converting, the proper behavior
4643 is to raise an exception */
4646 /***********************************************************************
4647 * NdrConvert2 [RPCRT4.@]
4649 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4651 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4652 pStubMsg, pFormat, NumberParams);
4653 /* FIXME: since this stub doesn't do any converting, the proper behavior
4654 is to raise an exception */
4657 #include "pshpack1.h"
4658 typedef struct _NDR_CSTRUCT_FORMAT
4660 unsigned char type;
4661 unsigned char alignment;
4662 unsigned short memory_size;
4663 short offset_to_array_description;
4664 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4665 #include "poppack.h"
4667 /***********************************************************************
4668 * NdrConformantStructMarshall [RPCRT4.@]
4670 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4671 unsigned char *pMemory,
4672 PFORMAT_STRING pFormat)
4674 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4675 PFORMAT_STRING pCArrayFormat;
4676 ULONG esize, bufsize;
4678 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4680 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4681 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4683 ERR("invalid format type %x\n", pCStructFormat->type);
4684 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4685 return NULL;
4688 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4689 pCStructFormat->offset_to_array_description;
4690 if (*pCArrayFormat != RPC_FC_CARRAY)
4692 ERR("invalid array format type %x\n", pCStructFormat->type);
4693 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4694 return NULL;
4696 esize = *(const WORD*)(pCArrayFormat+2);
4698 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4699 pCArrayFormat + 4, 0);
4701 WriteConformance(pStubMsg);
4703 align_pointer_clear(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4705 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4707 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4708 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4710 ERR("integer overflow of memory_size %u with bufsize %u\n",
4711 pCStructFormat->memory_size, bufsize);
4712 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4714 /* copy constant sized part of struct */
4715 pStubMsg->BufferMark = pStubMsg->Buffer;
4716 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4718 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4719 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4721 return NULL;
4724 /***********************************************************************
4725 * NdrConformantStructUnmarshall [RPCRT4.@]
4727 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4728 unsigned char **ppMemory,
4729 PFORMAT_STRING pFormat,
4730 unsigned char fMustAlloc)
4732 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4733 PFORMAT_STRING pCArrayFormat;
4734 ULONG esize, bufsize;
4735 unsigned char *saved_buffer;
4737 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4739 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4740 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4742 ERR("invalid format type %x\n", pCStructFormat->type);
4743 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4744 return NULL;
4746 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4747 pCStructFormat->offset_to_array_description;
4748 if (*pCArrayFormat != RPC_FC_CARRAY)
4750 ERR("invalid array format type %x\n", pCStructFormat->type);
4751 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4752 return NULL;
4754 esize = *(const WORD*)(pCArrayFormat+2);
4756 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4758 align_pointer(&pStubMsg->Buffer, pCStructFormat->alignment + 1);
4760 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4762 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4763 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4765 ERR("integer overflow of memory_size %u with bufsize %u\n",
4766 pCStructFormat->memory_size, bufsize);
4767 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4770 if (fMustAlloc)
4772 SIZE_T size = pCStructFormat->memory_size + bufsize;
4773 *ppMemory = NdrAllocate(pStubMsg, size);
4775 else
4777 if (!pStubMsg->IsClient && !*ppMemory)
4778 /* for servers, we just point straight into the RPC buffer */
4779 *ppMemory = pStubMsg->Buffer;
4782 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4783 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4784 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4785 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4787 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4788 if (*ppMemory != saved_buffer)
4789 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4791 return NULL;
4794 /***********************************************************************
4795 * NdrConformantStructBufferSize [RPCRT4.@]
4797 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4798 unsigned char *pMemory,
4799 PFORMAT_STRING pFormat)
4801 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4802 PFORMAT_STRING pCArrayFormat;
4803 ULONG esize;
4805 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4807 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4808 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4810 ERR("invalid format type %x\n", pCStructFormat->type);
4811 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4812 return;
4814 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4815 pCStructFormat->offset_to_array_description;
4816 if (*pCArrayFormat != RPC_FC_CARRAY)
4818 ERR("invalid array format type %x\n", pCStructFormat->type);
4819 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4820 return;
4822 esize = *(const WORD*)(pCArrayFormat+2);
4824 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4825 SizeConformance(pStubMsg);
4827 align_length(&pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4829 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4831 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4832 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4834 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4835 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4838 /***********************************************************************
4839 * NdrConformantStructMemorySize [RPCRT4.@]
4841 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4842 PFORMAT_STRING pFormat)
4844 FIXME("stub\n");
4845 return 0;
4848 /***********************************************************************
4849 * NdrConformantStructFree [RPCRT4.@]
4851 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4852 unsigned char *pMemory,
4853 PFORMAT_STRING pFormat)
4855 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4856 PFORMAT_STRING pCArrayFormat;
4858 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4860 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4861 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4863 ERR("invalid format type %x\n", pCStructFormat->type);
4864 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4865 return;
4868 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4869 pCStructFormat->offset_to_array_description;
4870 if (*pCArrayFormat != RPC_FC_CARRAY)
4872 ERR("invalid array format type %x\n", pCStructFormat->type);
4873 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4874 return;
4877 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4878 pCArrayFormat + 4, 0);
4880 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4882 /* copy constant sized part of struct */
4883 pStubMsg->BufferMark = pStubMsg->Buffer;
4885 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4886 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4889 /***********************************************************************
4890 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4892 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4893 unsigned char *pMemory,
4894 PFORMAT_STRING pFormat)
4896 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4897 PFORMAT_STRING pCVArrayFormat;
4899 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4901 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4902 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4904 ERR("invalid format type %x\n", pCVStructFormat->type);
4905 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4906 return NULL;
4909 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4910 pCVStructFormat->offset_to_array_description;
4912 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4913 pMemory + pCVStructFormat->memory_size,
4914 pCVArrayFormat);
4916 align_pointer_clear(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4918 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4920 /* write constant sized part */
4921 pStubMsg->BufferMark = pStubMsg->Buffer;
4922 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4924 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4925 pMemory + pCVStructFormat->memory_size,
4926 pCVArrayFormat, FALSE /* fHasPointers */);
4928 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4930 return NULL;
4933 /***********************************************************************
4934 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4936 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4937 unsigned char **ppMemory,
4938 PFORMAT_STRING pFormat,
4939 unsigned char fMustAlloc)
4941 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4942 PFORMAT_STRING pCVArrayFormat;
4943 ULONG memsize, bufsize;
4944 unsigned char *saved_buffer, *saved_array_buffer;
4945 ULONG offset;
4946 unsigned char *array_memory;
4948 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4950 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4951 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4953 ERR("invalid format type %x\n", pCVStructFormat->type);
4954 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4955 return NULL;
4958 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4959 pCVStructFormat->offset_to_array_description;
4961 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4962 pCVArrayFormat);
4964 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4966 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4968 /* work out how much memory to allocate if we need to do so */
4969 if (!fMustAlloc && !*ppMemory)
4970 fMustAlloc = TRUE;
4971 if (fMustAlloc)
4973 SIZE_T size = pCVStructFormat->memory_size + memsize;
4974 *ppMemory = NdrAllocate(pStubMsg, size);
4977 /* mark the start of the constant data */
4978 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4979 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4981 array_memory = *ppMemory + pCVStructFormat->memory_size;
4982 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4983 &array_memory, pCVArrayFormat,
4984 FALSE /* fMustAlloc */,
4985 FALSE /* fUseServerBufferMemory */,
4986 FALSE /* fUnmarshall */);
4988 /* save offset in case unmarshalling pointers changes it */
4989 offset = pStubMsg->Offset;
4991 /* mark the start of the array data */
4992 saved_array_buffer = pStubMsg->Buffer;
4993 safe_buffer_increment(pStubMsg, bufsize);
4995 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4997 /* copy the constant data */
4998 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4999 /* copy the array data */
5000 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
5001 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
5002 saved_array_buffer, bufsize);
5004 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
5005 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
5006 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
5007 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
5009 return NULL;
5012 /***********************************************************************
5013 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5015 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5016 unsigned char *pMemory,
5017 PFORMAT_STRING pFormat)
5019 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5020 PFORMAT_STRING pCVArrayFormat;
5022 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5024 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5025 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5027 ERR("invalid format type %x\n", pCVStructFormat->type);
5028 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5029 return;
5032 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5033 pCVStructFormat->offset_to_array_description;
5034 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
5035 pMemory + pCVStructFormat->memory_size,
5036 pCVArrayFormat);
5038 align_length(&pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
5040 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5042 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
5044 array_buffer_size(*pCVArrayFormat, pStubMsg,
5045 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5046 FALSE /* fHasPointers */);
5048 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5051 /***********************************************************************
5052 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5054 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5055 PFORMAT_STRING pFormat)
5057 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5058 PFORMAT_STRING pCVArrayFormat;
5060 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5062 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5063 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5065 ERR("invalid format type %x\n", pCVStructFormat->type);
5066 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5067 return 0;
5070 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5071 pCVStructFormat->offset_to_array_description;
5072 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
5074 align_pointer(&pStubMsg->Buffer, pCVStructFormat->alignment + 1);
5076 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5078 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
5079 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
5080 FALSE /* fHasPointers */);
5082 pStubMsg->MemorySize += pCVStructFormat->memory_size;
5084 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5086 return pStubMsg->MemorySize;
5089 /***********************************************************************
5090 * NdrConformantVaryingStructFree [RPCRT4.@]
5092 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
5093 unsigned char *pMemory,
5094 PFORMAT_STRING pFormat)
5096 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
5097 PFORMAT_STRING pCVArrayFormat;
5099 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5101 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
5102 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
5104 ERR("invalid format type %x\n", pCVStructFormat->type);
5105 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5106 return;
5109 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
5110 pCVStructFormat->offset_to_array_description;
5111 array_free(*pCVArrayFormat, pStubMsg,
5112 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
5113 FALSE /* fHasPointers */);
5115 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
5117 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5120 #include "pshpack1.h"
5121 typedef struct
5123 unsigned char type;
5124 unsigned char alignment;
5125 unsigned short total_size;
5126 } NDR_SMFARRAY_FORMAT;
5128 typedef struct
5130 unsigned char type;
5131 unsigned char alignment;
5132 ULONG total_size;
5133 } NDR_LGFARRAY_FORMAT;
5134 #include "poppack.h"
5136 /***********************************************************************
5137 * NdrFixedArrayMarshall [RPCRT4.@]
5139 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5140 unsigned char *pMemory,
5141 PFORMAT_STRING pFormat)
5143 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5144 ULONG total_size;
5146 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5148 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5149 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5151 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5152 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5153 return NULL;
5156 align_pointer_clear(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5158 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5160 total_size = pSmFArrayFormat->total_size;
5161 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5163 else
5165 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5166 total_size = pLgFArrayFormat->total_size;
5167 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5170 pStubMsg->BufferMark = pStubMsg->Buffer;
5171 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
5173 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5175 return NULL;
5178 /***********************************************************************
5179 * NdrFixedArrayUnmarshall [RPCRT4.@]
5181 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5182 unsigned char **ppMemory,
5183 PFORMAT_STRING pFormat,
5184 unsigned char fMustAlloc)
5186 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5187 ULONG total_size;
5188 unsigned char *saved_buffer;
5190 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5192 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5193 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5195 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5196 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5197 return NULL;
5200 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5202 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5204 total_size = pSmFArrayFormat->total_size;
5205 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5207 else
5209 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5210 total_size = pLgFArrayFormat->total_size;
5211 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5214 if (fMustAlloc)
5215 *ppMemory = NdrAllocate(pStubMsg, total_size);
5216 else
5218 if (!pStubMsg->IsClient && !*ppMemory)
5219 /* for servers, we just point straight into the RPC buffer */
5220 *ppMemory = pStubMsg->Buffer;
5223 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5224 safe_buffer_increment(pStubMsg, total_size);
5225 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5227 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5228 if (*ppMemory != saved_buffer)
5229 memcpy(*ppMemory, saved_buffer, total_size);
5231 return NULL;
5234 /***********************************************************************
5235 * NdrFixedArrayBufferSize [RPCRT4.@]
5237 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5238 unsigned char *pMemory,
5239 PFORMAT_STRING pFormat)
5241 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5242 ULONG total_size;
5244 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5246 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5247 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5249 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5250 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5251 return;
5254 align_length(&pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5256 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5258 total_size = pSmFArrayFormat->total_size;
5259 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5261 else
5263 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5264 total_size = pLgFArrayFormat->total_size;
5265 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5267 safe_buffer_length_increment(pStubMsg, total_size);
5269 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5272 /***********************************************************************
5273 * NdrFixedArrayMemorySize [RPCRT4.@]
5275 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5276 PFORMAT_STRING pFormat)
5278 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5279 ULONG total_size;
5281 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5283 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5284 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5286 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5287 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5288 return 0;
5291 align_pointer(&pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5293 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5295 total_size = pSmFArrayFormat->total_size;
5296 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5298 else
5300 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5301 total_size = pLgFArrayFormat->total_size;
5302 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5304 pStubMsg->BufferMark = pStubMsg->Buffer;
5305 safe_buffer_increment(pStubMsg, total_size);
5306 pStubMsg->MemorySize += total_size;
5308 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5310 return total_size;
5313 /***********************************************************************
5314 * NdrFixedArrayFree [RPCRT4.@]
5316 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5317 unsigned char *pMemory,
5318 PFORMAT_STRING pFormat)
5320 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5322 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5324 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5325 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5327 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5328 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5329 return;
5332 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5333 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5334 else
5336 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5337 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5340 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5343 /***********************************************************************
5344 * NdrVaryingArrayMarshall [RPCRT4.@]
5346 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5347 unsigned char *pMemory,
5348 PFORMAT_STRING pFormat)
5350 unsigned char alignment;
5351 DWORD elements, esize;
5352 ULONG bufsize;
5354 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5356 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5357 (pFormat[0] != RPC_FC_LGVARRAY))
5359 ERR("invalid format type %x\n", pFormat[0]);
5360 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5361 return NULL;
5364 alignment = pFormat[1] + 1;
5366 if (pFormat[0] == RPC_FC_SMVARRAY)
5368 pFormat += 2;
5369 pFormat += sizeof(WORD);
5370 elements = *(const WORD*)pFormat;
5371 pFormat += sizeof(WORD);
5373 else
5375 pFormat += 2;
5376 pFormat += sizeof(DWORD);
5377 elements = *(const DWORD*)pFormat;
5378 pFormat += sizeof(DWORD);
5381 esize = *(const WORD*)pFormat;
5382 pFormat += sizeof(WORD);
5384 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5385 if ((pStubMsg->ActualCount > elements) ||
5386 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5388 RpcRaiseException(RPC_S_INVALID_BOUND);
5389 return NULL;
5392 WriteVariance(pStubMsg);
5394 align_pointer_clear(&pStubMsg->Buffer, alignment);
5396 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5397 pStubMsg->BufferMark = pStubMsg->Buffer;
5398 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5400 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5402 return NULL;
5405 /***********************************************************************
5406 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5408 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5409 unsigned char **ppMemory,
5410 PFORMAT_STRING pFormat,
5411 unsigned char fMustAlloc)
5413 unsigned char alignment;
5414 DWORD size, elements, esize;
5415 ULONG bufsize;
5416 unsigned char *saved_buffer;
5417 ULONG offset;
5419 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5421 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5422 (pFormat[0] != RPC_FC_LGVARRAY))
5424 ERR("invalid format type %x\n", pFormat[0]);
5425 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5426 return NULL;
5429 alignment = pFormat[1] + 1;
5431 if (pFormat[0] == RPC_FC_SMVARRAY)
5433 pFormat += 2;
5434 size = *(const WORD*)pFormat;
5435 pFormat += sizeof(WORD);
5436 elements = *(const WORD*)pFormat;
5437 pFormat += sizeof(WORD);
5439 else
5441 pFormat += 2;
5442 size = *(const DWORD*)pFormat;
5443 pFormat += sizeof(DWORD);
5444 elements = *(const DWORD*)pFormat;
5445 pFormat += sizeof(DWORD);
5448 esize = *(const WORD*)pFormat;
5449 pFormat += sizeof(WORD);
5451 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5453 align_pointer(&pStubMsg->Buffer, alignment);
5455 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5456 offset = pStubMsg->Offset;
5458 if (!fMustAlloc && !*ppMemory)
5459 fMustAlloc = TRUE;
5460 if (fMustAlloc)
5461 *ppMemory = NdrAllocate(pStubMsg, size);
5462 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5463 safe_buffer_increment(pStubMsg, bufsize);
5465 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5467 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5469 return NULL;
5472 /***********************************************************************
5473 * NdrVaryingArrayBufferSize [RPCRT4.@]
5475 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5476 unsigned char *pMemory,
5477 PFORMAT_STRING pFormat)
5479 unsigned char alignment;
5480 DWORD elements, esize;
5482 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5484 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5485 (pFormat[0] != RPC_FC_LGVARRAY))
5487 ERR("invalid format type %x\n", pFormat[0]);
5488 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5489 return;
5492 alignment = pFormat[1] + 1;
5494 if (pFormat[0] == RPC_FC_SMVARRAY)
5496 pFormat += 2;
5497 pFormat += sizeof(WORD);
5498 elements = *(const WORD*)pFormat;
5499 pFormat += sizeof(WORD);
5501 else
5503 pFormat += 2;
5504 pFormat += sizeof(DWORD);
5505 elements = *(const DWORD*)pFormat;
5506 pFormat += sizeof(DWORD);
5509 esize = *(const WORD*)pFormat;
5510 pFormat += sizeof(WORD);
5512 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5513 if ((pStubMsg->ActualCount > elements) ||
5514 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5516 RpcRaiseException(RPC_S_INVALID_BOUND);
5517 return;
5520 SizeVariance(pStubMsg);
5522 align_length(&pStubMsg->BufferLength, alignment);
5524 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5526 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5529 /***********************************************************************
5530 * NdrVaryingArrayMemorySize [RPCRT4.@]
5532 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5533 PFORMAT_STRING pFormat)
5535 unsigned char alignment;
5536 DWORD size, elements, esize;
5538 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5540 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5541 (pFormat[0] != RPC_FC_LGVARRAY))
5543 ERR("invalid format type %x\n", pFormat[0]);
5544 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5545 return 0;
5548 alignment = pFormat[1] + 1;
5550 if (pFormat[0] == RPC_FC_SMVARRAY)
5552 pFormat += 2;
5553 size = *(const WORD*)pFormat;
5554 pFormat += sizeof(WORD);
5555 elements = *(const WORD*)pFormat;
5556 pFormat += sizeof(WORD);
5558 else
5560 pFormat += 2;
5561 size = *(const DWORD*)pFormat;
5562 pFormat += sizeof(DWORD);
5563 elements = *(const DWORD*)pFormat;
5564 pFormat += sizeof(DWORD);
5567 esize = *(const WORD*)pFormat;
5568 pFormat += sizeof(WORD);
5570 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5572 align_pointer(&pStubMsg->Buffer, alignment);
5574 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5575 pStubMsg->MemorySize += size;
5577 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5579 return pStubMsg->MemorySize;
5582 /***********************************************************************
5583 * NdrVaryingArrayFree [RPCRT4.@]
5585 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5586 unsigned char *pMemory,
5587 PFORMAT_STRING pFormat)
5589 DWORD elements;
5591 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5593 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5594 (pFormat[0] != RPC_FC_LGVARRAY))
5596 ERR("invalid format type %x\n", pFormat[0]);
5597 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5598 return;
5601 if (pFormat[0] == RPC_FC_SMVARRAY)
5603 pFormat += 2;
5604 pFormat += sizeof(WORD);
5605 elements = *(const WORD*)pFormat;
5606 pFormat += sizeof(WORD);
5608 else
5610 pFormat += 2;
5611 pFormat += sizeof(DWORD);
5612 elements = *(const DWORD*)pFormat;
5613 pFormat += sizeof(DWORD);
5616 pFormat += sizeof(WORD);
5618 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5619 if ((pStubMsg->ActualCount > elements) ||
5620 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5622 RpcRaiseException(RPC_S_INVALID_BOUND);
5623 return;
5626 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5629 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5631 switch (fc)
5633 case RPC_FC_BYTE:
5634 case RPC_FC_CHAR:
5635 case RPC_FC_SMALL:
5636 case RPC_FC_USMALL:
5637 return *pMemory;
5638 case RPC_FC_WCHAR:
5639 case RPC_FC_SHORT:
5640 case RPC_FC_USHORT:
5641 case RPC_FC_ENUM16:
5642 return *(const USHORT *)pMemory;
5643 case RPC_FC_LONG:
5644 case RPC_FC_ULONG:
5645 case RPC_FC_ENUM32:
5646 return *(const ULONG *)pMemory;
5647 case RPC_FC_INT3264:
5648 case RPC_FC_UINT3264:
5649 return *(const ULONG_PTR *)pMemory;
5650 default:
5651 FIXME("Unhandled base type: 0x%02x\n", fc);
5652 return 0;
5656 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5657 ULONG discriminant,
5658 PFORMAT_STRING pFormat)
5660 unsigned short num_arms, arm, type;
5662 num_arms = *(const SHORT*)pFormat & 0x0fff;
5663 pFormat += 2;
5664 for(arm = 0; arm < num_arms; arm++)
5666 if(discriminant == *(const ULONG*)pFormat)
5668 pFormat += 4;
5669 break;
5671 pFormat += 6;
5674 type = *(const unsigned short*)pFormat;
5675 TRACE("type %04x\n", type);
5676 if(arm == num_arms) /* default arm extras */
5678 if(type == 0xffff)
5680 ERR("no arm for 0x%x and no default case\n", discriminant);
5681 RpcRaiseException(RPC_S_INVALID_TAG);
5682 return NULL;
5684 if(type == 0)
5686 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5687 return NULL;
5690 return pFormat;
5693 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5695 unsigned short type;
5697 pFormat += 2;
5699 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5700 if(!pFormat)
5701 return NULL;
5703 type = *(const unsigned short*)pFormat;
5704 if((type & 0xff00) == 0x8000)
5706 unsigned char basetype = LOBYTE(type);
5707 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5709 else
5711 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5712 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5713 if (m)
5715 unsigned char *saved_buffer = NULL;
5716 BOOL pointer_buffer_mark_set = FALSE;
5717 switch(*desc)
5719 case RPC_FC_RP:
5720 case RPC_FC_UP:
5721 case RPC_FC_OP:
5722 case RPC_FC_FP:
5723 align_pointer_clear(&pStubMsg->Buffer, 4);
5724 saved_buffer = pStubMsg->Buffer;
5725 if (pStubMsg->PointerBufferMark)
5727 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5728 pStubMsg->PointerBufferMark = NULL;
5729 pointer_buffer_mark_set = TRUE;
5731 else
5732 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5734 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5735 if (pointer_buffer_mark_set)
5737 STD_OVERFLOW_CHECK(pStubMsg);
5738 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5739 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5741 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5742 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5743 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5745 pStubMsg->Buffer = saved_buffer + 4;
5747 break;
5748 default:
5749 m(pStubMsg, pMemory, desc);
5752 else FIXME("no marshaller for embedded type %02x\n", *desc);
5754 return NULL;
5757 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5758 unsigned char **ppMemory,
5759 ULONG discriminant,
5760 PFORMAT_STRING pFormat,
5761 unsigned char fMustAlloc)
5763 unsigned short type;
5765 pFormat += 2;
5767 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5768 if(!pFormat)
5769 return NULL;
5771 type = *(const unsigned short*)pFormat;
5772 if((type & 0xff00) == 0x8000)
5774 unsigned char basetype = LOBYTE(type);
5775 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5777 else
5779 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5780 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5781 if (m)
5783 unsigned char *saved_buffer = NULL;
5784 BOOL pointer_buffer_mark_set = FALSE;
5785 switch(*desc)
5787 case RPC_FC_RP:
5788 case RPC_FC_UP:
5789 case RPC_FC_OP:
5790 case RPC_FC_FP:
5791 align_pointer(&pStubMsg->Buffer, 4);
5792 saved_buffer = pStubMsg->Buffer;
5793 if (pStubMsg->PointerBufferMark)
5795 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5796 pStubMsg->PointerBufferMark = NULL;
5797 pointer_buffer_mark_set = TRUE;
5799 else
5800 pStubMsg->Buffer += 4; /* for pointer ID */
5802 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5804 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5805 saved_buffer, pStubMsg->BufferEnd);
5806 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5809 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5810 if (pointer_buffer_mark_set)
5812 STD_OVERFLOW_CHECK(pStubMsg);
5813 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5814 pStubMsg->Buffer = saved_buffer + 4;
5816 break;
5817 default:
5818 m(pStubMsg, ppMemory, desc, fMustAlloc);
5821 else FIXME("no marshaller for embedded type %02x\n", *desc);
5823 return NULL;
5826 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5827 unsigned char *pMemory,
5828 ULONG discriminant,
5829 PFORMAT_STRING pFormat)
5831 unsigned short type;
5833 pFormat += 2;
5835 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5836 if(!pFormat)
5837 return;
5839 type = *(const unsigned short*)pFormat;
5840 if((type & 0xff00) == 0x8000)
5842 unsigned char basetype = LOBYTE(type);
5843 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5845 else
5847 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5848 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5849 if (m)
5851 switch(*desc)
5853 case RPC_FC_RP:
5854 case RPC_FC_UP:
5855 case RPC_FC_OP:
5856 case RPC_FC_FP:
5857 align_length(&pStubMsg->BufferLength, 4);
5858 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5859 if (!pStubMsg->IgnoreEmbeddedPointers)
5861 int saved_buffer_length = pStubMsg->BufferLength;
5862 pStubMsg->BufferLength = pStubMsg->PointerLength;
5863 pStubMsg->PointerLength = 0;
5864 if(!pStubMsg->BufferLength)
5865 ERR("BufferLength == 0??\n");
5866 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5867 pStubMsg->PointerLength = pStubMsg->BufferLength;
5868 pStubMsg->BufferLength = saved_buffer_length;
5870 break;
5871 default:
5872 m(pStubMsg, pMemory, desc);
5875 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5879 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5880 ULONG discriminant,
5881 PFORMAT_STRING pFormat)
5883 unsigned short type, size;
5885 size = *(const unsigned short*)pFormat;
5886 pStubMsg->Memory += size;
5887 pFormat += 2;
5889 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5890 if(!pFormat)
5891 return 0;
5893 type = *(const unsigned short*)pFormat;
5894 if((type & 0xff00) == 0x8000)
5896 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5898 else
5900 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5901 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5902 unsigned char *saved_buffer;
5903 if (m)
5905 switch(*desc)
5907 case RPC_FC_RP:
5908 case RPC_FC_UP:
5909 case RPC_FC_OP:
5910 case RPC_FC_FP:
5911 align_pointer(&pStubMsg->Buffer, 4);
5912 saved_buffer = pStubMsg->Buffer;
5913 safe_buffer_increment(pStubMsg, 4);
5914 align_length(&pStubMsg->MemorySize, sizeof(void *));
5915 pStubMsg->MemorySize += sizeof(void *);
5916 if (!pStubMsg->IgnoreEmbeddedPointers)
5917 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5918 break;
5919 default:
5920 return m(pStubMsg, desc);
5923 else FIXME("no marshaller for embedded type %02x\n", *desc);
5926 TRACE("size %d\n", size);
5927 return size;
5930 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5931 unsigned char *pMemory,
5932 ULONG discriminant,
5933 PFORMAT_STRING pFormat)
5935 unsigned short type;
5937 pFormat += 2;
5939 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5940 if(!pFormat)
5941 return;
5943 type = *(const unsigned short*)pFormat;
5944 if((type & 0xff00) != 0x8000)
5946 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5947 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5948 if (m)
5950 switch(*desc)
5952 case RPC_FC_RP:
5953 case RPC_FC_UP:
5954 case RPC_FC_OP:
5955 case RPC_FC_FP:
5956 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5957 break;
5958 default:
5959 m(pStubMsg, pMemory, desc);
5965 /***********************************************************************
5966 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5968 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5969 unsigned char *pMemory,
5970 PFORMAT_STRING pFormat)
5972 unsigned char switch_type;
5973 unsigned char increment;
5974 ULONG switch_value;
5976 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5977 pFormat++;
5979 switch_type = *pFormat & 0xf;
5980 increment = (*pFormat & 0xf0) >> 4;
5981 pFormat++;
5983 align_pointer_clear(&pStubMsg->Buffer, increment);
5985 switch_value = get_discriminant(switch_type, pMemory);
5986 TRACE("got switch value 0x%x\n", switch_value);
5988 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5989 pMemory += increment;
5991 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5994 /***********************************************************************
5995 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5997 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5998 unsigned char **ppMemory,
5999 PFORMAT_STRING pFormat,
6000 unsigned char fMustAlloc)
6002 unsigned char switch_type;
6003 unsigned char increment;
6004 ULONG switch_value;
6005 unsigned short size;
6006 unsigned char *pMemoryArm;
6008 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6009 pFormat++;
6011 switch_type = *pFormat & 0xf;
6012 increment = (*pFormat & 0xf0) >> 4;
6013 pFormat++;
6015 align_pointer(&pStubMsg->Buffer, increment);
6016 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6017 TRACE("got switch value 0x%x\n", switch_value);
6019 size = *(const unsigned short*)pFormat + increment;
6020 if (!fMustAlloc && !*ppMemory)
6021 fMustAlloc = TRUE;
6022 if (fMustAlloc)
6023 *ppMemory = NdrAllocate(pStubMsg, size);
6025 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6026 * since the arm is part of the memory block that is encompassed by
6027 * the whole union. Memory is forced to allocate when pointers
6028 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6029 * clearing the memory we pass in to the unmarshaller */
6030 if (fMustAlloc)
6031 memset(*ppMemory, 0, size);
6033 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
6034 pMemoryArm = *ppMemory + increment;
6036 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
6039 /***********************************************************************
6040 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6042 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6043 unsigned char *pMemory,
6044 PFORMAT_STRING pFormat)
6046 unsigned char switch_type;
6047 unsigned char increment;
6048 ULONG switch_value;
6050 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6051 pFormat++;
6053 switch_type = *pFormat & 0xf;
6054 increment = (*pFormat & 0xf0) >> 4;
6055 pFormat++;
6057 align_length(&pStubMsg->BufferLength, increment);
6058 switch_value = get_discriminant(switch_type, pMemory);
6059 TRACE("got switch value 0x%x\n", switch_value);
6061 /* Add discriminant size */
6062 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
6063 pMemory += increment;
6065 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
6068 /***********************************************************************
6069 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6071 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6072 PFORMAT_STRING pFormat)
6074 unsigned char switch_type;
6075 unsigned char increment;
6076 ULONG switch_value;
6078 switch_type = *pFormat & 0xf;
6079 increment = (*pFormat & 0xf0) >> 4;
6080 pFormat++;
6082 align_pointer(&pStubMsg->Buffer, increment);
6083 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
6084 TRACE("got switch value 0x%x\n", switch_value);
6086 pStubMsg->Memory += increment;
6088 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
6091 /***********************************************************************
6092 * NdrEncapsulatedUnionFree [RPCRT4.@]
6094 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6095 unsigned char *pMemory,
6096 PFORMAT_STRING pFormat)
6098 unsigned char switch_type;
6099 unsigned char increment;
6100 ULONG switch_value;
6102 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6103 pFormat++;
6105 switch_type = *pFormat & 0xf;
6106 increment = (*pFormat & 0xf0) >> 4;
6107 pFormat++;
6109 switch_value = get_discriminant(switch_type, pMemory);
6110 TRACE("got switch value 0x%x\n", switch_value);
6112 pMemory += increment;
6114 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
6117 /***********************************************************************
6118 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6120 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6121 unsigned char *pMemory,
6122 PFORMAT_STRING pFormat)
6124 unsigned char switch_type;
6126 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6127 pFormat++;
6129 switch_type = *pFormat;
6130 pFormat++;
6132 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6133 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6134 /* Marshall discriminant */
6135 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6137 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6140 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
6141 PFORMAT_STRING *ppFormat)
6143 LONG discriminant = 0;
6145 switch(**ppFormat)
6147 case RPC_FC_BYTE:
6148 case RPC_FC_CHAR:
6149 case RPC_FC_SMALL:
6150 case RPC_FC_USMALL:
6152 UCHAR d;
6153 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6154 discriminant = d;
6155 break;
6157 case RPC_FC_WCHAR:
6158 case RPC_FC_SHORT:
6159 case RPC_FC_USHORT:
6160 case RPC_FC_ENUM16:
6162 USHORT d;
6163 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6164 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6165 discriminant = d;
6166 break;
6168 case RPC_FC_LONG:
6169 case RPC_FC_ULONG:
6171 ULONG d;
6172 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6173 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
6174 discriminant = d;
6175 break;
6177 default:
6178 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
6180 (*ppFormat)++;
6182 *ppFormat = SkipConformance(pStubMsg, *ppFormat);
6183 return discriminant;
6186 /**********************************************************************
6187 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6189 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6190 unsigned char **ppMemory,
6191 PFORMAT_STRING pFormat,
6192 unsigned char fMustAlloc)
6194 LONG discriminant;
6195 unsigned short size;
6197 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
6198 pFormat++;
6200 /* Unmarshall discriminant */
6201 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6202 TRACE("unmarshalled discriminant %x\n", discriminant);
6204 pFormat += *(const SHORT*)pFormat;
6206 size = *(const unsigned short*)pFormat;
6208 if (!fMustAlloc && !*ppMemory)
6209 fMustAlloc = TRUE;
6210 if (fMustAlloc)
6211 *ppMemory = NdrAllocate(pStubMsg, size);
6213 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6214 * since the arm is part of the memory block that is encompassed by
6215 * the whole union. Memory is forced to allocate when pointers
6216 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6217 * clearing the memory we pass in to the unmarshaller */
6218 if (fMustAlloc)
6219 memset(*ppMemory, 0, size);
6221 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
6224 /***********************************************************************
6225 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6227 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6228 unsigned char *pMemory,
6229 PFORMAT_STRING pFormat)
6231 unsigned char switch_type;
6233 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6234 pFormat++;
6236 switch_type = *pFormat;
6237 pFormat++;
6239 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6240 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6241 /* Add discriminant size */
6242 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6244 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6247 /***********************************************************************
6248 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6250 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6251 PFORMAT_STRING pFormat)
6253 ULONG discriminant;
6255 pFormat++;
6256 /* Unmarshall discriminant */
6257 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6258 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6260 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6263 /***********************************************************************
6264 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6266 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6267 unsigned char *pMemory,
6268 PFORMAT_STRING pFormat)
6270 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6271 pFormat++;
6272 pFormat++;
6274 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6275 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6277 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6280 /***********************************************************************
6281 * NdrByteCountPointerMarshall [RPCRT4.@]
6283 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6284 unsigned char *pMemory,
6285 PFORMAT_STRING pFormat)
6287 FIXME("stub\n");
6288 return NULL;
6291 /***********************************************************************
6292 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6294 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6295 unsigned char **ppMemory,
6296 PFORMAT_STRING pFormat,
6297 unsigned char fMustAlloc)
6299 FIXME("stub\n");
6300 return NULL;
6303 /***********************************************************************
6304 * NdrByteCountPointerBufferSize [RPCRT4.@]
6306 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6307 unsigned char *pMemory,
6308 PFORMAT_STRING pFormat)
6310 FIXME("stub\n");
6313 /***********************************************************************
6314 * NdrByteCountPointerMemorySize [internal]
6316 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6317 PFORMAT_STRING pFormat)
6319 FIXME("stub\n");
6320 return 0;
6323 /***********************************************************************
6324 * NdrByteCountPointerFree [RPCRT4.@]
6326 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6327 unsigned char *pMemory,
6328 PFORMAT_STRING pFormat)
6330 FIXME("stub\n");
6333 /***********************************************************************
6334 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6336 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6337 unsigned char *pMemory,
6338 PFORMAT_STRING pFormat)
6340 FIXME("stub\n");
6341 return NULL;
6344 /***********************************************************************
6345 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6347 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6348 unsigned char **ppMemory,
6349 PFORMAT_STRING pFormat,
6350 unsigned char fMustAlloc)
6352 FIXME("stub\n");
6353 return NULL;
6356 /***********************************************************************
6357 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6359 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6360 unsigned char *pMemory,
6361 PFORMAT_STRING pFormat)
6363 FIXME("stub\n");
6366 /***********************************************************************
6367 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6369 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6370 PFORMAT_STRING pFormat)
6372 FIXME("stub\n");
6373 return 0;
6376 /***********************************************************************
6377 * NdrXmitOrRepAsFree [RPCRT4.@]
6379 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6380 unsigned char *pMemory,
6381 PFORMAT_STRING pFormat)
6383 FIXME("stub\n");
6386 /***********************************************************************
6387 * NdrRangeMarshall [internal]
6389 static unsigned char *WINAPI NdrRangeMarshall(
6390 PMIDL_STUB_MESSAGE pStubMsg,
6391 unsigned char *pMemory,
6392 PFORMAT_STRING pFormat)
6394 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6395 unsigned char base_type;
6397 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6399 if (pRange->type != RPC_FC_RANGE)
6401 ERR("invalid format type %x\n", pRange->type);
6402 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6403 return NULL;
6406 base_type = pRange->flags_type & 0xf;
6408 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6411 /***********************************************************************
6412 * NdrRangeUnmarshall [RPCRT4.@]
6414 unsigned char *WINAPI NdrRangeUnmarshall(
6415 PMIDL_STUB_MESSAGE pStubMsg,
6416 unsigned char **ppMemory,
6417 PFORMAT_STRING pFormat,
6418 unsigned char fMustAlloc)
6420 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6421 unsigned char base_type;
6423 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6425 if (pRange->type != RPC_FC_RANGE)
6427 ERR("invalid format type %x\n", pRange->type);
6428 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6429 return NULL;
6431 base_type = pRange->flags_type & 0xf;
6433 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6434 base_type, pRange->low_value, pRange->high_value);
6436 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6437 do \
6439 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6440 if (!fMustAlloc && !*ppMemory) \
6441 fMustAlloc = TRUE; \
6442 if (fMustAlloc) \
6443 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6444 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6446 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6447 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6448 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6450 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6451 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6453 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6454 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6455 (mem_type)pRange->high_value); \
6456 RpcRaiseException(RPC_S_INVALID_BOUND); \
6457 return NULL; \
6459 TRACE("*ppMemory: %p\n", *ppMemory); \
6460 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6461 pStubMsg->Buffer += sizeof(wire_type); \
6462 } while (0)
6464 switch(base_type)
6466 case RPC_FC_CHAR:
6467 case RPC_FC_SMALL:
6468 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6469 TRACE("value: 0x%02x\n", **ppMemory);
6470 break;
6471 case RPC_FC_BYTE:
6472 case RPC_FC_USMALL:
6473 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6474 TRACE("value: 0x%02x\n", **ppMemory);
6475 break;
6476 case RPC_FC_WCHAR: /* FIXME: valid? */
6477 case RPC_FC_USHORT:
6478 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6479 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6480 break;
6481 case RPC_FC_SHORT:
6482 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6483 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6484 break;
6485 case RPC_FC_LONG:
6486 case RPC_FC_ENUM32:
6487 RANGE_UNMARSHALL(LONG, LONG, "%d");
6488 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6489 break;
6490 case RPC_FC_ULONG:
6491 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6492 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6493 break;
6494 case RPC_FC_ENUM16:
6495 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6496 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6497 break;
6498 case RPC_FC_FLOAT:
6499 case RPC_FC_DOUBLE:
6500 case RPC_FC_HYPER:
6501 default:
6502 ERR("invalid range base type: 0x%02x\n", base_type);
6503 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6506 return NULL;
6509 /***********************************************************************
6510 * NdrRangeBufferSize [internal]
6512 static void WINAPI NdrRangeBufferSize(
6513 PMIDL_STUB_MESSAGE pStubMsg,
6514 unsigned char *pMemory,
6515 PFORMAT_STRING pFormat)
6517 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6518 unsigned char base_type;
6520 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6522 if (pRange->type != RPC_FC_RANGE)
6524 ERR("invalid format type %x\n", pRange->type);
6525 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6527 base_type = pRange->flags_type & 0xf;
6529 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6532 /***********************************************************************
6533 * NdrRangeMemorySize [internal]
6535 static ULONG WINAPI NdrRangeMemorySize(
6536 PMIDL_STUB_MESSAGE pStubMsg,
6537 PFORMAT_STRING pFormat)
6539 const NDR_RANGE *pRange = (const NDR_RANGE *)pFormat;
6540 unsigned char base_type;
6542 if (pRange->type != RPC_FC_RANGE)
6544 ERR("invalid format type %x\n", pRange->type);
6545 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6546 return 0;
6548 base_type = pRange->flags_type & 0xf;
6550 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6553 /***********************************************************************
6554 * NdrRangeFree [internal]
6556 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6557 unsigned char *pMemory,
6558 PFORMAT_STRING pFormat)
6560 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6562 /* nothing to do */
6565 /***********************************************************************
6566 * NdrBaseTypeMarshall [internal]
6568 static unsigned char *WINAPI NdrBaseTypeMarshall(
6569 PMIDL_STUB_MESSAGE pStubMsg,
6570 unsigned char *pMemory,
6571 PFORMAT_STRING pFormat)
6573 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6575 switch(*pFormat)
6577 case RPC_FC_BYTE:
6578 case RPC_FC_CHAR:
6579 case RPC_FC_SMALL:
6580 case RPC_FC_USMALL:
6581 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6582 TRACE("value: 0x%02x\n", *pMemory);
6583 break;
6584 case RPC_FC_WCHAR:
6585 case RPC_FC_SHORT:
6586 case RPC_FC_USHORT:
6587 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6588 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6589 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6590 break;
6591 case RPC_FC_LONG:
6592 case RPC_FC_ULONG:
6593 case RPC_FC_ERROR_STATUS_T:
6594 case RPC_FC_ENUM32:
6595 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONG));
6596 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6597 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6598 break;
6599 case RPC_FC_FLOAT:
6600 align_pointer_clear(&pStubMsg->Buffer, sizeof(float));
6601 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6602 break;
6603 case RPC_FC_DOUBLE:
6604 align_pointer_clear(&pStubMsg->Buffer, sizeof(double));
6605 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6606 break;
6607 case RPC_FC_HYPER:
6608 align_pointer_clear(&pStubMsg->Buffer, sizeof(ULONGLONG));
6609 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6610 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6611 break;
6612 case RPC_FC_ENUM16:
6614 USHORT val = *(UINT *)pMemory;
6615 /* only 16-bits on the wire, so do a sanity check */
6616 if (*(UINT *)pMemory > SHRT_MAX)
6617 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6618 align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
6619 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6620 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6621 break;
6623 case RPC_FC_INT3264:
6624 case RPC_FC_UINT3264:
6626 UINT val = *(UINT_PTR *)pMemory;
6627 align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
6628 safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
6629 break;
6631 case RPC_FC_IGNORE:
6632 break;
6633 default:
6634 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6637 /* FIXME: what is the correct return value? */
6638 return NULL;
6641 /***********************************************************************
6642 * NdrBaseTypeUnmarshall [internal]
6644 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6645 PMIDL_STUB_MESSAGE pStubMsg,
6646 unsigned char **ppMemory,
6647 PFORMAT_STRING pFormat,
6648 unsigned char fMustAlloc)
6650 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6652 #define BASE_TYPE_UNMARSHALL(type) do { \
6653 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6654 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6656 *ppMemory = pStubMsg->Buffer; \
6657 TRACE("*ppMemory: %p\n", *ppMemory); \
6658 safe_buffer_increment(pStubMsg, sizeof(type)); \
6660 else \
6662 if (fMustAlloc) \
6663 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6664 TRACE("*ppMemory: %p\n", *ppMemory); \
6665 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6667 } while (0)
6669 switch(*pFormat)
6671 case RPC_FC_BYTE:
6672 case RPC_FC_CHAR:
6673 case RPC_FC_SMALL:
6674 case RPC_FC_USMALL:
6675 BASE_TYPE_UNMARSHALL(UCHAR);
6676 TRACE("value: 0x%02x\n", **ppMemory);
6677 break;
6678 case RPC_FC_WCHAR:
6679 case RPC_FC_SHORT:
6680 case RPC_FC_USHORT:
6681 BASE_TYPE_UNMARSHALL(USHORT);
6682 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6683 break;
6684 case RPC_FC_LONG:
6685 case RPC_FC_ULONG:
6686 case RPC_FC_ERROR_STATUS_T:
6687 case RPC_FC_ENUM32:
6688 BASE_TYPE_UNMARSHALL(ULONG);
6689 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6690 break;
6691 case RPC_FC_FLOAT:
6692 BASE_TYPE_UNMARSHALL(float);
6693 TRACE("value: %f\n", **(float **)ppMemory);
6694 break;
6695 case RPC_FC_DOUBLE:
6696 BASE_TYPE_UNMARSHALL(double);
6697 TRACE("value: %f\n", **(double **)ppMemory);
6698 break;
6699 case RPC_FC_HYPER:
6700 BASE_TYPE_UNMARSHALL(ULONGLONG);
6701 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6702 break;
6703 case RPC_FC_ENUM16:
6705 USHORT val;
6706 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6707 if (!fMustAlloc && !*ppMemory)
6708 fMustAlloc = TRUE;
6709 if (fMustAlloc)
6710 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6711 safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
6712 /* 16-bits on the wire, but int in memory */
6713 **(UINT **)ppMemory = val;
6714 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6715 break;
6717 case RPC_FC_INT3264:
6718 if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
6719 else
6721 INT val;
6722 align_pointer(&pStubMsg->Buffer, sizeof(INT));
6723 if (!fMustAlloc && !*ppMemory)
6724 fMustAlloc = TRUE;
6725 if (fMustAlloc)
6726 *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
6727 safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
6728 **(INT_PTR **)ppMemory = val;
6729 TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
6731 break;
6732 case RPC_FC_UINT3264:
6733 if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
6734 else
6736 UINT val;
6737 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6738 if (!fMustAlloc && !*ppMemory)
6739 fMustAlloc = TRUE;
6740 if (fMustAlloc)
6741 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
6742 safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
6743 **(UINT_PTR **)ppMemory = val;
6744 TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
6746 break;
6747 case RPC_FC_IGNORE:
6748 break;
6749 default:
6750 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6752 #undef BASE_TYPE_UNMARSHALL
6754 /* FIXME: what is the correct return value? */
6756 return NULL;
6759 /***********************************************************************
6760 * NdrBaseTypeBufferSize [internal]
6762 static void WINAPI NdrBaseTypeBufferSize(
6763 PMIDL_STUB_MESSAGE pStubMsg,
6764 unsigned char *pMemory,
6765 PFORMAT_STRING pFormat)
6767 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6769 switch(*pFormat)
6771 case RPC_FC_BYTE:
6772 case RPC_FC_CHAR:
6773 case RPC_FC_SMALL:
6774 case RPC_FC_USMALL:
6775 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6776 break;
6777 case RPC_FC_WCHAR:
6778 case RPC_FC_SHORT:
6779 case RPC_FC_USHORT:
6780 case RPC_FC_ENUM16:
6781 align_length(&pStubMsg->BufferLength, sizeof(USHORT));
6782 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6783 break;
6784 case RPC_FC_LONG:
6785 case RPC_FC_ULONG:
6786 case RPC_FC_ENUM32:
6787 case RPC_FC_INT3264:
6788 case RPC_FC_UINT3264:
6789 align_length(&pStubMsg->BufferLength, sizeof(ULONG));
6790 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6791 break;
6792 case RPC_FC_FLOAT:
6793 align_length(&pStubMsg->BufferLength, sizeof(float));
6794 safe_buffer_length_increment(pStubMsg, sizeof(float));
6795 break;
6796 case RPC_FC_DOUBLE:
6797 align_length(&pStubMsg->BufferLength, sizeof(double));
6798 safe_buffer_length_increment(pStubMsg, sizeof(double));
6799 break;
6800 case RPC_FC_HYPER:
6801 align_length(&pStubMsg->BufferLength, sizeof(ULONGLONG));
6802 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6803 break;
6804 case RPC_FC_ERROR_STATUS_T:
6805 align_length(&pStubMsg->BufferLength, sizeof(error_status_t));
6806 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6807 break;
6808 case RPC_FC_IGNORE:
6809 break;
6810 default:
6811 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6815 /***********************************************************************
6816 * NdrBaseTypeMemorySize [internal]
6818 static ULONG WINAPI NdrBaseTypeMemorySize(
6819 PMIDL_STUB_MESSAGE pStubMsg,
6820 PFORMAT_STRING pFormat)
6822 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6824 switch(*pFormat)
6826 case RPC_FC_BYTE:
6827 case RPC_FC_CHAR:
6828 case RPC_FC_SMALL:
6829 case RPC_FC_USMALL:
6830 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6831 pStubMsg->MemorySize += sizeof(UCHAR);
6832 return sizeof(UCHAR);
6833 case RPC_FC_WCHAR:
6834 case RPC_FC_SHORT:
6835 case RPC_FC_USHORT:
6836 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6837 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6838 align_length(&pStubMsg->MemorySize, sizeof(USHORT));
6839 pStubMsg->MemorySize += sizeof(USHORT);
6840 return sizeof(USHORT);
6841 case RPC_FC_LONG:
6842 case RPC_FC_ULONG:
6843 case RPC_FC_ENUM32:
6844 align_pointer(&pStubMsg->Buffer, sizeof(ULONG));
6845 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6846 align_length(&pStubMsg->MemorySize, sizeof(ULONG));
6847 pStubMsg->MemorySize += sizeof(ULONG);
6848 return sizeof(ULONG);
6849 case RPC_FC_FLOAT:
6850 align_pointer(&pStubMsg->Buffer, sizeof(float));
6851 safe_buffer_increment(pStubMsg, sizeof(float));
6852 align_length(&pStubMsg->MemorySize, sizeof(float));
6853 pStubMsg->MemorySize += sizeof(float);
6854 return sizeof(float);
6855 case RPC_FC_DOUBLE:
6856 align_pointer(&pStubMsg->Buffer, sizeof(double));
6857 safe_buffer_increment(pStubMsg, sizeof(double));
6858 align_length(&pStubMsg->MemorySize, sizeof(double));
6859 pStubMsg->MemorySize += sizeof(double);
6860 return sizeof(double);
6861 case RPC_FC_HYPER:
6862 align_pointer(&pStubMsg->Buffer, sizeof(ULONGLONG));
6863 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6864 align_length(&pStubMsg->MemorySize, sizeof(ULONGLONG));
6865 pStubMsg->MemorySize += sizeof(ULONGLONG);
6866 return sizeof(ULONGLONG);
6867 case RPC_FC_ERROR_STATUS_T:
6868 align_pointer(&pStubMsg->Buffer, sizeof(error_status_t));
6869 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6870 align_length(&pStubMsg->MemorySize, sizeof(error_status_t));
6871 pStubMsg->MemorySize += sizeof(error_status_t);
6872 return sizeof(error_status_t);
6873 case RPC_FC_ENUM16:
6874 align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
6875 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6876 align_length(&pStubMsg->MemorySize, sizeof(UINT));
6877 pStubMsg->MemorySize += sizeof(UINT);
6878 return sizeof(UINT);
6879 case RPC_FC_INT3264:
6880 case RPC_FC_UINT3264:
6881 align_pointer(&pStubMsg->Buffer, sizeof(UINT));
6882 safe_buffer_increment(pStubMsg, sizeof(UINT));
6883 align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
6884 pStubMsg->MemorySize += sizeof(UINT_PTR);
6885 return sizeof(UINT_PTR);
6886 case RPC_FC_IGNORE:
6887 align_length(&pStubMsg->MemorySize, sizeof(void *));
6888 pStubMsg->MemorySize += sizeof(void *);
6889 return sizeof(void *);
6890 default:
6891 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6892 return 0;
6896 /***********************************************************************
6897 * NdrBaseTypeFree [internal]
6899 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6900 unsigned char *pMemory,
6901 PFORMAT_STRING pFormat)
6903 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6905 /* nothing to do */
6908 /***********************************************************************
6909 * NdrContextHandleBufferSize [internal]
6911 static void WINAPI NdrContextHandleBufferSize(
6912 PMIDL_STUB_MESSAGE pStubMsg,
6913 unsigned char *pMemory,
6914 PFORMAT_STRING pFormat)
6916 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6918 if (*pFormat != RPC_FC_BIND_CONTEXT)
6920 ERR("invalid format type %x\n", *pFormat);
6921 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6923 align_length(&pStubMsg->BufferLength, 4);
6924 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6927 /***********************************************************************
6928 * NdrContextHandleMarshall [internal]
6930 static unsigned char *WINAPI NdrContextHandleMarshall(
6931 PMIDL_STUB_MESSAGE pStubMsg,
6932 unsigned char *pMemory,
6933 PFORMAT_STRING pFormat)
6935 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6937 if (*pFormat != RPC_FC_BIND_CONTEXT)
6939 ERR("invalid format type %x\n", *pFormat);
6940 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6942 TRACE("flags: 0x%02x\n", pFormat[1]);
6944 if (pStubMsg->IsClient)
6946 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6947 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6948 else
6949 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6951 else
6953 NDR_SCONTEXT ctxt = NDRSContextFromValue(pMemory);
6954 NDR_RUNDOWN rundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[pFormat[2]];
6955 NdrServerContextNewMarshall(pStubMsg, ctxt, rundown, pFormat);
6958 return NULL;
6961 /***********************************************************************
6962 * NdrContextHandleUnmarshall [internal]
6964 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6965 PMIDL_STUB_MESSAGE pStubMsg,
6966 unsigned char **ppMemory,
6967 PFORMAT_STRING pFormat,
6968 unsigned char fMustAlloc)
6970 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6971 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6973 if (*pFormat != RPC_FC_BIND_CONTEXT)
6975 ERR("invalid format type %x\n", *pFormat);
6976 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6978 TRACE("flags: 0x%02x\n", pFormat[1]);
6980 if (pStubMsg->IsClient)
6982 /* [out]-only or [ret] param */
6983 if ((pFormat[1] & (HANDLE_PARAM_IS_IN|HANDLE_PARAM_IS_OUT)) == HANDLE_PARAM_IS_OUT)
6984 **(NDR_CCONTEXT **)ppMemory = NULL;
6985 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6987 else
6989 NDR_SCONTEXT ctxt;
6990 ctxt = NdrServerContextNewUnmarshall(pStubMsg, pFormat);
6991 if (pFormat[1] & HANDLE_PARAM_IS_VIA_PTR)
6992 *(void **)ppMemory = NDRSContextValue(ctxt);
6993 else
6994 *(void **)ppMemory = *NDRSContextValue(ctxt);
6997 return NULL;
7000 /***********************************************************************
7001 * NdrClientContextMarshall [RPCRT4.@]
7003 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7004 NDR_CCONTEXT ContextHandle,
7005 int fCheck)
7007 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
7009 align_pointer_clear(&pStubMsg->Buffer, 4);
7011 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7013 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7014 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7015 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7018 /* FIXME: what does fCheck do? */
7019 NDRCContextMarshall(ContextHandle,
7020 pStubMsg->Buffer);
7022 pStubMsg->Buffer += cbNDRContext;
7025 /***********************************************************************
7026 * NdrClientContextUnmarshall [RPCRT4.@]
7028 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7029 NDR_CCONTEXT * pContextHandle,
7030 RPC_BINDING_HANDLE BindHandle)
7032 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
7034 align_pointer(&pStubMsg->Buffer, 4);
7036 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
7037 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7039 NDRCContextUnmarshall(pContextHandle,
7040 BindHandle,
7041 pStubMsg->Buffer,
7042 pStubMsg->RpcMsg->DataRepresentation);
7044 pStubMsg->Buffer += cbNDRContext;
7047 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7048 NDR_SCONTEXT ContextHandle,
7049 NDR_RUNDOWN RundownRoutine )
7051 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
7053 align_pointer(&pStubMsg->Buffer, 4);
7055 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7057 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7058 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7059 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7062 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7063 pStubMsg->Buffer, RundownRoutine, NULL,
7064 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7065 pStubMsg->Buffer += cbNDRContext;
7068 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
7070 NDR_SCONTEXT ContextHandle;
7072 TRACE("(%p)\n", pStubMsg);
7074 align_pointer(&pStubMsg->Buffer, 4);
7076 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7078 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7079 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7080 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7083 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7084 pStubMsg->Buffer,
7085 pStubMsg->RpcMsg->DataRepresentation,
7086 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
7087 pStubMsg->Buffer += cbNDRContext;
7089 return ContextHandle;
7092 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
7093 unsigned char* pMemory,
7094 PFORMAT_STRING pFormat)
7096 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
7099 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
7100 PFORMAT_STRING pFormat)
7102 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7103 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7105 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7107 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7108 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7109 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7110 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7111 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7113 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7114 if_id = &sif->InterfaceId;
7117 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
7118 pStubMsg->RpcMsg->DataRepresentation, if_id,
7119 flags);
7122 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
7123 NDR_SCONTEXT ContextHandle,
7124 NDR_RUNDOWN RundownRoutine,
7125 PFORMAT_STRING pFormat)
7127 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7128 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7130 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
7132 align_pointer(&pStubMsg->Buffer, 4);
7134 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7136 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7137 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7138 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7141 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7142 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7143 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7144 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7145 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7147 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7148 if_id = &sif->InterfaceId;
7151 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
7152 pStubMsg->Buffer, RundownRoutine, if_id, flags);
7153 pStubMsg->Buffer += cbNDRContext;
7156 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
7157 PFORMAT_STRING pFormat)
7159 NDR_SCONTEXT ContextHandle;
7160 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
7161 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
7163 TRACE("(%p, %p)\n", pStubMsg, pFormat);
7165 align_pointer(&pStubMsg->Buffer, 4);
7167 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
7169 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7170 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
7171 RpcRaiseException(RPC_X_BAD_STUB_DATA);
7174 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
7175 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
7176 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
7177 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
7178 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
7180 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
7181 if_id = &sif->InterfaceId;
7184 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
7185 pStubMsg->Buffer,
7186 pStubMsg->RpcMsg->DataRepresentation,
7187 if_id, flags);
7188 pStubMsg->Buffer += cbNDRContext;
7190 return ContextHandle;
7193 /***********************************************************************
7194 * NdrCorrelationInitialize [RPCRT4.@]
7196 * Initializes correlation validity checking.
7198 * PARAMS
7199 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7200 * pMemory [I] Pointer to memory to use as a cache.
7201 * CacheSize [I] Size of the memory pointed to by pMemory.
7202 * Flags [I] Reserved. Set to zero.
7204 * RETURNS
7205 * Nothing.
7207 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
7209 FIXME("(%p, %p, %d, 0x%x): semi-stub\n", pStubMsg, pMemory, CacheSize, Flags);
7211 if (pStubMsg->CorrDespIncrement == 0)
7212 pStubMsg->CorrDespIncrement = 2; /* size of the normal (non-range) /robust payload */
7214 pStubMsg->fHasNewCorrDesc = TRUE;
7217 /***********************************************************************
7218 * NdrCorrelationPass [RPCRT4.@]
7220 * Performs correlation validity checking.
7222 * PARAMS
7223 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7225 * RETURNS
7226 * Nothing.
7228 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
7230 FIXME("(%p): stub\n", pStubMsg);
7233 /***********************************************************************
7234 * NdrCorrelationFree [RPCRT4.@]
7236 * Frees any resources used while unmarshalling parameters that need
7237 * correlation validity checking.
7239 * PARAMS
7240 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7242 * RETURNS
7243 * Nothing.
7245 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
7247 FIXME("(%p): stub\n", pStubMsg);