push 57b67fa3cb0bad7ec17bcd37e0e1e936855340bd
[wine/hacks.git] / dlls / rpcrt4 / ndr_marshall.c
blob3be736d1edcdd00f9f05da0511cd39b4cf4f0659
1 /*
2 * NDR data marshalling
4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * TODO:
22 * - String structs
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <limits.h>
35 #include "windef.h"
36 #include "winbase.h"
37 #include "winerror.h"
39 #include "ndr_misc.h"
40 #include "rpcndr.h"
42 #include "wine/unicode.h"
43 #include "wine/rpcfc.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ole);
49 #if defined(__i386__)
50 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
51 (*((UINT32 *)(pchar)) = (uint32))
53 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
54 (*((UINT32 *)(pchar)))
55 #else
56 /* these would work for i386 too, but less efficient */
57 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
58 (*(pchar) = LOBYTE(LOWORD(uint32)), \
59 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
60 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
61 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
62 (uint32)) /* allow as r-value */
64 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
65 (MAKELONG( \
66 MAKEWORD(*(pchar), *((pchar)+1)), \
67 MAKEWORD(*((pchar)+2), *((pchar)+3))))
68 #endif
70 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
71 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
72 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
73 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
74 *(pchar) = HIBYTE(HIWORD(uint32)), \
75 (uint32)) /* allow as r-value */
77 #define BIG_ENDIAN_UINT32_READ(pchar) \
78 (MAKELONG( \
79 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
80 MAKEWORD(*((pchar)+1), *(pchar))))
82 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
83 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
84 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
85 # define NDR_LOCAL_UINT32_READ(pchar) \
86 BIG_ENDIAN_UINT32_READ(pchar)
87 #else
88 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
89 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
90 # define NDR_LOCAL_UINT32_READ(pchar) \
91 LITTLE_ENDIAN_UINT32_READ(pchar)
92 #endif
94 /* _Align must be the desired alignment,
95 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
96 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
97 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
98 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
99 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
100 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
101 do { \
102 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
103 ALIGN_POINTER(_Ptr, _Align); \
104 } while(0)
106 #define STD_OVERFLOW_CHECK(_Msg) do { \
107 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
108 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
109 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
110 } while (0)
112 #define NDR_POINTER_ID_BASE 0x20000
113 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
114 #define NDR_TABLE_SIZE 128
115 #define NDR_TABLE_MASK 127
117 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
119 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
121 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
123 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
124 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
125 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
127 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
132 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
133 /* 0x10 */
134 NdrBaseTypeMarshall,
135 /* 0x11 */
136 NdrPointerMarshall, NdrPointerMarshall,
137 NdrPointerMarshall, NdrPointerMarshall,
138 /* 0x15 */
139 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
140 NdrConformantStructMarshall, NdrConformantStructMarshall,
141 NdrConformantVaryingStructMarshall,
142 NdrComplexStructMarshall,
143 /* 0x1b */
144 NdrConformantArrayMarshall,
145 NdrConformantVaryingArrayMarshall,
146 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
147 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
148 NdrComplexArrayMarshall,
149 /* 0x22 */
150 NdrConformantStringMarshall, 0, 0,
151 NdrConformantStringMarshall,
152 NdrNonConformantStringMarshall, 0, 0, 0,
153 /* 0x2a */
154 NdrEncapsulatedUnionMarshall,
155 NdrNonEncapsulatedUnionMarshall,
156 NdrByteCountPointerMarshall,
157 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
158 /* 0x2f */
159 NdrInterfacePointerMarshall,
160 /* 0x30 */
161 NdrContextHandleMarshall,
162 /* 0xb1 */
163 0, 0, 0,
164 NdrUserMarshalMarshall,
165 0, 0,
166 /* 0xb7 */
167 NdrRangeMarshall
169 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
174 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
175 /* 0x10 */
176 NdrBaseTypeUnmarshall,
177 /* 0x11 */
178 NdrPointerUnmarshall, NdrPointerUnmarshall,
179 NdrPointerUnmarshall, NdrPointerUnmarshall,
180 /* 0x15 */
181 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
182 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
183 NdrConformantVaryingStructUnmarshall,
184 NdrComplexStructUnmarshall,
185 /* 0x1b */
186 NdrConformantArrayUnmarshall,
187 NdrConformantVaryingArrayUnmarshall,
188 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
189 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
190 NdrComplexArrayUnmarshall,
191 /* 0x22 */
192 NdrConformantStringUnmarshall, 0, 0,
193 NdrConformantStringUnmarshall,
194 NdrNonConformantStringUnmarshall, 0, 0, 0,
195 /* 0x2a */
196 NdrEncapsulatedUnionUnmarshall,
197 NdrNonEncapsulatedUnionUnmarshall,
198 NdrByteCountPointerUnmarshall,
199 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
200 /* 0x2f */
201 NdrInterfacePointerUnmarshall,
202 /* 0x30 */
203 NdrContextHandleUnmarshall,
204 /* 0xb1 */
205 0, 0, 0,
206 NdrUserMarshalUnmarshall,
207 0, 0,
208 /* 0xb7 */
209 NdrRangeUnmarshall
211 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
216 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
217 /* 0x10 */
218 NdrBaseTypeBufferSize,
219 /* 0x11 */
220 NdrPointerBufferSize, NdrPointerBufferSize,
221 NdrPointerBufferSize, NdrPointerBufferSize,
222 /* 0x15 */
223 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
224 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
225 NdrConformantVaryingStructBufferSize,
226 NdrComplexStructBufferSize,
227 /* 0x1b */
228 NdrConformantArrayBufferSize,
229 NdrConformantVaryingArrayBufferSize,
230 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
231 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
232 NdrComplexArrayBufferSize,
233 /* 0x22 */
234 NdrConformantStringBufferSize, 0, 0,
235 NdrConformantStringBufferSize,
236 NdrNonConformantStringBufferSize, 0, 0, 0,
237 /* 0x2a */
238 NdrEncapsulatedUnionBufferSize,
239 NdrNonEncapsulatedUnionBufferSize,
240 NdrByteCountPointerBufferSize,
241 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
242 /* 0x2f */
243 NdrInterfacePointerBufferSize,
244 /* 0x30 */
245 NdrContextHandleBufferSize,
246 /* 0xb1 */
247 0, 0, 0,
248 NdrUserMarshalBufferSize,
249 0, 0,
250 /* 0xb7 */
251 NdrRangeBufferSize
253 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
258 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
259 /* 0x10 */
260 NdrBaseTypeMemorySize,
261 /* 0x11 */
262 NdrPointerMemorySize, NdrPointerMemorySize,
263 NdrPointerMemorySize, NdrPointerMemorySize,
264 /* 0x15 */
265 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
266 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
267 NdrConformantVaryingStructMemorySize,
268 NdrComplexStructMemorySize,
269 /* 0x1b */
270 NdrConformantArrayMemorySize,
271 NdrConformantVaryingArrayMemorySize,
272 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
273 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
274 NdrComplexArrayMemorySize,
275 /* 0x22 */
276 NdrConformantStringMemorySize, 0, 0,
277 NdrConformantStringMemorySize,
278 NdrNonConformantStringMemorySize, 0, 0, 0,
279 /* 0x2a */
280 NdrEncapsulatedUnionMemorySize,
281 NdrNonEncapsulatedUnionMemorySize,
282 NdrByteCountPointerMemorySize,
283 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
284 /* 0x2f */
285 NdrInterfacePointerMemorySize,
286 /* 0x30 */
288 /* 0xb1 */
289 0, 0, 0,
290 NdrUserMarshalMemorySize,
291 0, 0,
292 /* 0xb7 */
293 NdrRangeMemorySize
295 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
298 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
299 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
300 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
301 /* 0x10 */
302 NdrBaseTypeFree,
303 /* 0x11 */
304 NdrPointerFree, NdrPointerFree,
305 NdrPointerFree, NdrPointerFree,
306 /* 0x15 */
307 NdrSimpleStructFree, NdrSimpleStructFree,
308 NdrConformantStructFree, NdrConformantStructFree,
309 NdrConformantVaryingStructFree,
310 NdrComplexStructFree,
311 /* 0x1b */
312 NdrConformantArrayFree,
313 NdrConformantVaryingArrayFree,
314 NdrFixedArrayFree, NdrFixedArrayFree,
315 NdrVaryingArrayFree, NdrVaryingArrayFree,
316 NdrComplexArrayFree,
317 /* 0x22 */
318 0, 0, 0,
319 0, 0, 0, 0, 0,
320 /* 0x2a */
321 NdrEncapsulatedUnionFree,
322 NdrNonEncapsulatedUnionFree,
324 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
325 /* 0x2f */
326 NdrInterfacePointerFree,
327 /* 0x30 */
329 /* 0xb1 */
330 0, 0, 0,
331 NdrUserMarshalFree,
332 0, 0,
333 /* 0xb7 */
334 NdrRangeFree
337 typedef struct _NDR_MEMORY_LIST
339 ULONG magic;
340 ULONG size;
341 ULONG reserved;
342 struct _NDR_MEMORY_LIST *next;
343 } NDR_MEMORY_LIST;
345 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
347 /***********************************************************************
348 * NdrAllocate [RPCRT4.@]
350 * Allocates a block of memory using pStubMsg->pfnAllocate.
352 * PARAMS
353 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
354 * len [I] Size of memory block to allocate.
356 * RETURNS
357 * The memory block of size len that was allocated.
359 * NOTES
360 * The memory block is always 8-byte aligned.
361 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
362 * exception is raised.
364 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
366 SIZE_T aligned_len;
367 SIZE_T adjusted_len;
368 void *p;
369 NDR_MEMORY_LIST *mem_list;
371 aligned_len = ALIGNED_LENGTH(len, 8);
372 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
373 /* check for overflow */
374 if (adjusted_len < len)
376 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
377 RpcRaiseException(RPC_X_BAD_STUB_DATA);
380 p = pStubMsg->pfnAllocate(adjusted_len);
381 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
383 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
384 mem_list->magic = MEML_MAGIC;
385 mem_list->size = aligned_len;
386 mem_list->reserved = 0;
387 mem_list->next = pStubMsg->pMemoryList;
388 pStubMsg->pMemoryList = mem_list;
390 TRACE("-- %p\n", p);
391 return p;
394 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
396 TRACE("(%p, %p)\n", pStubMsg, Pointer);
398 pStubMsg->pfnFree(Pointer);
401 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
403 return (*(const ULONG *)pFormat != -1);
406 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
408 ALIGN_POINTER(pStubMsg->Buffer, 4);
409 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
410 RpcRaiseException(RPC_X_BAD_STUB_DATA);
411 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
412 pStubMsg->Buffer += 4;
413 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
414 if (pStubMsg->fHasNewCorrDesc)
415 return pFormat+6;
416 else
417 return pFormat+4;
420 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
422 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
424 pStubMsg->Offset = 0;
425 pStubMsg->ActualCount = pStubMsg->MaxCount;
426 goto done;
429 ALIGN_POINTER(pStubMsg->Buffer, 4);
430 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
431 RpcRaiseException(RPC_X_BAD_STUB_DATA);
432 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
433 pStubMsg->Buffer += 4;
434 TRACE("offset is %d\n", pStubMsg->Offset);
435 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
436 pStubMsg->Buffer += 4;
437 TRACE("variance is %d\n", pStubMsg->ActualCount);
439 if ((pStubMsg->ActualCount > MaxValue) ||
440 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
442 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
443 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
444 RpcRaiseException(RPC_S_INVALID_BOUND);
445 return NULL;
448 done:
449 if (pStubMsg->fHasNewCorrDesc)
450 return pFormat+6;
451 else
452 return pFormat+4;
455 /* writes the conformance value to the buffer */
456 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
458 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
459 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
460 RpcRaiseException(RPC_X_BAD_STUB_DATA);
461 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
462 pStubMsg->Buffer += 4;
465 /* writes the variance values to the buffer */
466 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
468 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
469 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
470 RpcRaiseException(RPC_X_BAD_STUB_DATA);
471 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
472 pStubMsg->Buffer += 4;
473 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
474 pStubMsg->Buffer += 4;
477 /* requests buffer space for the conformance value */
478 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
480 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
481 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
482 RpcRaiseException(RPC_X_BAD_STUB_DATA);
483 pStubMsg->BufferLength += 4;
486 /* requests buffer space for the variance values */
487 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
489 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
490 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
491 RpcRaiseException(RPC_X_BAD_STUB_DATA);
492 pStubMsg->BufferLength += 8;
495 PFORMAT_STRING ComputeConformanceOrVariance(
496 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
497 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
499 BYTE dtype = pFormat[0] & 0xf;
500 short ofs = *(const short *)&pFormat[2];
501 LPVOID ptr = NULL;
502 DWORD data = 0;
504 if (!IsConformanceOrVariancePresent(pFormat)) {
505 /* null descriptor */
506 *pCount = def;
507 goto finish_conf;
510 switch (pFormat[0] & 0xf0) {
511 case RPC_FC_NORMAL_CONFORMANCE:
512 TRACE("normal conformance, ofs=%d\n", ofs);
513 ptr = pMemory;
514 break;
515 case RPC_FC_POINTER_CONFORMANCE:
516 TRACE("pointer conformance, ofs=%d\n", ofs);
517 ptr = pStubMsg->Memory;
518 break;
519 case RPC_FC_TOP_LEVEL_CONFORMANCE:
520 TRACE("toplevel conformance, ofs=%d\n", ofs);
521 if (pStubMsg->StackTop) {
522 ptr = pStubMsg->StackTop;
524 else {
525 /* -Os mode, *pCount is already set */
526 goto finish_conf;
528 break;
529 case RPC_FC_CONSTANT_CONFORMANCE:
530 data = ofs | ((DWORD)pFormat[1] << 16);
531 TRACE("constant conformance, val=%d\n", data);
532 *pCount = data;
533 goto finish_conf;
534 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
535 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
536 if (pStubMsg->StackTop) {
537 ptr = pStubMsg->StackTop;
539 else {
540 /* ? */
541 goto done_conf_grab;
543 break;
544 default:
545 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
548 switch (pFormat[1]) {
549 case RPC_FC_DEREFERENCE:
550 ptr = *(LPVOID*)((char *)ptr + ofs);
551 break;
552 case RPC_FC_CALLBACK:
554 unsigned char *old_stack_top = pStubMsg->StackTop;
555 pStubMsg->StackTop = ptr;
557 /* ofs is index into StubDesc->apfnExprEval */
558 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
559 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
561 pStubMsg->StackTop = old_stack_top;
563 /* the callback function always stores the computed value in MaxCount */
564 *pCount = pStubMsg->MaxCount;
565 goto finish_conf;
567 default:
568 ptr = (char *)ptr + ofs;
569 break;
572 switch (dtype) {
573 case RPC_FC_LONG:
574 case RPC_FC_ULONG:
575 data = *(DWORD*)ptr;
576 break;
577 case RPC_FC_SHORT:
578 data = *(SHORT*)ptr;
579 break;
580 case RPC_FC_USHORT:
581 data = *(USHORT*)ptr;
582 break;
583 case RPC_FC_CHAR:
584 case RPC_FC_SMALL:
585 data = *(CHAR*)ptr;
586 break;
587 case RPC_FC_BYTE:
588 case RPC_FC_USMALL:
589 data = *(UCHAR*)ptr;
590 break;
591 default:
592 FIXME("unknown conformance data type %x\n", dtype);
593 goto done_conf_grab;
595 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
597 done_conf_grab:
598 switch (pFormat[1]) {
599 case RPC_FC_DEREFERENCE: /* already handled */
600 case 0: /* no op */
601 *pCount = data;
602 break;
603 case RPC_FC_ADD_1:
604 *pCount = data + 1;
605 break;
606 case RPC_FC_SUB_1:
607 *pCount = data - 1;
608 break;
609 case RPC_FC_MULT_2:
610 *pCount = data * 2;
611 break;
612 case RPC_FC_DIV_2:
613 *pCount = data / 2;
614 break;
615 default:
616 FIXME("unknown conformance op %d\n", pFormat[1]);
617 goto finish_conf;
620 finish_conf:
621 TRACE("resulting conformance is %ld\n", *pCount);
622 if (pStubMsg->fHasNewCorrDesc)
623 return pFormat+6;
624 else
625 return pFormat+4;
628 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
629 PFORMAT_STRING pFormat)
631 if (IsConformanceOrVariancePresent(pFormat))
633 if (pStubMsg->fHasNewCorrDesc)
634 pFormat += 6;
635 else
636 pFormat += 4;
638 return pFormat;
641 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
642 * the result overflows 32-bits */
643 static inline ULONG safe_multiply(ULONG a, ULONG b)
645 ULONGLONG ret = (ULONGLONG)a * b;
646 if (ret > 0xffffffff)
648 RpcRaiseException(RPC_S_INVALID_BOUND);
649 return 0;
651 return ret;
654 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
656 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
657 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
658 RpcRaiseException(RPC_X_BAD_STUB_DATA);
659 pStubMsg->Buffer += size;
662 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
664 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
666 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
667 pStubMsg->BufferLength, size);
668 RpcRaiseException(RPC_X_BAD_STUB_DATA);
670 pStubMsg->BufferLength += size;
673 /* copies data from the buffer, checking that there is enough data in the buffer
674 * to do so */
675 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
677 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
678 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
680 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
681 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
682 RpcRaiseException(RPC_X_BAD_STUB_DATA);
684 if (p == pStubMsg->Buffer)
685 ERR("pointer is the same as the buffer\n");
686 memcpy(p, pStubMsg->Buffer, size);
687 pStubMsg->Buffer += size;
690 /* copies data to the buffer, checking that there is enough space to do so */
691 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
693 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
694 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
696 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
697 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
698 size);
699 RpcRaiseException(RPC_X_BAD_STUB_DATA);
701 memcpy(pStubMsg->Buffer, p, size);
702 pStubMsg->Buffer += size;
705 /* verify that string data sitting in the buffer is valid and safe to
706 * unmarshall */
707 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
709 ULONG i;
711 /* verify the buffer is safe to access */
712 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
713 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
715 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
716 pStubMsg->BufferEnd, pStubMsg->Buffer);
717 RpcRaiseException(RPC_X_BAD_STUB_DATA);
720 /* strings must always have null terminating bytes */
721 if (bufsize < esize)
723 ERR("invalid string length of %d\n", bufsize / esize);
724 RpcRaiseException(RPC_S_INVALID_BOUND);
727 for (i = bufsize - esize; i < bufsize; i++)
728 if (pStubMsg->Buffer[i] != 0)
730 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
731 i, pStubMsg->Buffer[i]);
732 RpcRaiseException(RPC_S_INVALID_BOUND);
736 static inline void dump_pointer_attr(unsigned char attr)
738 if (attr & RPC_FC_P_ALLOCALLNODES)
739 TRACE(" RPC_FC_P_ALLOCALLNODES");
740 if (attr & RPC_FC_P_DONTFREE)
741 TRACE(" RPC_FC_P_DONTFREE");
742 if (attr & RPC_FC_P_ONSTACK)
743 TRACE(" RPC_FC_P_ONSTACK");
744 if (attr & RPC_FC_P_SIMPLEPOINTER)
745 TRACE(" RPC_FC_P_SIMPLEPOINTER");
746 if (attr & RPC_FC_P_DEREF)
747 TRACE(" RPC_FC_P_DEREF");
748 TRACE("\n");
751 /***********************************************************************
752 * PointerMarshall [internal]
754 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
755 unsigned char *Buffer,
756 unsigned char *Pointer,
757 PFORMAT_STRING pFormat)
759 unsigned type = pFormat[0], attr = pFormat[1];
760 PFORMAT_STRING desc;
761 NDR_MARSHALL m;
762 ULONG pointer_id;
763 int pointer_needs_marshaling;
765 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
766 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
767 pFormat += 2;
768 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
769 else desc = pFormat + *(const SHORT*)pFormat;
771 switch (type) {
772 case RPC_FC_RP: /* ref pointer (always non-null) */
773 if (!Pointer)
775 ERR("NULL ref pointer is not allowed\n");
776 RpcRaiseException(RPC_X_NULL_REF_POINTER);
778 pointer_needs_marshaling = 1;
779 break;
780 case RPC_FC_UP: /* unique pointer */
781 case RPC_FC_OP: /* object pointer - same as unique here */
782 if (Pointer)
783 pointer_needs_marshaling = 1;
784 else
785 pointer_needs_marshaling = 0;
786 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
787 TRACE("writing 0x%08x to buffer\n", pointer_id);
788 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
789 break;
790 case RPC_FC_FP:
791 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
792 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
793 TRACE("writing 0x%08x to buffer\n", pointer_id);
794 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
795 break;
796 default:
797 FIXME("unhandled ptr type=%02x\n", type);
798 RpcRaiseException(RPC_X_BAD_STUB_DATA);
799 return;
802 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
804 if (pointer_needs_marshaling) {
805 if (attr & RPC_FC_P_DEREF) {
806 Pointer = *(unsigned char**)Pointer;
807 TRACE("deref => %p\n", Pointer);
809 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
810 if (m) m(pStubMsg, Pointer, desc);
811 else FIXME("no marshaller for data type=%02x\n", *desc);
814 STD_OVERFLOW_CHECK(pStubMsg);
817 /***********************************************************************
818 * PointerUnmarshall [internal]
820 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
821 unsigned char *Buffer,
822 unsigned char **pPointer,
823 unsigned char *pSrcPointer,
824 PFORMAT_STRING pFormat,
825 unsigned char fMustAlloc)
827 unsigned type = pFormat[0], attr = pFormat[1];
828 PFORMAT_STRING desc;
829 NDR_UNMARSHALL m;
830 DWORD pointer_id = 0;
831 int pointer_needs_unmarshaling;
833 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
834 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
835 pFormat += 2;
836 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
837 else desc = pFormat + *(const SHORT*)pFormat;
839 switch (type) {
840 case RPC_FC_RP: /* ref pointer (always non-null) */
841 pointer_needs_unmarshaling = 1;
842 break;
843 case RPC_FC_UP: /* unique pointer */
844 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
845 TRACE("pointer_id is 0x%08x\n", pointer_id);
846 if (pointer_id)
847 pointer_needs_unmarshaling = 1;
848 else {
849 *pPointer = NULL;
850 pointer_needs_unmarshaling = 0;
852 break;
853 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
854 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
855 TRACE("pointer_id is 0x%08x\n", pointer_id);
856 if (!fMustAlloc && pSrcPointer)
858 FIXME("free object pointer %p\n", pSrcPointer);
859 fMustAlloc = TRUE;
861 if (pointer_id)
862 pointer_needs_unmarshaling = 1;
863 else
865 *pPointer = NULL;
866 pointer_needs_unmarshaling = 0;
868 break;
869 case RPC_FC_FP:
870 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
871 TRACE("pointer_id is 0x%08x\n", pointer_id);
872 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
873 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
874 break;
875 default:
876 FIXME("unhandled ptr type=%02x\n", type);
877 RpcRaiseException(RPC_X_BAD_STUB_DATA);
878 return;
881 if (pointer_needs_unmarshaling) {
882 unsigned char *base_ptr_val = *pPointer;
883 unsigned char **current_ptr = pPointer;
884 if (pStubMsg->IsClient) {
885 TRACE("client\n");
886 /* if we aren't forcing allocation of memory then try to use the existing
887 * (source) pointer to unmarshall the data into so that [in,out]
888 * parameters behave correctly. it doesn't matter if the parameter is
889 * [out] only since in that case the pointer will be NULL. we force
890 * allocation when the source pointer is NULL here instead of in the type
891 * unmarshalling routine for the benefit of the deref code below */
892 if (!fMustAlloc) {
893 if (pSrcPointer) {
894 TRACE("setting *pPointer to %p\n", pSrcPointer);
895 *pPointer = base_ptr_val = pSrcPointer;
896 } else
897 fMustAlloc = TRUE;
899 } else {
900 TRACE("server\n");
901 /* the memory in a stub is never initialised, so we have to work out here
902 * whether we have to initialise it so we can use the optimisation of
903 * setting the pointer to the buffer, if possible, or set fMustAlloc to
904 * TRUE. */
905 if (attr & RPC_FC_P_DEREF) {
906 fMustAlloc = TRUE;
907 } else {
908 base_ptr_val = NULL;
909 *current_ptr = NULL;
913 if (attr & RPC_FC_P_ALLOCALLNODES)
914 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
916 if (attr & RPC_FC_P_DEREF) {
917 if (fMustAlloc) {
918 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
919 *pPointer = base_ptr_val;
920 current_ptr = (unsigned char **)base_ptr_val;
921 } else
922 current_ptr = *(unsigned char***)current_ptr;
923 TRACE("deref => %p\n", current_ptr);
924 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
926 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
927 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
928 else FIXME("no unmarshaller for data type=%02x\n", *desc);
930 if (type == RPC_FC_FP)
931 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
932 base_ptr_val);
935 TRACE("pointer=%p\n", *pPointer);
938 /***********************************************************************
939 * PointerBufferSize [internal]
941 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
942 unsigned char *Pointer,
943 PFORMAT_STRING pFormat)
945 unsigned type = pFormat[0], attr = pFormat[1];
946 PFORMAT_STRING desc;
947 NDR_BUFFERSIZE m;
948 int pointer_needs_sizing;
949 ULONG pointer_id;
951 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
952 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
953 pFormat += 2;
954 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
955 else desc = pFormat + *(const SHORT*)pFormat;
957 switch (type) {
958 case RPC_FC_RP: /* ref pointer (always non-null) */
959 if (!Pointer)
961 ERR("NULL ref pointer is not allowed\n");
962 RpcRaiseException(RPC_X_NULL_REF_POINTER);
964 break;
965 case RPC_FC_OP:
966 case RPC_FC_UP:
967 /* NULL pointer has no further representation */
968 if (!Pointer)
969 return;
970 break;
971 case RPC_FC_FP:
972 pointer_needs_sizing = !NdrFullPointerQueryPointer(
973 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
974 if (!pointer_needs_sizing)
975 return;
976 break;
977 default:
978 FIXME("unhandled ptr type=%02x\n", type);
979 RpcRaiseException(RPC_X_BAD_STUB_DATA);
980 return;
983 if (attr & RPC_FC_P_DEREF) {
984 Pointer = *(unsigned char**)Pointer;
985 TRACE("deref => %p\n", Pointer);
988 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
989 if (m) m(pStubMsg, Pointer, desc);
990 else FIXME("no buffersizer for data type=%02x\n", *desc);
993 /***********************************************************************
994 * PointerMemorySize [internal]
996 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
997 unsigned char *Buffer,
998 PFORMAT_STRING pFormat)
1000 unsigned type = pFormat[0], attr = pFormat[1];
1001 PFORMAT_STRING desc;
1002 NDR_MEMORYSIZE m;
1003 DWORD pointer_id = 0;
1004 int pointer_needs_sizing;
1006 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1007 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1008 pFormat += 2;
1009 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1010 else desc = pFormat + *(const SHORT*)pFormat;
1012 switch (type) {
1013 case RPC_FC_RP: /* ref pointer (always non-null) */
1014 pointer_needs_sizing = 1;
1015 break;
1016 case RPC_FC_UP: /* unique pointer */
1017 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1018 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1019 TRACE("pointer_id is 0x%08x\n", pointer_id);
1020 if (pointer_id)
1021 pointer_needs_sizing = 1;
1022 else
1023 pointer_needs_sizing = 0;
1024 break;
1025 case RPC_FC_FP:
1027 void *pointer;
1028 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1029 TRACE("pointer_id is 0x%08x\n", pointer_id);
1030 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1031 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1032 break;
1034 default:
1035 FIXME("unhandled ptr type=%02x\n", type);
1036 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1037 return 0;
1040 if (attr & RPC_FC_P_DEREF) {
1041 TRACE("deref\n");
1044 if (pointer_needs_sizing) {
1045 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1046 if (m) m(pStubMsg, desc);
1047 else FIXME("no memorysizer for data type=%02x\n", *desc);
1050 return pStubMsg->MemorySize;
1053 /***********************************************************************
1054 * PointerFree [internal]
1056 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1057 unsigned char *Pointer,
1058 PFORMAT_STRING pFormat)
1060 unsigned type = pFormat[0], attr = pFormat[1];
1061 PFORMAT_STRING desc;
1062 NDR_FREE m;
1063 unsigned char *current_pointer = Pointer;
1065 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1066 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1067 if (attr & RPC_FC_P_DONTFREE) return;
1068 pFormat += 2;
1069 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1070 else desc = pFormat + *(const SHORT*)pFormat;
1072 if (!Pointer) return;
1074 if (type == RPC_FC_FP) {
1075 int pointer_needs_freeing = NdrFullPointerFree(
1076 pStubMsg->FullPtrXlatTables, Pointer);
1077 if (!pointer_needs_freeing)
1078 return;
1081 if (attr & RPC_FC_P_DEREF) {
1082 current_pointer = *(unsigned char**)Pointer;
1083 TRACE("deref => %p\n", current_pointer);
1086 m = NdrFreer[*desc & NDR_TABLE_MASK];
1087 if (m) m(pStubMsg, current_pointer, desc);
1089 /* this check stops us from trying to free buffer memory. we don't have to
1090 * worry about clients, since they won't call this function.
1091 * we don't have to check for the buffer being reallocated because
1092 * BufferStart and BufferEnd won't be reset when allocating memory for
1093 * sending the response. we don't have to check for the new buffer here as
1094 * it won't be used a type memory, only for buffer memory */
1095 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1096 goto notfree;
1098 if (attr & RPC_FC_P_ONSTACK) {
1099 TRACE("not freeing stack ptr %p\n", Pointer);
1100 return;
1102 TRACE("freeing %p\n", Pointer);
1103 NdrFree(pStubMsg, Pointer);
1104 return;
1105 notfree:
1106 TRACE("not freeing %p\n", Pointer);
1109 /***********************************************************************
1110 * EmbeddedPointerMarshall
1112 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1113 unsigned char *pMemory,
1114 PFORMAT_STRING pFormat)
1116 unsigned char *Mark = pStubMsg->BufferMark;
1117 unsigned rep, count, stride;
1118 unsigned i;
1119 unsigned char *saved_buffer = NULL;
1121 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1123 if (*pFormat != RPC_FC_PP) return NULL;
1124 pFormat += 2;
1126 if (pStubMsg->PointerBufferMark)
1128 saved_buffer = pStubMsg->Buffer;
1129 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1130 pStubMsg->PointerBufferMark = NULL;
1133 while (pFormat[0] != RPC_FC_END) {
1134 switch (pFormat[0]) {
1135 default:
1136 FIXME("unknown repeat type %d\n", pFormat[0]);
1137 case RPC_FC_NO_REPEAT:
1138 rep = 1;
1139 stride = 0;
1140 count = 1;
1141 pFormat += 2;
1142 break;
1143 case RPC_FC_FIXED_REPEAT:
1144 rep = *(const WORD*)&pFormat[2];
1145 stride = *(const WORD*)&pFormat[4];
1146 count = *(const WORD*)&pFormat[8];
1147 pFormat += 10;
1148 break;
1149 case RPC_FC_VARIABLE_REPEAT:
1150 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1151 stride = *(const WORD*)&pFormat[2];
1152 count = *(const WORD*)&pFormat[6];
1153 pFormat += 8;
1154 break;
1156 for (i = 0; i < rep; i++) {
1157 PFORMAT_STRING info = pFormat;
1158 unsigned char *membase = pMemory + (i * stride);
1159 unsigned char *bufbase = Mark + (i * stride);
1160 unsigned u;
1162 for (u=0; u<count; u++,info+=8) {
1163 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1164 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1165 unsigned char *saved_memory = pStubMsg->Memory;
1167 pStubMsg->Memory = pMemory;
1168 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1169 pStubMsg->Memory = saved_memory;
1172 pFormat += 8 * count;
1175 if (saved_buffer)
1177 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1178 pStubMsg->Buffer = saved_buffer;
1181 STD_OVERFLOW_CHECK(pStubMsg);
1183 return NULL;
1186 /***********************************************************************
1187 * EmbeddedPointerUnmarshall
1189 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1190 unsigned char *pDstBuffer,
1191 unsigned char *pSrcMemoryPtrs,
1192 PFORMAT_STRING pFormat,
1193 unsigned char fMustAlloc)
1195 unsigned char *Mark = pStubMsg->BufferMark;
1196 unsigned rep, count, stride;
1197 unsigned i;
1198 unsigned char *saved_buffer = NULL;
1200 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1202 if (*pFormat != RPC_FC_PP) return NULL;
1203 pFormat += 2;
1205 if (pStubMsg->PointerBufferMark)
1207 saved_buffer = pStubMsg->Buffer;
1208 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1209 pStubMsg->PointerBufferMark = NULL;
1212 while (pFormat[0] != RPC_FC_END) {
1213 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1214 switch (pFormat[0]) {
1215 default:
1216 FIXME("unknown repeat type %d\n", pFormat[0]);
1217 case RPC_FC_NO_REPEAT:
1218 rep = 1;
1219 stride = 0;
1220 count = 1;
1221 pFormat += 2;
1222 break;
1223 case RPC_FC_FIXED_REPEAT:
1224 rep = *(const WORD*)&pFormat[2];
1225 stride = *(const WORD*)&pFormat[4];
1226 count = *(const WORD*)&pFormat[8];
1227 pFormat += 10;
1228 break;
1229 case RPC_FC_VARIABLE_REPEAT:
1230 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1231 stride = *(const WORD*)&pFormat[2];
1232 count = *(const WORD*)&pFormat[6];
1233 pFormat += 8;
1234 break;
1236 for (i = 0; i < rep; i++) {
1237 PFORMAT_STRING info = pFormat;
1238 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1239 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1240 unsigned char *bufbase = Mark + (i * stride);
1241 unsigned u;
1243 for (u=0; u<count; u++,info+=8) {
1244 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1245 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1246 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1247 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1250 pFormat += 8 * count;
1253 if (saved_buffer)
1255 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1256 pStubMsg->Buffer = saved_buffer;
1259 return NULL;
1262 /***********************************************************************
1263 * EmbeddedPointerBufferSize
1265 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1266 unsigned char *pMemory,
1267 PFORMAT_STRING pFormat)
1269 unsigned rep, count, stride;
1270 unsigned i;
1271 ULONG saved_buffer_length = 0;
1273 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1275 if (pStubMsg->IgnoreEmbeddedPointers) return;
1277 if (*pFormat != RPC_FC_PP) return;
1278 pFormat += 2;
1280 if (pStubMsg->PointerLength)
1282 saved_buffer_length = pStubMsg->BufferLength;
1283 pStubMsg->BufferLength = pStubMsg->PointerLength;
1284 pStubMsg->PointerLength = 0;
1287 while (pFormat[0] != RPC_FC_END) {
1288 switch (pFormat[0]) {
1289 default:
1290 FIXME("unknown repeat type %d\n", pFormat[0]);
1291 case RPC_FC_NO_REPEAT:
1292 rep = 1;
1293 stride = 0;
1294 count = 1;
1295 pFormat += 2;
1296 break;
1297 case RPC_FC_FIXED_REPEAT:
1298 rep = *(const WORD*)&pFormat[2];
1299 stride = *(const WORD*)&pFormat[4];
1300 count = *(const WORD*)&pFormat[8];
1301 pFormat += 10;
1302 break;
1303 case RPC_FC_VARIABLE_REPEAT:
1304 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1305 stride = *(const WORD*)&pFormat[2];
1306 count = *(const WORD*)&pFormat[6];
1307 pFormat += 8;
1308 break;
1310 for (i = 0; i < rep; i++) {
1311 PFORMAT_STRING info = pFormat;
1312 unsigned char *membase = pMemory + (i * stride);
1313 unsigned u;
1315 for (u=0; u<count; u++,info+=8) {
1316 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1317 unsigned char *saved_memory = pStubMsg->Memory;
1319 pStubMsg->Memory = pMemory;
1320 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1321 pStubMsg->Memory = saved_memory;
1324 pFormat += 8 * count;
1327 if (saved_buffer_length)
1329 pStubMsg->PointerLength = pStubMsg->BufferLength;
1330 pStubMsg->BufferLength = saved_buffer_length;
1334 /***********************************************************************
1335 * EmbeddedPointerMemorySize [internal]
1337 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1338 PFORMAT_STRING pFormat)
1340 unsigned char *Mark = pStubMsg->BufferMark;
1341 unsigned rep, count, stride;
1342 unsigned i;
1343 unsigned char *saved_buffer = NULL;
1345 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1347 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1349 if (pStubMsg->PointerBufferMark)
1351 saved_buffer = pStubMsg->Buffer;
1352 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1353 pStubMsg->PointerBufferMark = NULL;
1356 if (*pFormat != RPC_FC_PP) return 0;
1357 pFormat += 2;
1359 while (pFormat[0] != RPC_FC_END) {
1360 switch (pFormat[0]) {
1361 default:
1362 FIXME("unknown repeat type %d\n", pFormat[0]);
1363 case RPC_FC_NO_REPEAT:
1364 rep = 1;
1365 stride = 0;
1366 count = 1;
1367 pFormat += 2;
1368 break;
1369 case RPC_FC_FIXED_REPEAT:
1370 rep = *(const WORD*)&pFormat[2];
1371 stride = *(const WORD*)&pFormat[4];
1372 count = *(const WORD*)&pFormat[8];
1373 pFormat += 10;
1374 break;
1375 case RPC_FC_VARIABLE_REPEAT:
1376 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1377 stride = *(const WORD*)&pFormat[2];
1378 count = *(const WORD*)&pFormat[6];
1379 pFormat += 8;
1380 break;
1382 for (i = 0; i < rep; i++) {
1383 PFORMAT_STRING info = pFormat;
1384 unsigned char *bufbase = Mark + (i * stride);
1385 unsigned u;
1386 for (u=0; u<count; u++,info+=8) {
1387 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1388 PointerMemorySize(pStubMsg, bufptr, info+4);
1391 pFormat += 8 * count;
1394 if (saved_buffer)
1396 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1397 pStubMsg->Buffer = saved_buffer;
1400 return 0;
1403 /***********************************************************************
1404 * EmbeddedPointerFree [internal]
1406 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1407 unsigned char *pMemory,
1408 PFORMAT_STRING pFormat)
1410 unsigned rep, count, stride;
1411 unsigned i;
1413 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1414 if (*pFormat != RPC_FC_PP) return;
1415 pFormat += 2;
1417 while (pFormat[0] != RPC_FC_END) {
1418 switch (pFormat[0]) {
1419 default:
1420 FIXME("unknown repeat type %d\n", pFormat[0]);
1421 case RPC_FC_NO_REPEAT:
1422 rep = 1;
1423 stride = 0;
1424 count = 1;
1425 pFormat += 2;
1426 break;
1427 case RPC_FC_FIXED_REPEAT:
1428 rep = *(const WORD*)&pFormat[2];
1429 stride = *(const WORD*)&pFormat[4];
1430 count = *(const WORD*)&pFormat[8];
1431 pFormat += 10;
1432 break;
1433 case RPC_FC_VARIABLE_REPEAT:
1434 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1435 stride = *(const WORD*)&pFormat[2];
1436 count = *(const WORD*)&pFormat[6];
1437 pFormat += 8;
1438 break;
1440 for (i = 0; i < rep; i++) {
1441 PFORMAT_STRING info = pFormat;
1442 unsigned char *membase = pMemory + (i * stride);
1443 unsigned u;
1445 for (u=0; u<count; u++,info+=8) {
1446 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1447 unsigned char *saved_memory = pStubMsg->Memory;
1449 pStubMsg->Memory = pMemory;
1450 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1451 pStubMsg->Memory = saved_memory;
1454 pFormat += 8 * count;
1458 /***********************************************************************
1459 * NdrPointerMarshall [RPCRT4.@]
1461 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1462 unsigned char *pMemory,
1463 PFORMAT_STRING pFormat)
1465 unsigned char *Buffer;
1467 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1469 /* Increment the buffer here instead of in PointerMarshall,
1470 * as that is used by embedded pointers which already handle the incrementing
1471 * the buffer, and shouldn't write any additional pointer data to the wire */
1472 if (*pFormat != RPC_FC_RP)
1474 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1475 Buffer = pStubMsg->Buffer;
1476 safe_buffer_increment(pStubMsg, 4);
1478 else
1479 Buffer = pStubMsg->Buffer;
1481 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1483 return NULL;
1486 /***********************************************************************
1487 * NdrPointerUnmarshall [RPCRT4.@]
1489 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1490 unsigned char **ppMemory,
1491 PFORMAT_STRING pFormat,
1492 unsigned char fMustAlloc)
1494 unsigned char *Buffer;
1496 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1498 /* Increment the buffer here instead of in PointerUnmarshall,
1499 * as that is used by embedded pointers which already handle the incrementing
1500 * the buffer, and shouldn't read any additional pointer data from the
1501 * buffer */
1502 if (*pFormat != RPC_FC_RP)
1504 ALIGN_POINTER(pStubMsg->Buffer, 4);
1505 Buffer = pStubMsg->Buffer;
1506 safe_buffer_increment(pStubMsg, 4);
1508 else
1509 Buffer = pStubMsg->Buffer;
1511 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1513 return NULL;
1516 /***********************************************************************
1517 * NdrPointerBufferSize [RPCRT4.@]
1519 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1520 unsigned char *pMemory,
1521 PFORMAT_STRING pFormat)
1523 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1525 /* Increment the buffer length here instead of in PointerBufferSize,
1526 * as that is used by embedded pointers which already handle the buffer
1527 * length, and shouldn't write anything more to the wire */
1528 if (*pFormat != RPC_FC_RP)
1530 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1531 safe_buffer_length_increment(pStubMsg, 4);
1534 PointerBufferSize(pStubMsg, pMemory, pFormat);
1537 /***********************************************************************
1538 * NdrPointerMemorySize [RPCRT4.@]
1540 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1541 PFORMAT_STRING pFormat)
1543 /* unsigned size = *(LPWORD)(pFormat+2); */
1544 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1545 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1546 return 0;
1549 /***********************************************************************
1550 * NdrPointerFree [RPCRT4.@]
1552 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1553 unsigned char *pMemory,
1554 PFORMAT_STRING pFormat)
1556 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1557 PointerFree(pStubMsg, pMemory, pFormat);
1560 /***********************************************************************
1561 * NdrSimpleTypeMarshall [RPCRT4.@]
1563 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1564 unsigned char FormatChar )
1566 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1569 /***********************************************************************
1570 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1572 * Unmarshall a base type.
1574 * NOTES
1575 * Doesn't check that the buffer is long enough before copying, so the caller
1576 * should do this.
1578 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1579 unsigned char FormatChar )
1581 #define BASE_TYPE_UNMARSHALL(type) \
1582 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1583 TRACE("pMemory: %p\n", pMemory); \
1584 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1585 pStubMsg->Buffer += sizeof(type);
1587 switch(FormatChar)
1589 case RPC_FC_BYTE:
1590 case RPC_FC_CHAR:
1591 case RPC_FC_SMALL:
1592 case RPC_FC_USMALL:
1593 BASE_TYPE_UNMARSHALL(UCHAR);
1594 TRACE("value: 0x%02x\n", *pMemory);
1595 break;
1596 case RPC_FC_WCHAR:
1597 case RPC_FC_SHORT:
1598 case RPC_FC_USHORT:
1599 BASE_TYPE_UNMARSHALL(USHORT);
1600 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1601 break;
1602 case RPC_FC_LONG:
1603 case RPC_FC_ULONG:
1604 case RPC_FC_ERROR_STATUS_T:
1605 case RPC_FC_ENUM32:
1606 BASE_TYPE_UNMARSHALL(ULONG);
1607 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1608 break;
1609 case RPC_FC_FLOAT:
1610 BASE_TYPE_UNMARSHALL(float);
1611 TRACE("value: %f\n", *(float *)pMemory);
1612 break;
1613 case RPC_FC_DOUBLE:
1614 BASE_TYPE_UNMARSHALL(double);
1615 TRACE("value: %f\n", *(double *)pMemory);
1616 break;
1617 case RPC_FC_HYPER:
1618 BASE_TYPE_UNMARSHALL(ULONGLONG);
1619 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1620 break;
1621 case RPC_FC_ENUM16:
1622 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1623 TRACE("pMemory: %p\n", pMemory);
1624 /* 16-bits on the wire, but int in memory */
1625 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1626 pStubMsg->Buffer += sizeof(USHORT);
1627 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1628 break;
1629 case RPC_FC_IGNORE:
1630 break;
1631 default:
1632 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1634 #undef BASE_TYPE_UNMARSHALL
1637 /***********************************************************************
1638 * NdrSimpleStructMarshall [RPCRT4.@]
1640 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1641 unsigned char *pMemory,
1642 PFORMAT_STRING pFormat)
1644 unsigned size = *(const WORD*)(pFormat+2);
1645 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1647 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1649 pStubMsg->BufferMark = pStubMsg->Buffer;
1650 safe_copy_to_buffer(pStubMsg, pMemory, size);
1652 if (pFormat[0] != RPC_FC_STRUCT)
1653 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1655 return NULL;
1658 /***********************************************************************
1659 * NdrSimpleStructUnmarshall [RPCRT4.@]
1661 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1662 unsigned char **ppMemory,
1663 PFORMAT_STRING pFormat,
1664 unsigned char fMustAlloc)
1666 unsigned size = *(const WORD*)(pFormat+2);
1667 unsigned char *saved_buffer;
1668 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1670 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1672 if (fMustAlloc)
1673 *ppMemory = NdrAllocate(pStubMsg, size);
1674 else
1676 if (!pStubMsg->IsClient && !*ppMemory)
1677 /* for servers, we just point straight into the RPC buffer */
1678 *ppMemory = pStubMsg->Buffer;
1681 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1682 safe_buffer_increment(pStubMsg, size);
1683 if (pFormat[0] == RPC_FC_PSTRUCT)
1684 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1686 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1687 if (*ppMemory != saved_buffer)
1688 memcpy(*ppMemory, saved_buffer, size);
1690 return NULL;
1693 /***********************************************************************
1694 * NdrSimpleStructBufferSize [RPCRT4.@]
1696 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1697 unsigned char *pMemory,
1698 PFORMAT_STRING pFormat)
1700 unsigned size = *(const WORD*)(pFormat+2);
1701 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1703 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1705 safe_buffer_length_increment(pStubMsg, size);
1706 if (pFormat[0] != RPC_FC_STRUCT)
1707 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1710 /***********************************************************************
1711 * NdrSimpleStructMemorySize [RPCRT4.@]
1713 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1714 PFORMAT_STRING pFormat)
1716 unsigned short size = *(const WORD *)(pFormat+2);
1718 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1720 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1721 pStubMsg->MemorySize += size;
1722 safe_buffer_increment(pStubMsg, size);
1724 if (pFormat[0] != RPC_FC_STRUCT)
1725 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1726 return pStubMsg->MemorySize;
1729 /***********************************************************************
1730 * NdrSimpleStructFree [RPCRT4.@]
1732 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1733 unsigned char *pMemory,
1734 PFORMAT_STRING pFormat)
1736 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1737 if (pFormat[0] != RPC_FC_STRUCT)
1738 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1741 /* Array helpers */
1743 static inline void array_compute_and_size_conformance(
1744 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1745 PFORMAT_STRING pFormat)
1747 switch (fc)
1749 case RPC_FC_CARRAY:
1750 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1751 SizeConformance(pStubMsg);
1752 break;
1753 case RPC_FC_CVARRAY:
1754 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1755 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1756 SizeConformance(pStubMsg);
1757 break;
1758 case RPC_FC_C_CSTRING:
1759 case RPC_FC_C_WSTRING:
1760 if (pFormat[0] == RPC_FC_C_CSTRING)
1762 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1763 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1765 else
1767 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1768 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1771 if (fc == RPC_FC_STRING_SIZED)
1772 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1773 else
1774 pStubMsg->MaxCount = pStubMsg->ActualCount;
1776 SizeConformance(pStubMsg);
1777 break;
1778 default:
1779 ERR("unknown array format 0x%x\n", fc);
1780 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1784 static inline void array_buffer_size(
1785 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1786 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1788 DWORD size;
1789 DWORD esize;
1790 unsigned char alignment;
1792 switch (fc)
1794 case RPC_FC_CARRAY:
1795 esize = *(const WORD*)(pFormat+2);
1796 alignment = pFormat[1] + 1;
1798 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1800 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1802 size = safe_multiply(esize, pStubMsg->MaxCount);
1803 /* conformance value plus array */
1804 safe_buffer_length_increment(pStubMsg, size);
1806 if (fHasPointers)
1807 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1808 break;
1809 case RPC_FC_CVARRAY:
1810 esize = *(const WORD*)(pFormat+2);
1811 alignment = pFormat[1] + 1;
1813 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1814 pFormat = SkipConformance(pStubMsg, pFormat);
1816 SizeVariance(pStubMsg);
1818 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1820 size = safe_multiply(esize, pStubMsg->ActualCount);
1821 safe_buffer_length_increment(pStubMsg, size);
1823 if (fHasPointers)
1824 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1825 break;
1826 case RPC_FC_C_CSTRING:
1827 case RPC_FC_C_WSTRING:
1828 if (fc == RPC_FC_C_CSTRING)
1829 esize = 1;
1830 else
1831 esize = 2;
1833 SizeVariance(pStubMsg);
1835 size = safe_multiply(esize, pStubMsg->ActualCount);
1836 safe_buffer_length_increment(pStubMsg, size);
1837 break;
1838 default:
1839 ERR("unknown array format 0x%x\n", fc);
1840 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1844 static inline void array_compute_and_write_conformance(
1845 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1846 PFORMAT_STRING pFormat)
1848 switch (fc)
1850 case RPC_FC_CARRAY:
1851 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1852 WriteConformance(pStubMsg);
1853 break;
1854 case RPC_FC_CVARRAY:
1855 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1856 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1857 WriteConformance(pStubMsg);
1858 break;
1859 case RPC_FC_C_CSTRING:
1860 case RPC_FC_C_WSTRING:
1861 if (fc == RPC_FC_C_CSTRING)
1863 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1864 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1866 else
1868 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1869 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1871 if (pFormat[1] == RPC_FC_STRING_SIZED)
1872 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1873 else
1874 pStubMsg->MaxCount = pStubMsg->ActualCount;
1875 pStubMsg->Offset = 0;
1876 WriteConformance(pStubMsg);
1877 break;
1878 default:
1879 ERR("unknown array format 0x%x\n", fc);
1880 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1884 static inline void array_write_variance_and_marshall(
1885 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1886 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1888 DWORD size;
1889 DWORD esize;
1890 unsigned char alignment;
1892 switch (fc)
1894 case RPC_FC_CARRAY:
1895 esize = *(const WORD*)(pFormat+2);
1896 alignment = pFormat[1] + 1;
1898 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1900 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1902 size = safe_multiply(esize, pStubMsg->MaxCount);
1903 if (fHasPointers)
1904 pStubMsg->BufferMark = pStubMsg->Buffer;
1905 safe_copy_to_buffer(pStubMsg, pMemory, size);
1907 if (fHasPointers)
1908 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1909 break;
1910 case RPC_FC_CVARRAY:
1911 esize = *(const WORD*)(pFormat+2);
1912 alignment = pFormat[1] + 1;
1914 /* conformance */
1915 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1916 /* variance */
1917 pFormat = SkipConformance(pStubMsg, pFormat);
1919 WriteVariance(pStubMsg);
1921 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1923 size = safe_multiply(esize, pStubMsg->ActualCount);
1925 if (fHasPointers)
1926 pStubMsg->BufferMark = pStubMsg->Buffer;
1927 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
1929 if (fHasPointers)
1930 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1931 break;
1932 case RPC_FC_C_CSTRING:
1933 case RPC_FC_C_WSTRING:
1934 if (fc == RPC_FC_C_CSTRING)
1935 esize = 1;
1936 else
1937 esize = 2;
1939 WriteVariance(pStubMsg);
1941 size = safe_multiply(esize, pStubMsg->ActualCount);
1942 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
1943 break;
1944 default:
1945 ERR("unknown array format 0x%x\n", fc);
1946 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1950 static inline ULONG array_read_conformance(
1951 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
1953 DWORD esize;
1955 switch (fc)
1957 case RPC_FC_CARRAY:
1958 esize = *(const WORD*)(pFormat+2);
1959 pFormat = ReadConformance(pStubMsg, pFormat+4);
1960 return safe_multiply(esize, pStubMsg->MaxCount);
1961 case RPC_FC_CVARRAY:
1962 esize = *(const WORD*)(pFormat+2);
1963 pFormat = ReadConformance(pStubMsg, pFormat+4);
1964 return safe_multiply(esize, pStubMsg->MaxCount);
1965 case RPC_FC_C_CSTRING:
1966 case RPC_FC_C_WSTRING:
1967 if (fc == RPC_FC_C_CSTRING)
1968 esize = 1;
1969 else
1970 esize = 2;
1972 if (pFormat[1] == RPC_FC_STRING_SIZED)
1973 ReadConformance(pStubMsg, pFormat + 2);
1974 else
1975 ReadConformance(pStubMsg, NULL);
1976 return safe_multiply(esize, pStubMsg->MaxCount);
1977 default:
1978 ERR("unknown array format 0x%x\n", fc);
1979 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1983 static inline ULONG array_read_variance_and_unmarshall(
1984 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
1985 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
1986 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
1988 ULONG bufsize, memsize;
1989 WORD esize;
1990 unsigned char alignment;
1991 unsigned char *saved_buffer;
1992 ULONG offset;
1994 switch (fc)
1996 case RPC_FC_CARRAY:
1997 esize = *(const WORD*)(pFormat+2);
1998 alignment = pFormat[1] + 1;
2000 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2002 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2004 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2006 if (fUnmarshall)
2008 if (fMustAlloc)
2009 *ppMemory = NdrAllocate(pStubMsg, memsize);
2010 else
2012 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2013 /* for servers, we just point straight into the RPC buffer */
2014 *ppMemory = pStubMsg->Buffer;
2017 saved_buffer = pStubMsg->Buffer;
2018 safe_buffer_increment(pStubMsg, bufsize);
2020 pStubMsg->BufferMark = saved_buffer;
2021 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2023 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2024 if (*ppMemory != saved_buffer)
2025 memcpy(*ppMemory, saved_buffer, bufsize);
2027 return bufsize;
2028 case RPC_FC_CVARRAY:
2029 esize = *(const WORD*)(pFormat+2);
2030 alignment = pFormat[1] + 1;
2032 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2034 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2036 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2038 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2039 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2041 if (fUnmarshall)
2043 offset = pStubMsg->Offset;
2045 if (!fMustAlloc && !*ppMemory)
2046 fMustAlloc = TRUE;
2047 if (fMustAlloc)
2048 *ppMemory = NdrAllocate(pStubMsg, memsize);
2049 saved_buffer = pStubMsg->Buffer;
2050 safe_buffer_increment(pStubMsg, bufsize);
2052 pStubMsg->BufferMark = saved_buffer;
2053 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2054 fMustAlloc);
2056 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2058 return bufsize;
2059 case RPC_FC_C_CSTRING:
2060 case RPC_FC_C_WSTRING:
2061 if (fc == RPC_FC_C_CSTRING)
2062 esize = 1;
2063 else
2064 esize = 2;
2066 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2068 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2070 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2071 pStubMsg->ActualCount, pStubMsg->MaxCount);
2072 RpcRaiseException(RPC_S_INVALID_BOUND);
2074 if (pStubMsg->Offset)
2076 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2077 RpcRaiseException(RPC_S_INVALID_BOUND);
2080 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2081 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2083 validate_string_data(pStubMsg, bufsize, esize);
2085 if (fUnmarshall)
2087 if (fMustAlloc)
2088 *ppMemory = NdrAllocate(pStubMsg, memsize);
2089 else
2091 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2092 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2093 /* if the data in the RPC buffer is big enough, we just point
2094 * straight into it */
2095 *ppMemory = pStubMsg->Buffer;
2096 else if (!*ppMemory)
2097 *ppMemory = NdrAllocate(pStubMsg, memsize);
2100 if (*ppMemory == pStubMsg->Buffer)
2101 safe_buffer_increment(pStubMsg, bufsize);
2102 else
2103 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2105 if (*pFormat == RPC_FC_C_CSTRING)
2106 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2107 else
2108 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2110 return bufsize;
2111 default:
2112 ERR("unknown array format 0x%x\n", fc);
2113 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2117 static inline void array_memory_size(
2118 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2119 unsigned char fHasPointers)
2121 ULONG bufsize, memsize;
2122 DWORD esize;
2123 unsigned char alignment;
2125 switch (fc)
2127 case RPC_FC_CARRAY:
2128 esize = *(const WORD*)(pFormat+2);
2129 alignment = pFormat[1] + 1;
2131 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2133 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2134 pStubMsg->MemorySize += memsize;
2136 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2137 if (fHasPointers)
2138 pStubMsg->BufferMark = pStubMsg->Buffer;
2139 safe_buffer_increment(pStubMsg, bufsize);
2141 if (fHasPointers)
2142 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2143 break;
2144 case RPC_FC_CVARRAY:
2145 esize = *(const WORD*)(pFormat+2);
2146 alignment = pFormat[1] + 1;
2148 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2150 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2152 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2153 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2154 pStubMsg->MemorySize += memsize;
2156 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2157 if (fHasPointers)
2158 pStubMsg->BufferMark = pStubMsg->Buffer;
2159 safe_buffer_increment(pStubMsg, bufsize);
2161 if (fHasPointers)
2162 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2163 break;
2164 case RPC_FC_C_CSTRING:
2165 case RPC_FC_C_WSTRING:
2166 if (fc == RPC_FC_C_CSTRING)
2167 esize = 1;
2168 else
2169 esize = 2;
2171 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2173 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2175 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2176 pStubMsg->ActualCount, pStubMsg->MaxCount);
2177 RpcRaiseException(RPC_S_INVALID_BOUND);
2179 if (pStubMsg->Offset)
2181 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2182 RpcRaiseException(RPC_S_INVALID_BOUND);
2185 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2186 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2188 validate_string_data(pStubMsg, bufsize, esize);
2190 safe_buffer_increment(pStubMsg, bufsize);
2191 pStubMsg->MemorySize += memsize;
2192 break;
2193 default:
2194 ERR("unknown array format 0x%x\n", fc);
2195 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2199 static inline void array_free(
2200 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2201 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2203 switch (fc)
2205 case RPC_FC_CARRAY:
2206 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2207 if (fHasPointers)
2208 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2209 break;
2210 case RPC_FC_CVARRAY:
2211 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2212 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2213 if (fHasPointers)
2214 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2215 break;
2216 case RPC_FC_C_CSTRING:
2217 case RPC_FC_C_WSTRING:
2218 /* No embedded pointers so nothing to do */
2219 break;
2220 default:
2221 ERR("unknown array format 0x%x\n", fc);
2222 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2227 * NdrConformantString:
2229 * What MS calls a ConformantString is, in DCE terminology,
2230 * a Varying-Conformant String.
2232 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2233 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2234 * into unmarshalled string)
2235 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2237 * data: CHARTYPE[maxlen]
2239 * ], where CHARTYPE is the appropriate character type (specified externally)
2243 /***********************************************************************
2244 * NdrConformantStringMarshall [RPCRT4.@]
2246 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2247 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2249 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2251 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2252 ERR("Unhandled string type: %#x\n", pFormat[0]);
2253 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2256 /* allow compiler to optimise inline function by passing constant into
2257 * these functions */
2258 if (pFormat[0] == RPC_FC_C_CSTRING) {
2259 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2260 pFormat);
2261 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2262 pFormat, TRUE /* fHasPointers */);
2263 } else {
2264 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2265 pFormat);
2266 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2267 pFormat, TRUE /* fHasPointers */);
2270 return NULL;
2273 /***********************************************************************
2274 * NdrConformantStringBufferSize [RPCRT4.@]
2276 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2277 unsigned char* pMemory, PFORMAT_STRING pFormat)
2279 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2281 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2282 ERR("Unhandled string type: %#x\n", pFormat[0]);
2283 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2286 /* allow compiler to optimise inline function by passing constant into
2287 * these functions */
2288 if (pFormat[0] == RPC_FC_C_CSTRING) {
2289 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2290 pFormat);
2291 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2292 TRUE /* fHasPointers */);
2293 } else {
2294 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2295 pFormat);
2296 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2297 TRUE /* fHasPointers */);
2301 /************************************************************************
2302 * NdrConformantStringMemorySize [RPCRT4.@]
2304 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2305 PFORMAT_STRING pFormat )
2307 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2309 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2310 ERR("Unhandled string type: %#x\n", pFormat[0]);
2311 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2314 /* allow compiler to optimise inline function by passing constant into
2315 * these functions */
2316 if (pFormat[0] == RPC_FC_C_CSTRING) {
2317 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2318 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2319 TRUE /* fHasPointers */);
2320 } else {
2321 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2322 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2323 TRUE /* fHasPointers */);
2326 return pStubMsg->MemorySize;
2329 /************************************************************************
2330 * NdrConformantStringUnmarshall [RPCRT4.@]
2332 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2333 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2335 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2336 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2338 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2339 ERR("Unhandled string type: %#x\n", *pFormat);
2340 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2343 /* allow compiler to optimise inline function by passing constant into
2344 * these functions */
2345 if (pFormat[0] == RPC_FC_C_CSTRING) {
2346 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2347 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2348 pFormat, fMustAlloc,
2349 TRUE /* fUseBufferMemoryServer */,
2350 TRUE /* fUnmarshall */);
2351 } else {
2352 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2353 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2354 pFormat, fMustAlloc,
2355 TRUE /* fUseBufferMemoryServer */,
2356 TRUE /* fUnmarshall */);
2359 return NULL;
2362 /***********************************************************************
2363 * NdrNonConformantStringMarshall [RPCRT4.@]
2365 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2366 unsigned char *pMemory,
2367 PFORMAT_STRING pFormat)
2369 ULONG esize, size, maxsize;
2371 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2373 maxsize = *(USHORT *)&pFormat[2];
2375 if (*pFormat == RPC_FC_CSTRING)
2377 ULONG i;
2378 const char *str = (const char *)pMemory;
2379 for (i = 0; i < maxsize && *str; i++, str++)
2381 TRACE("string=%s\n", debugstr_an(str, i));
2382 pStubMsg->ActualCount = i + 1;
2383 esize = 1;
2385 else if (*pFormat == RPC_FC_WSTRING)
2387 ULONG i;
2388 const WCHAR *str = (const WCHAR *)pMemory;
2389 for (i = 0; i < maxsize && *str; i++, str++)
2391 TRACE("string=%s\n", debugstr_wn(str, i));
2392 pStubMsg->ActualCount = i + 1;
2393 esize = 2;
2395 else
2397 ERR("Unhandled string type: %#x\n", *pFormat);
2398 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2401 pStubMsg->Offset = 0;
2402 WriteVariance(pStubMsg);
2404 size = safe_multiply(esize, pStubMsg->ActualCount);
2405 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2407 return NULL;
2410 /***********************************************************************
2411 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2413 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2414 unsigned char **ppMemory,
2415 PFORMAT_STRING pFormat,
2416 unsigned char fMustAlloc)
2418 ULONG bufsize, memsize, esize, maxsize;
2420 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2421 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2423 maxsize = *(USHORT *)&pFormat[2];
2425 ReadVariance(pStubMsg, NULL, maxsize);
2426 if (pStubMsg->Offset)
2428 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2429 RpcRaiseException(RPC_S_INVALID_BOUND);
2432 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2433 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2434 else
2436 ERR("Unhandled string type: %#x\n", *pFormat);
2437 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2440 memsize = esize * maxsize;
2441 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2443 validate_string_data(pStubMsg, bufsize, esize);
2445 if (fMustAlloc || !*ppMemory)
2446 *ppMemory = NdrAllocate(pStubMsg, memsize);
2448 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2450 if (*pFormat == RPC_FC_CSTRING) {
2451 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2453 else if (*pFormat == RPC_FC_WSTRING) {
2454 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2457 return NULL;
2460 /***********************************************************************
2461 * NdrNonConformantStringBufferSize [RPCRT4.@]
2463 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2464 unsigned char *pMemory,
2465 PFORMAT_STRING pFormat)
2467 ULONG esize, maxsize;
2469 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2471 maxsize = *(USHORT *)&pFormat[2];
2473 SizeVariance(pStubMsg);
2475 if (*pFormat == RPC_FC_CSTRING)
2477 ULONG i;
2478 const char *str = (const char *)pMemory;
2479 for (i = 0; i < maxsize && *str; i++, str++)
2481 TRACE("string=%s\n", debugstr_an(str, i));
2482 pStubMsg->ActualCount = i + 1;
2483 esize = 1;
2485 else if (*pFormat == RPC_FC_WSTRING)
2487 ULONG i;
2488 const WCHAR *str = (const WCHAR *)pMemory;
2489 for (i = 0; i < maxsize && *str; i++, str++)
2491 TRACE("string=%s\n", debugstr_wn(str, i));
2492 pStubMsg->ActualCount = i + 1;
2493 esize = 2;
2495 else
2497 ERR("Unhandled string type: %#x\n", *pFormat);
2498 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2501 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2504 /***********************************************************************
2505 * NdrNonConformantStringMemorySize [RPCRT4.@]
2507 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2508 PFORMAT_STRING pFormat)
2510 ULONG bufsize, memsize, esize, maxsize;
2512 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2514 maxsize = *(USHORT *)&pFormat[2];
2516 ReadVariance(pStubMsg, NULL, maxsize);
2518 if (pStubMsg->Offset)
2520 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2521 RpcRaiseException(RPC_S_INVALID_BOUND);
2524 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2525 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2526 else
2528 ERR("Unhandled string type: %#x\n", *pFormat);
2529 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2532 memsize = esize * maxsize;
2533 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2535 validate_string_data(pStubMsg, bufsize, esize);
2537 safe_buffer_increment(pStubMsg, bufsize);
2538 pStubMsg->MemorySize += memsize;
2540 return pStubMsg->MemorySize;
2543 /* Complex types */
2545 #include "pshpack1.h"
2546 typedef struct
2548 unsigned char type;
2549 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2550 ULONG low_value;
2551 ULONG high_value;
2552 } NDR_RANGE;
2553 #include "poppack.h"
2555 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2556 PFORMAT_STRING pFormat)
2558 switch (*pFormat) {
2559 case RPC_FC_STRUCT:
2560 case RPC_FC_PSTRUCT:
2561 case RPC_FC_CSTRUCT:
2562 case RPC_FC_BOGUS_STRUCT:
2563 case RPC_FC_SMFARRAY:
2564 case RPC_FC_SMVARRAY:
2565 case RPC_FC_CSTRING:
2566 return *(const WORD*)&pFormat[2];
2567 case RPC_FC_USER_MARSHAL:
2568 return *(const WORD*)&pFormat[4];
2569 case RPC_FC_RANGE: {
2570 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2571 case RPC_FC_BYTE:
2572 case RPC_FC_CHAR:
2573 case RPC_FC_SMALL:
2574 case RPC_FC_USMALL:
2575 return sizeof(UCHAR);
2576 case RPC_FC_WCHAR:
2577 case RPC_FC_SHORT:
2578 case RPC_FC_USHORT:
2579 return sizeof(USHORT);
2580 case RPC_FC_LONG:
2581 case RPC_FC_ULONG:
2582 case RPC_FC_ENUM32:
2583 return sizeof(ULONG);
2584 case RPC_FC_FLOAT:
2585 return sizeof(float);
2586 case RPC_FC_DOUBLE:
2587 return sizeof(double);
2588 case RPC_FC_HYPER:
2589 return sizeof(ULONGLONG);
2590 case RPC_FC_ENUM16:
2591 return sizeof(UINT);
2592 default:
2593 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2594 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2597 case RPC_FC_NON_ENCAPSULATED_UNION:
2598 pFormat += 2;
2599 if (pStubMsg->fHasNewCorrDesc)
2600 pFormat += 6;
2601 else
2602 pFormat += 4;
2604 pFormat += *(const SHORT*)pFormat;
2605 return *(const SHORT*)pFormat;
2606 case RPC_FC_IP:
2607 return sizeof(void *);
2608 case RPC_FC_WSTRING:
2609 return *(const WORD*)&pFormat[2] * 2;
2610 default:
2611 FIXME("unhandled embedded type %02x\n", *pFormat);
2613 return 0;
2617 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2618 PFORMAT_STRING pFormat)
2620 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2622 if (!m)
2624 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2625 return 0;
2628 return m(pStubMsg, pFormat);
2632 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2633 unsigned char *pMemory,
2634 PFORMAT_STRING pFormat,
2635 PFORMAT_STRING pPointer)
2637 PFORMAT_STRING desc;
2638 NDR_MARSHALL m;
2639 unsigned long size;
2641 while (*pFormat != RPC_FC_END) {
2642 switch (*pFormat) {
2643 case RPC_FC_BYTE:
2644 case RPC_FC_CHAR:
2645 case RPC_FC_SMALL:
2646 case RPC_FC_USMALL:
2647 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2648 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2649 pMemory += 1;
2650 break;
2651 case RPC_FC_WCHAR:
2652 case RPC_FC_SHORT:
2653 case RPC_FC_USHORT:
2654 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2655 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2656 pMemory += 2;
2657 break;
2658 case RPC_FC_ENUM16:
2659 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2660 if (32767 < *(DWORD*)pMemory)
2661 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2662 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2663 pMemory += 4;
2664 break;
2665 case RPC_FC_LONG:
2666 case RPC_FC_ULONG:
2667 case RPC_FC_ENUM32:
2668 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2669 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2670 pMemory += 4;
2671 break;
2672 case RPC_FC_HYPER:
2673 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2674 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2675 pMemory += 8;
2676 break;
2677 case RPC_FC_POINTER:
2679 unsigned char *saved_buffer;
2680 int pointer_buffer_mark_set = 0;
2681 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2682 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2683 if (*pPointer != RPC_FC_RP)
2684 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2685 saved_buffer = pStubMsg->Buffer;
2686 if (pStubMsg->PointerBufferMark)
2688 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2689 pStubMsg->PointerBufferMark = NULL;
2690 pointer_buffer_mark_set = 1;
2692 else if (*pPointer != RPC_FC_RP)
2693 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2694 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2695 if (pointer_buffer_mark_set)
2697 STD_OVERFLOW_CHECK(pStubMsg);
2698 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2699 pStubMsg->Buffer = saved_buffer;
2700 if (*pPointer != RPC_FC_RP)
2701 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2703 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2704 pPointer += 4;
2705 pMemory += 4;
2706 break;
2708 case RPC_FC_ALIGNM4:
2709 ALIGN_POINTER(pMemory, 4);
2710 break;
2711 case RPC_FC_ALIGNM8:
2712 ALIGN_POINTER(pMemory, 8);
2713 break;
2714 case RPC_FC_STRUCTPAD1:
2715 case RPC_FC_STRUCTPAD2:
2716 case RPC_FC_STRUCTPAD3:
2717 case RPC_FC_STRUCTPAD4:
2718 case RPC_FC_STRUCTPAD5:
2719 case RPC_FC_STRUCTPAD6:
2720 case RPC_FC_STRUCTPAD7:
2721 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2722 break;
2723 case RPC_FC_EMBEDDED_COMPLEX:
2724 pMemory += pFormat[1];
2725 pFormat += 2;
2726 desc = pFormat + *(const SHORT*)pFormat;
2727 size = EmbeddedComplexSize(pStubMsg, desc);
2728 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2729 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2730 if (m)
2732 /* for some reason interface pointers aren't generated as
2733 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2734 * they still need the derefencing treatment that pointers are
2735 * given */
2736 if (*desc == RPC_FC_IP)
2737 m(pStubMsg, *(unsigned char **)pMemory, desc);
2738 else
2739 m(pStubMsg, pMemory, desc);
2741 else FIXME("no marshaller for embedded type %02x\n", *desc);
2742 pMemory += size;
2743 pFormat += 2;
2744 continue;
2745 case RPC_FC_PAD:
2746 break;
2747 default:
2748 FIXME("unhandled format 0x%02x\n", *pFormat);
2750 pFormat++;
2753 return pMemory;
2756 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2757 unsigned char *pMemory,
2758 PFORMAT_STRING pFormat,
2759 PFORMAT_STRING pPointer,
2760 unsigned char fMustAlloc)
2762 PFORMAT_STRING desc;
2763 NDR_UNMARSHALL m;
2764 unsigned long size;
2766 while (*pFormat != RPC_FC_END) {
2767 switch (*pFormat) {
2768 case RPC_FC_BYTE:
2769 case RPC_FC_CHAR:
2770 case RPC_FC_SMALL:
2771 case RPC_FC_USMALL:
2772 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2773 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2774 pMemory += 1;
2775 break;
2776 case RPC_FC_WCHAR:
2777 case RPC_FC_SHORT:
2778 case RPC_FC_USHORT:
2779 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2780 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2781 pMemory += 2;
2782 break;
2783 case RPC_FC_ENUM16:
2784 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2785 *(DWORD*)pMemory &= 0xffff;
2786 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2787 if (32767 < *(DWORD*)pMemory)
2788 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2789 pMemory += 4;
2790 break;
2791 case RPC_FC_LONG:
2792 case RPC_FC_ULONG:
2793 case RPC_FC_ENUM32:
2794 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2795 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2796 pMemory += 4;
2797 break;
2798 case RPC_FC_HYPER:
2799 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2800 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2801 pMemory += 8;
2802 break;
2803 case RPC_FC_POINTER:
2805 unsigned char *saved_buffer;
2806 int pointer_buffer_mark_set = 0;
2807 TRACE("pointer => %p\n", pMemory);
2808 if (*pPointer != RPC_FC_RP)
2809 ALIGN_POINTER(pStubMsg->Buffer, 4);
2810 saved_buffer = pStubMsg->Buffer;
2811 if (pStubMsg->PointerBufferMark)
2813 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2814 pStubMsg->PointerBufferMark = NULL;
2815 pointer_buffer_mark_set = 1;
2817 else if (*pPointer != RPC_FC_RP)
2818 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2820 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2821 if (pointer_buffer_mark_set)
2823 STD_OVERFLOW_CHECK(pStubMsg);
2824 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2825 pStubMsg->Buffer = saved_buffer;
2826 if (*pPointer != RPC_FC_RP)
2827 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2829 pPointer += 4;
2830 pMemory += 4;
2831 break;
2833 case RPC_FC_ALIGNM4:
2834 ALIGN_POINTER_CLEAR(pMemory, 4);
2835 break;
2836 case RPC_FC_ALIGNM8:
2837 ALIGN_POINTER_CLEAR(pMemory, 8);
2838 break;
2839 case RPC_FC_STRUCTPAD1:
2840 case RPC_FC_STRUCTPAD2:
2841 case RPC_FC_STRUCTPAD3:
2842 case RPC_FC_STRUCTPAD4:
2843 case RPC_FC_STRUCTPAD5:
2844 case RPC_FC_STRUCTPAD6:
2845 case RPC_FC_STRUCTPAD7:
2846 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2847 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2848 break;
2849 case RPC_FC_EMBEDDED_COMPLEX:
2850 pMemory += pFormat[1];
2851 pFormat += 2;
2852 desc = pFormat + *(const SHORT*)pFormat;
2853 size = EmbeddedComplexSize(pStubMsg, desc);
2854 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2855 if (fMustAlloc)
2856 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2857 * since the type is part of the memory block that is encompassed by
2858 * the whole complex type. Memory is forced to allocate when pointers
2859 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2860 * clearing the memory we pass in to the unmarshaller */
2861 memset(pMemory, 0, size);
2862 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2863 if (m)
2865 /* for some reason interface pointers aren't generated as
2866 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2867 * they still need the derefencing treatment that pointers are
2868 * given */
2869 if (*desc == RPC_FC_IP)
2870 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2871 else
2872 m(pStubMsg, &pMemory, desc, FALSE);
2874 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2875 pMemory += size;
2876 pFormat += 2;
2877 continue;
2878 case RPC_FC_PAD:
2879 break;
2880 default:
2881 FIXME("unhandled format %d\n", *pFormat);
2883 pFormat++;
2886 return pMemory;
2889 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2890 unsigned char *pMemory,
2891 PFORMAT_STRING pFormat,
2892 PFORMAT_STRING pPointer)
2894 PFORMAT_STRING desc;
2895 NDR_BUFFERSIZE m;
2896 unsigned long size;
2898 while (*pFormat != RPC_FC_END) {
2899 switch (*pFormat) {
2900 case RPC_FC_BYTE:
2901 case RPC_FC_CHAR:
2902 case RPC_FC_SMALL:
2903 case RPC_FC_USMALL:
2904 safe_buffer_length_increment(pStubMsg, 1);
2905 pMemory += 1;
2906 break;
2907 case RPC_FC_WCHAR:
2908 case RPC_FC_SHORT:
2909 case RPC_FC_USHORT:
2910 safe_buffer_length_increment(pStubMsg, 2);
2911 pMemory += 2;
2912 break;
2913 case RPC_FC_ENUM16:
2914 safe_buffer_length_increment(pStubMsg, 2);
2915 pMemory += 4;
2916 break;
2917 case RPC_FC_LONG:
2918 case RPC_FC_ULONG:
2919 case RPC_FC_ENUM32:
2920 safe_buffer_length_increment(pStubMsg, 4);
2921 pMemory += 4;
2922 break;
2923 case RPC_FC_HYPER:
2924 safe_buffer_length_increment(pStubMsg, 8);
2925 pMemory += 8;
2926 break;
2927 case RPC_FC_POINTER:
2928 if (!pStubMsg->IgnoreEmbeddedPointers)
2930 int saved_buffer_length = pStubMsg->BufferLength;
2931 pStubMsg->BufferLength = pStubMsg->PointerLength;
2932 pStubMsg->PointerLength = 0;
2933 if(!pStubMsg->BufferLength)
2934 ERR("BufferLength == 0??\n");
2935 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2936 pStubMsg->PointerLength = pStubMsg->BufferLength;
2937 pStubMsg->BufferLength = saved_buffer_length;
2939 if (*pPointer != RPC_FC_RP)
2941 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2942 safe_buffer_length_increment(pStubMsg, 4);
2944 pPointer += 4;
2945 pMemory += 4;
2946 break;
2947 case RPC_FC_ALIGNM4:
2948 ALIGN_POINTER(pMemory, 4);
2949 break;
2950 case RPC_FC_ALIGNM8:
2951 ALIGN_POINTER(pMemory, 8);
2952 break;
2953 case RPC_FC_STRUCTPAD1:
2954 case RPC_FC_STRUCTPAD2:
2955 case RPC_FC_STRUCTPAD3:
2956 case RPC_FC_STRUCTPAD4:
2957 case RPC_FC_STRUCTPAD5:
2958 case RPC_FC_STRUCTPAD6:
2959 case RPC_FC_STRUCTPAD7:
2960 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2961 break;
2962 case RPC_FC_EMBEDDED_COMPLEX:
2963 pMemory += pFormat[1];
2964 pFormat += 2;
2965 desc = pFormat + *(const SHORT*)pFormat;
2966 size = EmbeddedComplexSize(pStubMsg, desc);
2967 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2968 if (m)
2970 /* for some reason interface pointers aren't generated as
2971 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2972 * they still need the derefencing treatment that pointers are
2973 * given */
2974 if (*desc == RPC_FC_IP)
2975 m(pStubMsg, *(unsigned char **)pMemory, desc);
2976 else
2977 m(pStubMsg, pMemory, desc);
2979 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2980 pMemory += size;
2981 pFormat += 2;
2982 continue;
2983 case RPC_FC_PAD:
2984 break;
2985 default:
2986 FIXME("unhandled format 0x%02x\n", *pFormat);
2988 pFormat++;
2991 return pMemory;
2994 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2995 unsigned char *pMemory,
2996 PFORMAT_STRING pFormat,
2997 PFORMAT_STRING pPointer)
2999 PFORMAT_STRING desc;
3000 NDR_FREE m;
3001 unsigned long size;
3003 while (*pFormat != RPC_FC_END) {
3004 switch (*pFormat) {
3005 case RPC_FC_BYTE:
3006 case RPC_FC_CHAR:
3007 case RPC_FC_SMALL:
3008 case RPC_FC_USMALL:
3009 pMemory += 1;
3010 break;
3011 case RPC_FC_WCHAR:
3012 case RPC_FC_SHORT:
3013 case RPC_FC_USHORT:
3014 pMemory += 2;
3015 break;
3016 case RPC_FC_LONG:
3017 case RPC_FC_ULONG:
3018 case RPC_FC_ENUM16:
3019 case RPC_FC_ENUM32:
3020 pMemory += 4;
3021 break;
3022 case RPC_FC_HYPER:
3023 pMemory += 8;
3024 break;
3025 case RPC_FC_POINTER:
3026 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3027 pPointer += 4;
3028 pMemory += 4;
3029 break;
3030 case RPC_FC_ALIGNM4:
3031 ALIGN_POINTER(pMemory, 4);
3032 break;
3033 case RPC_FC_ALIGNM8:
3034 ALIGN_POINTER(pMemory, 8);
3035 break;
3036 case RPC_FC_STRUCTPAD1:
3037 case RPC_FC_STRUCTPAD2:
3038 case RPC_FC_STRUCTPAD3:
3039 case RPC_FC_STRUCTPAD4:
3040 case RPC_FC_STRUCTPAD5:
3041 case RPC_FC_STRUCTPAD6:
3042 case RPC_FC_STRUCTPAD7:
3043 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3044 break;
3045 case RPC_FC_EMBEDDED_COMPLEX:
3046 pMemory += pFormat[1];
3047 pFormat += 2;
3048 desc = pFormat + *(const SHORT*)pFormat;
3049 size = EmbeddedComplexSize(pStubMsg, desc);
3050 m = NdrFreer[*desc & NDR_TABLE_MASK];
3051 if (m)
3053 /* for some reason interface pointers aren't generated as
3054 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3055 * they still need the derefencing treatment that pointers are
3056 * given */
3057 if (*desc == RPC_FC_IP)
3058 m(pStubMsg, *(unsigned char **)pMemory, desc);
3059 else
3060 m(pStubMsg, pMemory, desc);
3062 pMemory += size;
3063 pFormat += 2;
3064 continue;
3065 case RPC_FC_PAD:
3066 break;
3067 default:
3068 FIXME("unhandled format 0x%02x\n", *pFormat);
3070 pFormat++;
3073 return pMemory;
3076 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3077 PFORMAT_STRING pFormat,
3078 PFORMAT_STRING pPointer)
3080 PFORMAT_STRING desc;
3081 unsigned long size = 0;
3083 while (*pFormat != RPC_FC_END) {
3084 switch (*pFormat) {
3085 case RPC_FC_BYTE:
3086 case RPC_FC_CHAR:
3087 case RPC_FC_SMALL:
3088 case RPC_FC_USMALL:
3089 size += 1;
3090 safe_buffer_increment(pStubMsg, 1);
3091 break;
3092 case RPC_FC_WCHAR:
3093 case RPC_FC_SHORT:
3094 case RPC_FC_USHORT:
3095 size += 2;
3096 safe_buffer_increment(pStubMsg, 2);
3097 break;
3098 case RPC_FC_ENUM16:
3099 size += 4;
3100 safe_buffer_increment(pStubMsg, 2);
3101 break;
3102 case RPC_FC_LONG:
3103 case RPC_FC_ULONG:
3104 case RPC_FC_ENUM32:
3105 size += 4;
3106 safe_buffer_increment(pStubMsg, 4);
3107 break;
3108 case RPC_FC_HYPER:
3109 size += 8;
3110 safe_buffer_increment(pStubMsg, 8);
3111 break;
3112 case RPC_FC_POINTER:
3114 unsigned char *saved_buffer;
3115 int pointer_buffer_mark_set = 0;
3116 if (*pPointer != RPC_FC_RP)
3117 ALIGN_POINTER(pStubMsg->Buffer, 4);
3118 saved_buffer = pStubMsg->Buffer;
3119 if (pStubMsg->PointerBufferMark)
3121 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3122 pStubMsg->PointerBufferMark = NULL;
3123 pointer_buffer_mark_set = 1;
3125 else if (*pPointer != RPC_FC_RP)
3126 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3128 if (!pStubMsg->IgnoreEmbeddedPointers)
3129 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3130 if (pointer_buffer_mark_set)
3132 STD_OVERFLOW_CHECK(pStubMsg);
3133 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3134 pStubMsg->Buffer = saved_buffer;
3135 if (*pPointer != RPC_FC_RP)
3136 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3138 pPointer += 4;
3139 size += 4;
3140 break;
3142 case RPC_FC_ALIGNM4:
3143 ALIGN_LENGTH(size, 4);
3144 ALIGN_POINTER(pStubMsg->Buffer, 4);
3145 break;
3146 case RPC_FC_ALIGNM8:
3147 ALIGN_LENGTH(size, 8);
3148 ALIGN_POINTER(pStubMsg->Buffer, 8);
3149 break;
3150 case RPC_FC_STRUCTPAD1:
3151 case RPC_FC_STRUCTPAD2:
3152 case RPC_FC_STRUCTPAD3:
3153 case RPC_FC_STRUCTPAD4:
3154 case RPC_FC_STRUCTPAD5:
3155 case RPC_FC_STRUCTPAD6:
3156 case RPC_FC_STRUCTPAD7:
3157 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3158 break;
3159 case RPC_FC_EMBEDDED_COMPLEX:
3160 size += pFormat[1];
3161 pFormat += 2;
3162 desc = pFormat + *(const SHORT*)pFormat;
3163 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3164 pFormat += 2;
3165 continue;
3166 case RPC_FC_PAD:
3167 break;
3168 default:
3169 FIXME("unhandled format 0x%02x\n", *pFormat);
3171 pFormat++;
3174 return size;
3177 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
3178 PFORMAT_STRING pFormat)
3180 PFORMAT_STRING desc;
3181 unsigned long size = 0;
3183 while (*pFormat != RPC_FC_END) {
3184 switch (*pFormat) {
3185 case RPC_FC_BYTE:
3186 case RPC_FC_CHAR:
3187 case RPC_FC_SMALL:
3188 case RPC_FC_USMALL:
3189 size += 1;
3190 break;
3191 case RPC_FC_WCHAR:
3192 case RPC_FC_SHORT:
3193 case RPC_FC_USHORT:
3194 size += 2;
3195 break;
3196 case RPC_FC_LONG:
3197 case RPC_FC_ULONG:
3198 case RPC_FC_ENUM16:
3199 case RPC_FC_ENUM32:
3200 size += 4;
3201 break;
3202 case RPC_FC_HYPER:
3203 size += 8;
3204 break;
3205 case RPC_FC_POINTER:
3206 size += sizeof(void *);
3207 break;
3208 case RPC_FC_ALIGNM4:
3209 ALIGN_LENGTH(size, 4);
3210 break;
3211 case RPC_FC_ALIGNM8:
3212 ALIGN_LENGTH(size, 8);
3213 break;
3214 case RPC_FC_STRUCTPAD1:
3215 case RPC_FC_STRUCTPAD2:
3216 case RPC_FC_STRUCTPAD3:
3217 case RPC_FC_STRUCTPAD4:
3218 case RPC_FC_STRUCTPAD5:
3219 case RPC_FC_STRUCTPAD6:
3220 case RPC_FC_STRUCTPAD7:
3221 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3222 break;
3223 case RPC_FC_EMBEDDED_COMPLEX:
3224 size += pFormat[1];
3225 pFormat += 2;
3226 desc = pFormat + *(const SHORT*)pFormat;
3227 size += EmbeddedComplexSize(pStubMsg, desc);
3228 pFormat += 2;
3229 continue;
3230 case RPC_FC_PAD:
3231 break;
3232 default:
3233 FIXME("unhandled format 0x%02x\n", *pFormat);
3235 pFormat++;
3238 return size;
3241 /***********************************************************************
3242 * NdrComplexStructMarshall [RPCRT4.@]
3244 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3245 unsigned char *pMemory,
3246 PFORMAT_STRING pFormat)
3248 PFORMAT_STRING conf_array = NULL;
3249 PFORMAT_STRING pointer_desc = NULL;
3250 unsigned char *OldMemory = pStubMsg->Memory;
3251 int pointer_buffer_mark_set = 0;
3252 ULONG count = 0;
3253 ULONG max_count = 0;
3254 ULONG offset = 0;
3256 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3258 if (!pStubMsg->PointerBufferMark)
3260 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3261 /* save buffer length */
3262 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3264 /* get the buffer pointer after complex array data, but before
3265 * pointer data */
3266 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3267 pStubMsg->IgnoreEmbeddedPointers = 1;
3268 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3269 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3271 /* save it for use by embedded pointer code later */
3272 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3273 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
3274 pointer_buffer_mark_set = 1;
3276 /* restore the original buffer length */
3277 pStubMsg->BufferLength = saved_buffer_length;
3280 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3282 pFormat += 4;
3283 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3284 pFormat += 2;
3285 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3286 pFormat += 2;
3288 pStubMsg->Memory = pMemory;
3290 if (conf_array)
3292 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3293 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3294 pMemory + struct_size, conf_array);
3295 /* these could be changed in ComplexMarshall so save them for later */
3296 max_count = pStubMsg->MaxCount;
3297 count = pStubMsg->ActualCount;
3298 offset = pStubMsg->Offset;
3301 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3303 if (conf_array)
3305 pStubMsg->MaxCount = max_count;
3306 pStubMsg->ActualCount = count;
3307 pStubMsg->Offset = offset;
3308 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3309 conf_array, TRUE /* fHasPointers */);
3312 pStubMsg->Memory = OldMemory;
3314 if (pointer_buffer_mark_set)
3316 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3317 pStubMsg->PointerBufferMark = NULL;
3320 STD_OVERFLOW_CHECK(pStubMsg);
3322 return NULL;
3325 /***********************************************************************
3326 * NdrComplexStructUnmarshall [RPCRT4.@]
3328 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3329 unsigned char **ppMemory,
3330 PFORMAT_STRING pFormat,
3331 unsigned char fMustAlloc)
3333 unsigned size = *(const WORD*)(pFormat+2);
3334 PFORMAT_STRING conf_array = NULL;
3335 PFORMAT_STRING pointer_desc = NULL;
3336 unsigned char *pMemory;
3337 int pointer_buffer_mark_set = 0;
3338 ULONG count = 0;
3339 ULONG max_count = 0;
3340 ULONG offset = 0;
3341 ULONG array_size = 0;
3343 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3345 if (!pStubMsg->PointerBufferMark)
3347 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3348 /* save buffer pointer */
3349 unsigned char *saved_buffer = pStubMsg->Buffer;
3351 /* get the buffer pointer after complex array data, but before
3352 * pointer data */
3353 pStubMsg->IgnoreEmbeddedPointers = 1;
3354 NdrComplexStructMemorySize(pStubMsg, pFormat);
3355 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3357 /* save it for use by embedded pointer code later */
3358 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3359 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
3360 pointer_buffer_mark_set = 1;
3362 /* restore the original buffer */
3363 pStubMsg->Buffer = saved_buffer;
3366 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3368 pFormat += 4;
3369 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3370 pFormat += 2;
3371 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3372 pFormat += 2;
3374 if (conf_array)
3376 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3377 size += array_size;
3379 /* these could be changed in ComplexMarshall so save them for later */
3380 max_count = pStubMsg->MaxCount;
3381 count = pStubMsg->ActualCount;
3382 offset = pStubMsg->Offset;
3385 if (fMustAlloc || !*ppMemory)
3386 *ppMemory = NdrAllocate(pStubMsg, size);
3388 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3390 if (conf_array)
3392 pStubMsg->MaxCount = max_count;
3393 pStubMsg->ActualCount = count;
3394 pStubMsg->Offset = offset;
3395 if (fMustAlloc)
3396 memset(pMemory, 0, array_size);
3397 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3398 conf_array, FALSE,
3399 FALSE /* fUseBufferMemoryServer */,
3400 TRUE /* fUnmarshall */);
3403 if (pointer_buffer_mark_set)
3405 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3406 pStubMsg->PointerBufferMark = NULL;
3409 return NULL;
3412 /***********************************************************************
3413 * NdrComplexStructBufferSize [RPCRT4.@]
3415 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3416 unsigned char *pMemory,
3417 PFORMAT_STRING pFormat)
3419 PFORMAT_STRING conf_array = NULL;
3420 PFORMAT_STRING pointer_desc = NULL;
3421 unsigned char *OldMemory = pStubMsg->Memory;
3422 int pointer_length_set = 0;
3423 ULONG count = 0;
3424 ULONG max_count = 0;
3425 ULONG offset = 0;
3427 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3429 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3431 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3433 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3434 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3436 /* get the buffer length after complex struct data, but before
3437 * pointer data */
3438 pStubMsg->IgnoreEmbeddedPointers = 1;
3439 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3440 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3442 /* save it for use by embedded pointer code later */
3443 pStubMsg->PointerLength = pStubMsg->BufferLength;
3444 pointer_length_set = 1;
3445 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
3447 /* restore the original buffer length */
3448 pStubMsg->BufferLength = saved_buffer_length;
3451 pFormat += 4;
3452 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3453 pFormat += 2;
3454 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3455 pFormat += 2;
3457 pStubMsg->Memory = pMemory;
3459 if (conf_array)
3461 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3462 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3463 conf_array);
3465 /* these could be changed in ComplexMarshall so save them for later */
3466 max_count = pStubMsg->MaxCount;
3467 count = pStubMsg->ActualCount;
3468 offset = pStubMsg->Offset;
3471 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3473 if (conf_array)
3475 pStubMsg->MaxCount = max_count;
3476 pStubMsg->ActualCount = count;
3477 pStubMsg->Offset = offset;
3478 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3479 TRUE /* fHasPointers */);
3482 pStubMsg->Memory = OldMemory;
3484 if(pointer_length_set)
3486 pStubMsg->BufferLength = pStubMsg->PointerLength;
3487 pStubMsg->PointerLength = 0;
3492 /***********************************************************************
3493 * NdrComplexStructMemorySize [RPCRT4.@]
3495 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3496 PFORMAT_STRING pFormat)
3498 unsigned size = *(const WORD*)(pFormat+2);
3499 PFORMAT_STRING conf_array = NULL;
3500 PFORMAT_STRING pointer_desc = NULL;
3501 ULONG count = 0;
3502 ULONG max_count = 0;
3503 ULONG offset = 0;
3505 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3507 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3509 pFormat += 4;
3510 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3511 pFormat += 2;
3512 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3513 pFormat += 2;
3515 if (conf_array)
3517 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3519 /* these could be changed in ComplexStructMemorySize so save them for
3520 * later */
3521 max_count = pStubMsg->MaxCount;
3522 count = pStubMsg->ActualCount;
3523 offset = pStubMsg->Offset;
3526 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3528 if (conf_array)
3530 pStubMsg->MaxCount = max_count;
3531 pStubMsg->ActualCount = count;
3532 pStubMsg->Offset = offset;
3533 array_memory_size(conf_array[0], pStubMsg, conf_array,
3534 TRUE /* fHasPointers */);
3537 return size;
3540 /***********************************************************************
3541 * NdrComplexStructFree [RPCRT4.@]
3543 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3544 unsigned char *pMemory,
3545 PFORMAT_STRING pFormat)
3547 PFORMAT_STRING conf_array = NULL;
3548 PFORMAT_STRING pointer_desc = NULL;
3549 unsigned char *OldMemory = pStubMsg->Memory;
3551 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3553 pFormat += 4;
3554 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3555 pFormat += 2;
3556 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3557 pFormat += 2;
3559 pStubMsg->Memory = pMemory;
3561 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3563 if (conf_array)
3564 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3565 TRUE /* fHasPointers */);
3567 pStubMsg->Memory = OldMemory;
3570 /***********************************************************************
3571 * NdrConformantArrayMarshall [RPCRT4.@]
3573 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3574 unsigned char *pMemory,
3575 PFORMAT_STRING pFormat)
3577 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3578 if (pFormat[0] != RPC_FC_CARRAY)
3580 ERR("invalid format = 0x%x\n", pFormat[0]);
3581 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3584 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3585 pFormat);
3586 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3587 TRUE /* fHasPointers */);
3589 return NULL;
3592 /***********************************************************************
3593 * NdrConformantArrayUnmarshall [RPCRT4.@]
3595 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3596 unsigned char **ppMemory,
3597 PFORMAT_STRING pFormat,
3598 unsigned char fMustAlloc)
3600 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3601 if (pFormat[0] != RPC_FC_CARRAY)
3603 ERR("invalid format = 0x%x\n", pFormat[0]);
3604 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3607 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3608 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3609 fMustAlloc,
3610 TRUE /* fUseBufferMemoryServer */,
3611 TRUE /* fUnmarshall */);
3613 return NULL;
3616 /***********************************************************************
3617 * NdrConformantArrayBufferSize [RPCRT4.@]
3619 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3620 unsigned char *pMemory,
3621 PFORMAT_STRING pFormat)
3623 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3624 if (pFormat[0] != RPC_FC_CARRAY)
3626 ERR("invalid format = 0x%x\n", pFormat[0]);
3627 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3630 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3631 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3632 TRUE /* fHasPointers */);
3635 /***********************************************************************
3636 * NdrConformantArrayMemorySize [RPCRT4.@]
3638 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3639 PFORMAT_STRING pFormat)
3641 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3642 if (pFormat[0] != RPC_FC_CARRAY)
3644 ERR("invalid format = 0x%x\n", pFormat[0]);
3645 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3648 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3649 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3651 return pStubMsg->MemorySize;
3654 /***********************************************************************
3655 * NdrConformantArrayFree [RPCRT4.@]
3657 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3658 unsigned char *pMemory,
3659 PFORMAT_STRING pFormat)
3661 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3662 if (pFormat[0] != RPC_FC_CARRAY)
3664 ERR("invalid format = 0x%x\n", pFormat[0]);
3665 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3668 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3669 TRUE /* fHasPointers */);
3673 /***********************************************************************
3674 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3676 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3677 unsigned char* pMemory,
3678 PFORMAT_STRING pFormat )
3680 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3682 if (pFormat[0] != RPC_FC_CVARRAY)
3684 ERR("invalid format type %x\n", pFormat[0]);
3685 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3686 return NULL;
3689 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3690 pFormat);
3691 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3692 pFormat, TRUE /* fHasPointers */);
3694 return NULL;
3698 /***********************************************************************
3699 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3701 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3702 unsigned char** ppMemory,
3703 PFORMAT_STRING pFormat,
3704 unsigned char fMustAlloc )
3706 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3708 if (pFormat[0] != RPC_FC_CVARRAY)
3710 ERR("invalid format type %x\n", pFormat[0]);
3711 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3712 return NULL;
3715 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3716 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3717 pFormat, fMustAlloc,
3718 TRUE /* fUseBufferMemoryServer */,
3719 TRUE /* fUnmarshall */);
3721 return NULL;
3725 /***********************************************************************
3726 * NdrConformantVaryingArrayFree [RPCRT4.@]
3728 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3729 unsigned char* pMemory,
3730 PFORMAT_STRING pFormat )
3732 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3734 if (pFormat[0] != RPC_FC_CVARRAY)
3736 ERR("invalid format type %x\n", pFormat[0]);
3737 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3738 return;
3741 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3742 TRUE /* fHasPointers */);
3746 /***********************************************************************
3747 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3749 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3750 unsigned char* pMemory, PFORMAT_STRING pFormat )
3752 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3754 if (pFormat[0] != RPC_FC_CVARRAY)
3756 ERR("invalid format type %x\n", pFormat[0]);
3757 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3758 return;
3761 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3762 pFormat);
3763 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3764 TRUE /* fHasPointers */);
3768 /***********************************************************************
3769 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3771 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3772 PFORMAT_STRING pFormat )
3774 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3776 if (pFormat[0] != RPC_FC_CVARRAY)
3778 ERR("invalid format type %x\n", pFormat[0]);
3779 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3780 return pStubMsg->MemorySize;
3783 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3784 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3785 TRUE /* fHasPointers */);
3787 return pStubMsg->MemorySize;
3791 /***********************************************************************
3792 * NdrComplexArrayMarshall [RPCRT4.@]
3794 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3795 unsigned char *pMemory,
3796 PFORMAT_STRING pFormat)
3798 ULONG i, count, def;
3799 BOOL variance_present;
3800 unsigned char alignment;
3801 int pointer_buffer_mark_set = 0;
3803 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3805 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3807 ERR("invalid format type %x\n", pFormat[0]);
3808 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3809 return NULL;
3812 alignment = pFormat[1] + 1;
3814 if (!pStubMsg->PointerBufferMark)
3816 /* save buffer fields that may be changed by buffer sizer functions
3817 * and that may be needed later on */
3818 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3819 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3820 unsigned long saved_max_count = pStubMsg->MaxCount;
3821 unsigned long saved_offset = pStubMsg->Offset;
3822 unsigned long saved_actual_count = pStubMsg->ActualCount;
3824 /* get the buffer pointer after complex array data, but before
3825 * pointer data */
3826 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3827 pStubMsg->IgnoreEmbeddedPointers = 1;
3828 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3829 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3831 /* save it for use by embedded pointer code later */
3832 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3833 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3834 pointer_buffer_mark_set = 1;
3836 /* restore fields */
3837 pStubMsg->ActualCount = saved_actual_count;
3838 pStubMsg->Offset = saved_offset;
3839 pStubMsg->MaxCount = saved_max_count;
3840 pStubMsg->BufferLength = saved_buffer_length;
3843 def = *(const WORD*)&pFormat[2];
3844 pFormat += 4;
3846 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3847 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3849 variance_present = IsConformanceOrVariancePresent(pFormat);
3850 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3851 TRACE("variance = %d\n", pStubMsg->ActualCount);
3853 WriteConformance(pStubMsg);
3854 if (variance_present)
3855 WriteVariance(pStubMsg);
3857 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3859 count = pStubMsg->ActualCount;
3860 for (i = 0; i < count; i++)
3861 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3863 STD_OVERFLOW_CHECK(pStubMsg);
3865 if (pointer_buffer_mark_set)
3867 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3868 pStubMsg->PointerBufferMark = NULL;
3871 return NULL;
3874 /***********************************************************************
3875 * NdrComplexArrayUnmarshall [RPCRT4.@]
3877 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3878 unsigned char **ppMemory,
3879 PFORMAT_STRING pFormat,
3880 unsigned char fMustAlloc)
3882 ULONG i, count, size;
3883 unsigned char alignment;
3884 unsigned char *pMemory;
3885 unsigned char *saved_buffer;
3886 int pointer_buffer_mark_set = 0;
3887 int saved_ignore_embedded;
3889 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3891 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3893 ERR("invalid format type %x\n", pFormat[0]);
3894 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3895 return NULL;
3898 alignment = pFormat[1] + 1;
3900 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3901 /* save buffer pointer */
3902 saved_buffer = pStubMsg->Buffer;
3903 /* get the buffer pointer after complex array data, but before
3904 * pointer data */
3905 pStubMsg->IgnoreEmbeddedPointers = 1;
3906 pStubMsg->MemorySize = 0;
3907 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3908 size = pStubMsg->MemorySize;
3909 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3911 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3912 if (!pStubMsg->PointerBufferMark)
3914 /* save it for use by embedded pointer code later */
3915 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3916 pointer_buffer_mark_set = 1;
3918 /* restore the original buffer */
3919 pStubMsg->Buffer = saved_buffer;
3921 pFormat += 4;
3923 pFormat = ReadConformance(pStubMsg, pFormat);
3924 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3926 if (fMustAlloc || !*ppMemory)
3927 *ppMemory = NdrAllocate(pStubMsg, size);
3929 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3931 pMemory = *ppMemory;
3932 count = pStubMsg->ActualCount;
3933 for (i = 0; i < count; i++)
3934 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3936 if (pointer_buffer_mark_set)
3938 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3939 pStubMsg->PointerBufferMark = NULL;
3942 return NULL;
3945 /***********************************************************************
3946 * NdrComplexArrayBufferSize [RPCRT4.@]
3948 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3949 unsigned char *pMemory,
3950 PFORMAT_STRING pFormat)
3952 ULONG i, count, def;
3953 unsigned char alignment;
3954 BOOL variance_present;
3955 int pointer_length_set = 0;
3957 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3959 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3961 ERR("invalid format type %x\n", pFormat[0]);
3962 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3963 return;
3966 alignment = pFormat[1] + 1;
3968 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3970 /* save buffer fields that may be changed by buffer sizer functions
3971 * and that may be needed later on */
3972 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3973 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3974 unsigned long saved_max_count = pStubMsg->MaxCount;
3975 unsigned long saved_offset = pStubMsg->Offset;
3976 unsigned long saved_actual_count = pStubMsg->ActualCount;
3978 /* get the buffer pointer after complex array data, but before
3979 * pointer data */
3980 pStubMsg->IgnoreEmbeddedPointers = 1;
3981 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3982 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3984 /* save it for use by embedded pointer code later */
3985 pStubMsg->PointerLength = pStubMsg->BufferLength;
3986 pointer_length_set = 1;
3988 /* restore fields */
3989 pStubMsg->ActualCount = saved_actual_count;
3990 pStubMsg->Offset = saved_offset;
3991 pStubMsg->MaxCount = saved_max_count;
3992 pStubMsg->BufferLength = saved_buffer_length;
3994 def = *(const WORD*)&pFormat[2];
3995 pFormat += 4;
3997 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3998 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3999 SizeConformance(pStubMsg);
4001 variance_present = IsConformanceOrVariancePresent(pFormat);
4002 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4003 TRACE("variance = %d\n", pStubMsg->ActualCount);
4005 if (variance_present)
4006 SizeVariance(pStubMsg);
4008 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4010 count = pStubMsg->ActualCount;
4011 for (i = 0; i < count; i++)
4012 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4014 if(pointer_length_set)
4016 pStubMsg->BufferLength = pStubMsg->PointerLength;
4017 pStubMsg->PointerLength = 0;
4021 /***********************************************************************
4022 * NdrComplexArrayMemorySize [RPCRT4.@]
4024 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4025 PFORMAT_STRING pFormat)
4027 ULONG i, count, esize, SavedMemorySize, MemorySize;
4028 unsigned char alignment;
4030 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4032 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4034 ERR("invalid format type %x\n", pFormat[0]);
4035 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4036 return 0;
4039 alignment = pFormat[1] + 1;
4041 pFormat += 4;
4043 pFormat = ReadConformance(pStubMsg, pFormat);
4044 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4046 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4048 SavedMemorySize = pStubMsg->MemorySize;
4050 esize = ComplexStructSize(pStubMsg, pFormat);
4052 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4054 count = pStubMsg->ActualCount;
4055 for (i = 0; i < count; i++)
4056 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4058 pStubMsg->MemorySize = SavedMemorySize;
4060 pStubMsg->MemorySize += MemorySize;
4061 return MemorySize;
4064 /***********************************************************************
4065 * NdrComplexArrayFree [RPCRT4.@]
4067 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4068 unsigned char *pMemory,
4069 PFORMAT_STRING pFormat)
4071 ULONG i, count, def;
4073 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4075 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4077 ERR("invalid format type %x\n", pFormat[0]);
4078 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4079 return;
4082 def = *(const WORD*)&pFormat[2];
4083 pFormat += 4;
4085 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4086 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4088 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4089 TRACE("variance = %d\n", pStubMsg->ActualCount);
4091 count = pStubMsg->ActualCount;
4092 for (i = 0; i < count; i++)
4093 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4096 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4097 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4098 USER_MARSHAL_CB *umcb)
4100 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4101 pStubMsg->RpcMsg->DataRepresentation);
4102 umcb->pStubMsg = pStubMsg;
4103 umcb->pReserve = NULL;
4104 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4105 umcb->CBType = cbtype;
4106 umcb->pFormat = pFormat;
4107 umcb->pTypeFormat = NULL /* FIXME */;
4110 #define USER_MARSHAL_PTR_PREFIX \
4111 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4112 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4114 /***********************************************************************
4115 * NdrUserMarshalMarshall [RPCRT4.@]
4117 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4118 unsigned char *pMemory,
4119 PFORMAT_STRING pFormat)
4121 unsigned flags = pFormat[1];
4122 unsigned index = *(const WORD*)&pFormat[2];
4123 unsigned char *saved_buffer = NULL;
4124 USER_MARSHAL_CB umcb;
4126 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4127 TRACE("index=%d\n", index);
4129 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4131 if (flags & USER_MARSHAL_POINTER)
4133 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4134 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4135 pStubMsg->Buffer += 4;
4136 if (pStubMsg->PointerBufferMark)
4138 saved_buffer = pStubMsg->Buffer;
4139 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4140 pStubMsg->PointerBufferMark = NULL;
4142 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4144 else
4145 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4147 pStubMsg->Buffer =
4148 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4149 &umcb.Flags, pStubMsg->Buffer, pMemory);
4151 if (saved_buffer)
4153 STD_OVERFLOW_CHECK(pStubMsg);
4154 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4155 pStubMsg->Buffer = saved_buffer;
4158 STD_OVERFLOW_CHECK(pStubMsg);
4160 return NULL;
4163 /***********************************************************************
4164 * NdrUserMarshalUnmarshall [RPCRT4.@]
4166 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4167 unsigned char **ppMemory,
4168 PFORMAT_STRING pFormat,
4169 unsigned char fMustAlloc)
4171 unsigned flags = pFormat[1];
4172 unsigned index = *(const WORD*)&pFormat[2];
4173 DWORD memsize = *(const WORD*)&pFormat[4];
4174 unsigned char *saved_buffer = NULL;
4175 USER_MARSHAL_CB umcb;
4177 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4178 TRACE("index=%d\n", index);
4180 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4182 if (flags & USER_MARSHAL_POINTER)
4184 ALIGN_POINTER(pStubMsg->Buffer, 4);
4185 /* skip pointer prefix */
4186 pStubMsg->Buffer += 4;
4187 if (pStubMsg->PointerBufferMark)
4189 saved_buffer = pStubMsg->Buffer;
4190 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4191 pStubMsg->PointerBufferMark = NULL;
4193 ALIGN_POINTER(pStubMsg->Buffer, 8);
4195 else
4196 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4198 if (fMustAlloc || !*ppMemory)
4199 *ppMemory = NdrAllocate(pStubMsg, memsize);
4201 pStubMsg->Buffer =
4202 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4203 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4205 if (saved_buffer)
4207 STD_OVERFLOW_CHECK(pStubMsg);
4208 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4209 pStubMsg->Buffer = saved_buffer;
4212 return NULL;
4215 /***********************************************************************
4216 * NdrUserMarshalBufferSize [RPCRT4.@]
4218 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4219 unsigned char *pMemory,
4220 PFORMAT_STRING pFormat)
4222 unsigned flags = pFormat[1];
4223 unsigned index = *(const WORD*)&pFormat[2];
4224 DWORD bufsize = *(const WORD*)&pFormat[6];
4225 USER_MARSHAL_CB umcb;
4226 unsigned long saved_buffer_length = 0;
4228 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4229 TRACE("index=%d\n", index);
4231 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4233 if (flags & USER_MARSHAL_POINTER)
4235 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4236 /* skip pointer prefix */
4237 safe_buffer_length_increment(pStubMsg, 4);
4238 if (pStubMsg->IgnoreEmbeddedPointers)
4239 return;
4240 if (pStubMsg->PointerLength)
4242 saved_buffer_length = pStubMsg->BufferLength;
4243 pStubMsg->BufferLength = pStubMsg->PointerLength;
4244 pStubMsg->PointerLength = 0;
4246 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4248 else
4249 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4251 if (bufsize) {
4252 TRACE("size=%d\n", bufsize);
4253 safe_buffer_length_increment(pStubMsg, bufsize);
4255 else
4256 pStubMsg->BufferLength =
4257 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4258 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4260 if (saved_buffer_length)
4262 pStubMsg->PointerLength = pStubMsg->BufferLength;
4263 pStubMsg->BufferLength = saved_buffer_length;
4268 /***********************************************************************
4269 * NdrUserMarshalMemorySize [RPCRT4.@]
4271 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4272 PFORMAT_STRING pFormat)
4274 unsigned flags = pFormat[1];
4275 unsigned index = *(const WORD*)&pFormat[2];
4276 DWORD memsize = *(const WORD*)&pFormat[4];
4277 DWORD bufsize = *(const WORD*)&pFormat[6];
4279 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4280 TRACE("index=%d\n", index);
4282 pStubMsg->MemorySize += memsize;
4284 if (flags & USER_MARSHAL_POINTER)
4286 ALIGN_POINTER(pStubMsg->Buffer, 4);
4287 /* skip pointer prefix */
4288 pStubMsg->Buffer += 4;
4289 if (pStubMsg->IgnoreEmbeddedPointers)
4290 return pStubMsg->MemorySize;
4291 ALIGN_POINTER(pStubMsg->Buffer, 8);
4293 else
4294 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4296 if (!bufsize)
4297 FIXME("not implemented for varying buffer size\n");
4299 pStubMsg->Buffer += bufsize;
4301 return pStubMsg->MemorySize;
4304 /***********************************************************************
4305 * NdrUserMarshalFree [RPCRT4.@]
4307 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4308 unsigned char *pMemory,
4309 PFORMAT_STRING pFormat)
4311 /* unsigned flags = pFormat[1]; */
4312 unsigned index = *(const WORD*)&pFormat[2];
4313 USER_MARSHAL_CB umcb;
4315 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4316 TRACE("index=%d\n", index);
4318 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4320 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4321 &umcb.Flags, pMemory);
4324 /***********************************************************************
4325 * NdrClearOutParameters [RPCRT4.@]
4327 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4328 PFORMAT_STRING pFormat,
4329 void *ArgAddr)
4331 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4334 /***********************************************************************
4335 * NdrConvert [RPCRT4.@]
4337 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4339 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4340 /* FIXME: since this stub doesn't do any converting, the proper behavior
4341 is to raise an exception */
4344 /***********************************************************************
4345 * NdrConvert2 [RPCRT4.@]
4347 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4349 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4350 pStubMsg, pFormat, NumberParams);
4351 /* FIXME: since this stub doesn't do any converting, the proper behavior
4352 is to raise an exception */
4355 #include "pshpack1.h"
4356 typedef struct _NDR_CSTRUCT_FORMAT
4358 unsigned char type;
4359 unsigned char alignment;
4360 unsigned short memory_size;
4361 short offset_to_array_description;
4362 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4363 #include "poppack.h"
4365 /***********************************************************************
4366 * NdrConformantStructMarshall [RPCRT4.@]
4368 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4369 unsigned char *pMemory,
4370 PFORMAT_STRING pFormat)
4372 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4373 PFORMAT_STRING pCArrayFormat;
4374 ULONG esize, bufsize;
4376 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4378 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4379 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4381 ERR("invalid format type %x\n", pCStructFormat->type);
4382 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4383 return NULL;
4386 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4387 pCStructFormat->offset_to_array_description;
4388 if (*pCArrayFormat != RPC_FC_CARRAY)
4390 ERR("invalid array format type %x\n", pCStructFormat->type);
4391 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4392 return NULL;
4394 esize = *(const WORD*)(pCArrayFormat+2);
4396 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4397 pCArrayFormat + 4, 0);
4399 WriteConformance(pStubMsg);
4401 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4403 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4405 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4406 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4408 ERR("integer overflow of memory_size %u with bufsize %u\n",
4409 pCStructFormat->memory_size, bufsize);
4410 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4412 /* copy constant sized part of struct */
4413 pStubMsg->BufferMark = pStubMsg->Buffer;
4414 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4416 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4417 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4419 return NULL;
4422 /***********************************************************************
4423 * NdrConformantStructUnmarshall [RPCRT4.@]
4425 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4426 unsigned char **ppMemory,
4427 PFORMAT_STRING pFormat,
4428 unsigned char fMustAlloc)
4430 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4431 PFORMAT_STRING pCArrayFormat;
4432 ULONG esize, bufsize;
4433 unsigned char *saved_buffer;
4435 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4437 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4438 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4440 ERR("invalid format type %x\n", pCStructFormat->type);
4441 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4442 return NULL;
4444 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4445 pCStructFormat->offset_to_array_description;
4446 if (*pCArrayFormat != RPC_FC_CARRAY)
4448 ERR("invalid array format type %x\n", pCStructFormat->type);
4449 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4450 return NULL;
4452 esize = *(const WORD*)(pCArrayFormat+2);
4454 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4456 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4458 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4460 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4461 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4463 ERR("integer overflow of memory_size %u with bufsize %u\n",
4464 pCStructFormat->memory_size, bufsize);
4465 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4468 if (fMustAlloc)
4470 SIZE_T size = pCStructFormat->memory_size + bufsize;
4471 *ppMemory = NdrAllocate(pStubMsg, size);
4473 else
4475 if (!pStubMsg->IsClient && !*ppMemory)
4476 /* for servers, we just point straight into the RPC buffer */
4477 *ppMemory = pStubMsg->Buffer;
4480 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4481 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4482 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4483 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4485 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4486 if (*ppMemory != saved_buffer)
4487 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4489 return NULL;
4492 /***********************************************************************
4493 * NdrConformantStructBufferSize [RPCRT4.@]
4495 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4496 unsigned char *pMemory,
4497 PFORMAT_STRING pFormat)
4499 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4500 PFORMAT_STRING pCArrayFormat;
4501 ULONG esize;
4503 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4505 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4506 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4508 ERR("invalid format type %x\n", pCStructFormat->type);
4509 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4510 return;
4512 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4513 pCStructFormat->offset_to_array_description;
4514 if (*pCArrayFormat != RPC_FC_CARRAY)
4516 ERR("invalid array format type %x\n", pCStructFormat->type);
4517 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4518 return;
4520 esize = *(const WORD*)(pCArrayFormat+2);
4522 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4523 SizeConformance(pStubMsg);
4525 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4527 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4529 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4530 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4532 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4533 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4536 /***********************************************************************
4537 * NdrConformantStructMemorySize [RPCRT4.@]
4539 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4540 PFORMAT_STRING pFormat)
4542 FIXME("stub\n");
4543 return 0;
4546 /***********************************************************************
4547 * NdrConformantStructFree [RPCRT4.@]
4549 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4550 unsigned char *pMemory,
4551 PFORMAT_STRING pFormat)
4553 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4554 PFORMAT_STRING pCArrayFormat;
4556 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4558 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4559 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4561 ERR("invalid format type %x\n", pCStructFormat->type);
4562 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4563 return;
4566 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4567 pCStructFormat->offset_to_array_description;
4568 if (*pCArrayFormat != RPC_FC_CARRAY)
4570 ERR("invalid array format type %x\n", pCStructFormat->type);
4571 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4572 return;
4575 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4576 pCArrayFormat + 4, 0);
4578 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4580 /* copy constant sized part of struct */
4581 pStubMsg->BufferMark = pStubMsg->Buffer;
4583 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4584 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4587 /***********************************************************************
4588 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4590 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4591 unsigned char *pMemory,
4592 PFORMAT_STRING pFormat)
4594 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4595 PFORMAT_STRING pCVArrayFormat;
4597 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4599 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4600 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4602 ERR("invalid format type %x\n", pCVStructFormat->type);
4603 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4604 return NULL;
4607 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4608 pCVStructFormat->offset_to_array_description;
4610 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4611 pMemory + pCVStructFormat->memory_size,
4612 pCVArrayFormat);
4614 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4616 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4618 /* write constant sized part */
4619 pStubMsg->BufferMark = pStubMsg->Buffer;
4620 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4622 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4623 pMemory + pCVStructFormat->memory_size,
4624 pCVArrayFormat, FALSE /* fHasPointers */);
4626 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4628 return NULL;
4631 /***********************************************************************
4632 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4634 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4635 unsigned char **ppMemory,
4636 PFORMAT_STRING pFormat,
4637 unsigned char fMustAlloc)
4639 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4640 PFORMAT_STRING pCVArrayFormat;
4641 ULONG memsize, bufsize;
4642 unsigned char *saved_buffer, *saved_array_buffer;
4643 ULONG offset;
4644 unsigned char *array_memory;
4646 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4648 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4649 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4651 ERR("invalid format type %x\n", pCVStructFormat->type);
4652 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4653 return NULL;
4656 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4657 pCVStructFormat->offset_to_array_description;
4659 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4660 pCVArrayFormat);
4662 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4664 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4666 /* work out how much memory to allocate if we need to do so */
4667 if (!*ppMemory || fMustAlloc)
4669 SIZE_T size = pCVStructFormat->memory_size + memsize;
4670 *ppMemory = NdrAllocate(pStubMsg, size);
4673 /* mark the start of the constant data */
4674 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4675 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4677 array_memory = *ppMemory + pCVStructFormat->memory_size;
4678 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4679 &array_memory, pCVArrayFormat,
4680 FALSE /* fMustAlloc */,
4681 FALSE /* fUseServerBufferMemory */,
4682 FALSE /* fUnmarshall */);
4684 /* save offset in case unmarshalling pointers changes it */
4685 offset = pStubMsg->Offset;
4687 /* mark the start of the array data */
4688 saved_array_buffer = pStubMsg->Buffer;
4689 safe_buffer_increment(pStubMsg, bufsize);
4691 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4693 /* copy the constant data */
4694 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4695 /* copy the array data */
4696 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4697 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4698 saved_array_buffer, bufsize);
4700 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4701 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4702 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4703 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4705 return NULL;
4708 /***********************************************************************
4709 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4711 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4712 unsigned char *pMemory,
4713 PFORMAT_STRING pFormat)
4715 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4716 PFORMAT_STRING pCVArrayFormat;
4718 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4720 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4721 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4723 ERR("invalid format type %x\n", pCVStructFormat->type);
4724 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4725 return;
4728 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4729 pCVStructFormat->offset_to_array_description;
4730 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4731 pMemory + pCVStructFormat->memory_size,
4732 pCVArrayFormat);
4734 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4736 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4738 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4740 array_buffer_size(*pCVArrayFormat, pStubMsg,
4741 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4742 FALSE /* fHasPointers */);
4744 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4747 /***********************************************************************
4748 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4750 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4751 PFORMAT_STRING pFormat)
4753 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4754 PFORMAT_STRING pCVArrayFormat;
4756 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4758 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4759 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4761 ERR("invalid format type %x\n", pCVStructFormat->type);
4762 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4763 return 0;
4766 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4767 pCVStructFormat->offset_to_array_description;
4768 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4770 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4772 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4774 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4775 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4776 FALSE /* fHasPointers */);
4778 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4780 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4782 return pStubMsg->MemorySize;
4785 /***********************************************************************
4786 * NdrConformantVaryingStructFree [RPCRT4.@]
4788 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4789 unsigned char *pMemory,
4790 PFORMAT_STRING pFormat)
4792 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4793 PFORMAT_STRING pCVArrayFormat;
4795 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4797 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4798 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4800 ERR("invalid format type %x\n", pCVStructFormat->type);
4801 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4802 return;
4805 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4806 pCVStructFormat->offset_to_array_description;
4807 array_free(*pCVArrayFormat, pStubMsg,
4808 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4809 FALSE /* fHasPointers */);
4811 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4813 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4816 #include "pshpack1.h"
4817 typedef struct
4819 unsigned char type;
4820 unsigned char alignment;
4821 unsigned short total_size;
4822 } NDR_SMFARRAY_FORMAT;
4824 typedef struct
4826 unsigned char type;
4827 unsigned char alignment;
4828 unsigned long total_size;
4829 } NDR_LGFARRAY_FORMAT;
4830 #include "poppack.h"
4832 /***********************************************************************
4833 * NdrFixedArrayMarshall [RPCRT4.@]
4835 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4836 unsigned char *pMemory,
4837 PFORMAT_STRING pFormat)
4839 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4840 unsigned long total_size;
4842 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4844 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4845 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4847 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4848 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4849 return NULL;
4852 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4854 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4856 total_size = pSmFArrayFormat->total_size;
4857 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4859 else
4861 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4862 total_size = pLgFArrayFormat->total_size;
4863 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4866 pStubMsg->BufferMark = pStubMsg->Buffer;
4867 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4869 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4871 return NULL;
4874 /***********************************************************************
4875 * NdrFixedArrayUnmarshall [RPCRT4.@]
4877 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4878 unsigned char **ppMemory,
4879 PFORMAT_STRING pFormat,
4880 unsigned char fMustAlloc)
4882 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4883 unsigned long total_size;
4884 unsigned char *saved_buffer;
4886 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4888 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4889 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4891 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4892 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4893 return NULL;
4896 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4898 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4900 total_size = pSmFArrayFormat->total_size;
4901 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4903 else
4905 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4906 total_size = pLgFArrayFormat->total_size;
4907 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4910 if (fMustAlloc)
4911 *ppMemory = NdrAllocate(pStubMsg, total_size);
4912 else
4914 if (!pStubMsg->IsClient && !*ppMemory)
4915 /* for servers, we just point straight into the RPC buffer */
4916 *ppMemory = pStubMsg->Buffer;
4919 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4920 safe_buffer_increment(pStubMsg, total_size);
4921 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4923 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4924 if (*ppMemory != saved_buffer)
4925 memcpy(*ppMemory, saved_buffer, total_size);
4927 return NULL;
4930 /***********************************************************************
4931 * NdrFixedArrayBufferSize [RPCRT4.@]
4933 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4934 unsigned char *pMemory,
4935 PFORMAT_STRING pFormat)
4937 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4938 unsigned long total_size;
4940 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4942 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4943 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4945 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4946 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4947 return;
4950 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4952 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4954 total_size = pSmFArrayFormat->total_size;
4955 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4957 else
4959 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4960 total_size = pLgFArrayFormat->total_size;
4961 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4963 safe_buffer_length_increment(pStubMsg, total_size);
4965 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4968 /***********************************************************************
4969 * NdrFixedArrayMemorySize [RPCRT4.@]
4971 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4972 PFORMAT_STRING pFormat)
4974 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4975 ULONG total_size;
4977 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4979 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4980 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4982 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4983 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4984 return 0;
4987 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4989 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4991 total_size = pSmFArrayFormat->total_size;
4992 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4994 else
4996 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4997 total_size = pLgFArrayFormat->total_size;
4998 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5000 pStubMsg->BufferMark = pStubMsg->Buffer;
5001 safe_buffer_increment(pStubMsg, total_size);
5002 pStubMsg->MemorySize += total_size;
5004 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5006 return total_size;
5009 /***********************************************************************
5010 * NdrFixedArrayFree [RPCRT4.@]
5012 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5013 unsigned char *pMemory,
5014 PFORMAT_STRING pFormat)
5016 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5018 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5020 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5021 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5023 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5024 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5025 return;
5028 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5029 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5030 else
5032 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5033 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5036 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5039 /***********************************************************************
5040 * NdrVaryingArrayMarshall [RPCRT4.@]
5042 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5043 unsigned char *pMemory,
5044 PFORMAT_STRING pFormat)
5046 unsigned char alignment;
5047 DWORD elements, esize;
5048 ULONG bufsize;
5050 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5052 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5053 (pFormat[0] != RPC_FC_LGVARRAY))
5055 ERR("invalid format type %x\n", pFormat[0]);
5056 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5057 return NULL;
5060 alignment = pFormat[1] + 1;
5062 if (pFormat[0] == RPC_FC_SMVARRAY)
5064 pFormat += 2;
5065 pFormat += sizeof(WORD);
5066 elements = *(const WORD*)pFormat;
5067 pFormat += sizeof(WORD);
5069 else
5071 pFormat += 2;
5072 pFormat += sizeof(DWORD);
5073 elements = *(const DWORD*)pFormat;
5074 pFormat += sizeof(DWORD);
5077 esize = *(const WORD*)pFormat;
5078 pFormat += sizeof(WORD);
5080 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5081 if ((pStubMsg->ActualCount > elements) ||
5082 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5084 RpcRaiseException(RPC_S_INVALID_BOUND);
5085 return NULL;
5088 WriteVariance(pStubMsg);
5090 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5092 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5093 pStubMsg->BufferMark = pStubMsg->Buffer;
5094 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5096 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5098 return NULL;
5101 /***********************************************************************
5102 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5104 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5105 unsigned char **ppMemory,
5106 PFORMAT_STRING pFormat,
5107 unsigned char fMustAlloc)
5109 unsigned char alignment;
5110 DWORD size, elements, esize;
5111 ULONG bufsize;
5112 unsigned char *saved_buffer;
5113 ULONG offset;
5115 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5117 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5118 (pFormat[0] != RPC_FC_LGVARRAY))
5120 ERR("invalid format type %x\n", pFormat[0]);
5121 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5122 return NULL;
5125 alignment = pFormat[1] + 1;
5127 if (pFormat[0] == RPC_FC_SMVARRAY)
5129 pFormat += 2;
5130 size = *(const WORD*)pFormat;
5131 pFormat += sizeof(WORD);
5132 elements = *(const WORD*)pFormat;
5133 pFormat += sizeof(WORD);
5135 else
5137 pFormat += 2;
5138 size = *(const DWORD*)pFormat;
5139 pFormat += sizeof(DWORD);
5140 elements = *(const DWORD*)pFormat;
5141 pFormat += sizeof(DWORD);
5144 esize = *(const WORD*)pFormat;
5145 pFormat += sizeof(WORD);
5147 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5149 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5151 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5152 offset = pStubMsg->Offset;
5154 if (!*ppMemory || fMustAlloc)
5155 *ppMemory = NdrAllocate(pStubMsg, size);
5156 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5157 safe_buffer_increment(pStubMsg, bufsize);
5159 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5161 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5163 return NULL;
5166 /***********************************************************************
5167 * NdrVaryingArrayBufferSize [RPCRT4.@]
5169 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5170 unsigned char *pMemory,
5171 PFORMAT_STRING pFormat)
5173 unsigned char alignment;
5174 DWORD elements, esize;
5176 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5178 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5179 (pFormat[0] != RPC_FC_LGVARRAY))
5181 ERR("invalid format type %x\n", pFormat[0]);
5182 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5183 return;
5186 alignment = pFormat[1] + 1;
5188 if (pFormat[0] == RPC_FC_SMVARRAY)
5190 pFormat += 2;
5191 pFormat += sizeof(WORD);
5192 elements = *(const WORD*)pFormat;
5193 pFormat += sizeof(WORD);
5195 else
5197 pFormat += 2;
5198 pFormat += sizeof(DWORD);
5199 elements = *(const DWORD*)pFormat;
5200 pFormat += sizeof(DWORD);
5203 esize = *(const WORD*)pFormat;
5204 pFormat += sizeof(WORD);
5206 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5207 if ((pStubMsg->ActualCount > elements) ||
5208 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5210 RpcRaiseException(RPC_S_INVALID_BOUND);
5211 return;
5214 SizeVariance(pStubMsg);
5216 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5218 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5220 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5223 /***********************************************************************
5224 * NdrVaryingArrayMemorySize [RPCRT4.@]
5226 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5227 PFORMAT_STRING pFormat)
5229 unsigned char alignment;
5230 DWORD size, elements, esize;
5232 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5234 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5235 (pFormat[0] != RPC_FC_LGVARRAY))
5237 ERR("invalid format type %x\n", pFormat[0]);
5238 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5239 return 0;
5242 alignment = pFormat[1] + 1;
5244 if (pFormat[0] == RPC_FC_SMVARRAY)
5246 pFormat += 2;
5247 size = *(const WORD*)pFormat;
5248 pFormat += sizeof(WORD);
5249 elements = *(const WORD*)pFormat;
5250 pFormat += sizeof(WORD);
5252 else
5254 pFormat += 2;
5255 size = *(const DWORD*)pFormat;
5256 pFormat += sizeof(DWORD);
5257 elements = *(const DWORD*)pFormat;
5258 pFormat += sizeof(DWORD);
5261 esize = *(const WORD*)pFormat;
5262 pFormat += sizeof(WORD);
5264 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5266 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5268 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5269 pStubMsg->MemorySize += size;
5271 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5273 return pStubMsg->MemorySize;
5276 /***********************************************************************
5277 * NdrVaryingArrayFree [RPCRT4.@]
5279 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5280 unsigned char *pMemory,
5281 PFORMAT_STRING pFormat)
5283 DWORD elements;
5285 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5287 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5288 (pFormat[0] != RPC_FC_LGVARRAY))
5290 ERR("invalid format type %x\n", pFormat[0]);
5291 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5292 return;
5295 if (pFormat[0] == RPC_FC_SMVARRAY)
5297 pFormat += 2;
5298 pFormat += sizeof(WORD);
5299 elements = *(const WORD*)pFormat;
5300 pFormat += sizeof(WORD);
5302 else
5304 pFormat += 2;
5305 pFormat += sizeof(DWORD);
5306 elements = *(const DWORD*)pFormat;
5307 pFormat += sizeof(DWORD);
5310 pFormat += sizeof(WORD);
5312 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5313 if ((pStubMsg->ActualCount > elements) ||
5314 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5316 RpcRaiseException(RPC_S_INVALID_BOUND);
5317 return;
5320 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5323 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5325 switch (fc)
5327 case RPC_FC_BYTE:
5328 case RPC_FC_CHAR:
5329 case RPC_FC_SMALL:
5330 case RPC_FC_USMALL:
5331 return *pMemory;
5332 case RPC_FC_WCHAR:
5333 case RPC_FC_SHORT:
5334 case RPC_FC_USHORT:
5335 case RPC_FC_ENUM16:
5336 return *(const USHORT *)pMemory;
5337 case RPC_FC_LONG:
5338 case RPC_FC_ULONG:
5339 case RPC_FC_ENUM32:
5340 return *(const ULONG *)pMemory;
5341 default:
5342 FIXME("Unhandled base type: 0x%02x\n", fc);
5343 return 0;
5347 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5348 unsigned long discriminant,
5349 PFORMAT_STRING pFormat)
5351 unsigned short num_arms, arm, type;
5353 num_arms = *(const SHORT*)pFormat & 0x0fff;
5354 pFormat += 2;
5355 for(arm = 0; arm < num_arms; arm++)
5357 if(discriminant == *(const ULONG*)pFormat)
5359 pFormat += 4;
5360 break;
5362 pFormat += 6;
5365 type = *(const unsigned short*)pFormat;
5366 TRACE("type %04x\n", type);
5367 if(arm == num_arms) /* default arm extras */
5369 if(type == 0xffff)
5371 ERR("no arm for 0x%lx and no default case\n", discriminant);
5372 RpcRaiseException(RPC_S_INVALID_TAG);
5373 return NULL;
5375 if(type == 0)
5377 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5378 return NULL;
5381 return pFormat;
5384 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5386 unsigned short type;
5388 pFormat += 2;
5390 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5391 if(!pFormat)
5392 return NULL;
5394 type = *(const unsigned short*)pFormat;
5395 if((type & 0xff00) == 0x8000)
5397 unsigned char basetype = LOBYTE(type);
5398 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5400 else
5402 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5403 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5404 if (m)
5406 unsigned char *saved_buffer = NULL;
5407 int pointer_buffer_mark_set = 0;
5408 switch(*desc)
5410 case RPC_FC_RP:
5411 case RPC_FC_UP:
5412 case RPC_FC_OP:
5413 case RPC_FC_FP:
5414 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5415 saved_buffer = pStubMsg->Buffer;
5416 if (pStubMsg->PointerBufferMark)
5418 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5419 pStubMsg->PointerBufferMark = NULL;
5420 pointer_buffer_mark_set = 1;
5422 else
5423 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5425 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5426 if (pointer_buffer_mark_set)
5428 STD_OVERFLOW_CHECK(pStubMsg);
5429 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5430 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5432 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5433 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5434 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5436 pStubMsg->Buffer = saved_buffer + 4;
5438 break;
5439 default:
5440 m(pStubMsg, pMemory, desc);
5443 else FIXME("no marshaller for embedded type %02x\n", *desc);
5445 return NULL;
5448 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5449 unsigned char **ppMemory,
5450 ULONG discriminant,
5451 PFORMAT_STRING pFormat,
5452 unsigned char fMustAlloc)
5454 unsigned short type;
5456 pFormat += 2;
5458 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5459 if(!pFormat)
5460 return NULL;
5462 type = *(const unsigned short*)pFormat;
5463 if((type & 0xff00) == 0x8000)
5465 unsigned char basetype = LOBYTE(type);
5466 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5468 else
5470 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5471 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5472 if (m)
5474 unsigned char *saved_buffer = NULL;
5475 int pointer_buffer_mark_set = 0;
5476 switch(*desc)
5478 case RPC_FC_RP:
5479 case RPC_FC_UP:
5480 case RPC_FC_OP:
5481 case RPC_FC_FP:
5482 **(void***)ppMemory = NULL;
5483 ALIGN_POINTER(pStubMsg->Buffer, 4);
5484 saved_buffer = pStubMsg->Buffer;
5485 if (pStubMsg->PointerBufferMark)
5487 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5488 pStubMsg->PointerBufferMark = NULL;
5489 pointer_buffer_mark_set = 1;
5491 else
5492 pStubMsg->Buffer += 4; /* for pointer ID */
5494 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5496 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5497 saved_buffer, pStubMsg->BufferEnd);
5498 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5501 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5502 if (pointer_buffer_mark_set)
5504 STD_OVERFLOW_CHECK(pStubMsg);
5505 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5506 pStubMsg->Buffer = saved_buffer + 4;
5508 break;
5509 default:
5510 m(pStubMsg, ppMemory, desc, fMustAlloc);
5513 else FIXME("no marshaller for embedded type %02x\n", *desc);
5515 return NULL;
5518 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5519 unsigned char *pMemory,
5520 ULONG discriminant,
5521 PFORMAT_STRING pFormat)
5523 unsigned short type;
5525 pFormat += 2;
5527 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5528 if(!pFormat)
5529 return;
5531 type = *(const unsigned short*)pFormat;
5532 if((type & 0xff00) == 0x8000)
5534 unsigned char basetype = LOBYTE(type);
5535 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5537 else
5539 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5540 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5541 if (m)
5543 switch(*desc)
5545 case RPC_FC_RP:
5546 case RPC_FC_UP:
5547 case RPC_FC_OP:
5548 case RPC_FC_FP:
5549 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5550 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5551 if (!pStubMsg->IgnoreEmbeddedPointers)
5553 int saved_buffer_length = pStubMsg->BufferLength;
5554 pStubMsg->BufferLength = pStubMsg->PointerLength;
5555 pStubMsg->PointerLength = 0;
5556 if(!pStubMsg->BufferLength)
5557 ERR("BufferLength == 0??\n");
5558 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5559 pStubMsg->PointerLength = pStubMsg->BufferLength;
5560 pStubMsg->BufferLength = saved_buffer_length;
5562 break;
5563 default:
5564 m(pStubMsg, pMemory, desc);
5567 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5571 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5572 ULONG discriminant,
5573 PFORMAT_STRING pFormat)
5575 unsigned short type, size;
5577 size = *(const unsigned short*)pFormat;
5578 pStubMsg->Memory += size;
5579 pFormat += 2;
5581 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5582 if(!pFormat)
5583 return 0;
5585 type = *(const unsigned short*)pFormat;
5586 if((type & 0xff00) == 0x8000)
5588 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5590 else
5592 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5593 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5594 unsigned char *saved_buffer;
5595 if (m)
5597 switch(*desc)
5599 case RPC_FC_RP:
5600 case RPC_FC_UP:
5601 case RPC_FC_OP:
5602 case RPC_FC_FP:
5603 ALIGN_POINTER(pStubMsg->Buffer, 4);
5604 saved_buffer = pStubMsg->Buffer;
5605 safe_buffer_increment(pStubMsg, 4);
5606 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5607 pStubMsg->MemorySize += 4;
5608 if (!pStubMsg->IgnoreEmbeddedPointers)
5609 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5610 break;
5611 default:
5612 return m(pStubMsg, desc);
5615 else FIXME("no marshaller for embedded type %02x\n", *desc);
5618 TRACE("size %d\n", size);
5619 return size;
5622 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5623 unsigned char *pMemory,
5624 ULONG discriminant,
5625 PFORMAT_STRING pFormat)
5627 unsigned short type;
5629 pFormat += 2;
5631 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5632 if(!pFormat)
5633 return;
5635 type = *(const unsigned short*)pFormat;
5636 if((type & 0xff00) != 0x8000)
5638 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5639 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5640 if (m)
5642 switch(*desc)
5644 case RPC_FC_RP:
5645 case RPC_FC_UP:
5646 case RPC_FC_OP:
5647 case RPC_FC_FP:
5648 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5649 break;
5650 default:
5651 m(pStubMsg, pMemory, desc);
5657 /***********************************************************************
5658 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5660 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5661 unsigned char *pMemory,
5662 PFORMAT_STRING pFormat)
5664 unsigned char switch_type;
5665 unsigned char increment;
5666 ULONG switch_value;
5668 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5669 pFormat++;
5671 switch_type = *pFormat & 0xf;
5672 increment = (*pFormat & 0xf0) >> 4;
5673 pFormat++;
5675 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5677 switch_value = get_discriminant(switch_type, pMemory);
5678 TRACE("got switch value 0x%x\n", switch_value);
5680 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5681 pMemory += increment;
5683 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5686 /***********************************************************************
5687 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5689 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5690 unsigned char **ppMemory,
5691 PFORMAT_STRING pFormat,
5692 unsigned char fMustAlloc)
5694 unsigned char switch_type;
5695 unsigned char increment;
5696 ULONG switch_value;
5697 unsigned short size;
5698 unsigned char *pMemoryArm;
5700 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5701 pFormat++;
5703 switch_type = *pFormat & 0xf;
5704 increment = (*pFormat & 0xf0) >> 4;
5705 pFormat++;
5707 ALIGN_POINTER(pStubMsg->Buffer, increment);
5708 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5709 TRACE("got switch value 0x%x\n", switch_value);
5711 size = *(const unsigned short*)pFormat + increment;
5712 if(!*ppMemory || fMustAlloc)
5713 *ppMemory = NdrAllocate(pStubMsg, size);
5715 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5716 pMemoryArm = *ppMemory + increment;
5718 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5721 /***********************************************************************
5722 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5724 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5725 unsigned char *pMemory,
5726 PFORMAT_STRING pFormat)
5728 unsigned char switch_type;
5729 unsigned char increment;
5730 ULONG switch_value;
5732 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5733 pFormat++;
5735 switch_type = *pFormat & 0xf;
5736 increment = (*pFormat & 0xf0) >> 4;
5737 pFormat++;
5739 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5740 switch_value = get_discriminant(switch_type, pMemory);
5741 TRACE("got switch value 0x%x\n", switch_value);
5743 /* Add discriminant size */
5744 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5745 pMemory += increment;
5747 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5750 /***********************************************************************
5751 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5753 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5754 PFORMAT_STRING pFormat)
5756 unsigned char switch_type;
5757 unsigned char increment;
5758 ULONG switch_value;
5760 switch_type = *pFormat & 0xf;
5761 increment = (*pFormat & 0xf0) >> 4;
5762 pFormat++;
5764 ALIGN_POINTER(pStubMsg->Buffer, increment);
5765 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5766 TRACE("got switch value 0x%x\n", switch_value);
5768 pStubMsg->Memory += increment;
5770 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5773 /***********************************************************************
5774 * NdrEncapsulatedUnionFree [RPCRT4.@]
5776 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5777 unsigned char *pMemory,
5778 PFORMAT_STRING pFormat)
5780 unsigned char switch_type;
5781 unsigned char increment;
5782 ULONG switch_value;
5784 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5785 pFormat++;
5787 switch_type = *pFormat & 0xf;
5788 increment = (*pFormat & 0xf0) >> 4;
5789 pFormat++;
5791 switch_value = get_discriminant(switch_type, pMemory);
5792 TRACE("got switch value 0x%x\n", switch_value);
5794 pMemory += increment;
5796 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5799 /***********************************************************************
5800 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5802 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5803 unsigned char *pMemory,
5804 PFORMAT_STRING pFormat)
5806 unsigned char switch_type;
5808 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5809 pFormat++;
5811 switch_type = *pFormat;
5812 pFormat++;
5814 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5815 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5816 /* Marshall discriminant */
5817 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5819 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5822 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5823 PFORMAT_STRING *ppFormat)
5825 long discriminant = 0;
5827 switch(**ppFormat)
5829 case RPC_FC_BYTE:
5830 case RPC_FC_CHAR:
5831 case RPC_FC_SMALL:
5832 case RPC_FC_USMALL:
5834 UCHAR d;
5835 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5836 discriminant = d;
5837 break;
5839 case RPC_FC_WCHAR:
5840 case RPC_FC_SHORT:
5841 case RPC_FC_USHORT:
5843 USHORT d;
5844 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5845 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5846 discriminant = d;
5847 break;
5849 case RPC_FC_LONG:
5850 case RPC_FC_ULONG:
5852 ULONG d;
5853 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5854 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5855 discriminant = d;
5856 break;
5858 default:
5859 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5861 (*ppFormat)++;
5863 if (pStubMsg->fHasNewCorrDesc)
5864 *ppFormat += 6;
5865 else
5866 *ppFormat += 4;
5867 return discriminant;
5870 /**********************************************************************
5871 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5873 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5874 unsigned char **ppMemory,
5875 PFORMAT_STRING pFormat,
5876 unsigned char fMustAlloc)
5878 long discriminant;
5879 unsigned short size;
5881 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5882 pFormat++;
5884 /* Unmarshall discriminant */
5885 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5886 TRACE("unmarshalled discriminant %lx\n", discriminant);
5888 pFormat += *(const SHORT*)pFormat;
5890 size = *(const unsigned short*)pFormat;
5892 if(!*ppMemory || fMustAlloc)
5893 *ppMemory = NdrAllocate(pStubMsg, size);
5895 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5898 /***********************************************************************
5899 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5901 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5902 unsigned char *pMemory,
5903 PFORMAT_STRING pFormat)
5905 unsigned char switch_type;
5907 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5908 pFormat++;
5910 switch_type = *pFormat;
5911 pFormat++;
5913 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5914 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5915 /* Add discriminant size */
5916 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5918 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5921 /***********************************************************************
5922 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5924 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5925 PFORMAT_STRING pFormat)
5927 ULONG discriminant;
5929 pFormat++;
5930 /* Unmarshall discriminant */
5931 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5932 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5934 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5937 /***********************************************************************
5938 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5940 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5941 unsigned char *pMemory,
5942 PFORMAT_STRING pFormat)
5944 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5945 pFormat++;
5946 pFormat++;
5948 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5949 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5951 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5954 /***********************************************************************
5955 * NdrByteCountPointerMarshall [RPCRT4.@]
5957 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5958 unsigned char *pMemory,
5959 PFORMAT_STRING pFormat)
5961 FIXME("stub\n");
5962 return NULL;
5965 /***********************************************************************
5966 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5968 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5969 unsigned char **ppMemory,
5970 PFORMAT_STRING pFormat,
5971 unsigned char fMustAlloc)
5973 FIXME("stub\n");
5974 return NULL;
5977 /***********************************************************************
5978 * NdrByteCountPointerBufferSize [RPCRT4.@]
5980 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5981 unsigned char *pMemory,
5982 PFORMAT_STRING pFormat)
5984 FIXME("stub\n");
5987 /***********************************************************************
5988 * NdrByteCountPointerMemorySize [RPCRT4.@]
5990 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5991 PFORMAT_STRING pFormat)
5993 FIXME("stub\n");
5994 return 0;
5997 /***********************************************************************
5998 * NdrByteCountPointerFree [RPCRT4.@]
6000 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6001 unsigned char *pMemory,
6002 PFORMAT_STRING pFormat)
6004 FIXME("stub\n");
6007 /***********************************************************************
6008 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6010 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6011 unsigned char *pMemory,
6012 PFORMAT_STRING pFormat)
6014 FIXME("stub\n");
6015 return NULL;
6018 /***********************************************************************
6019 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6021 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6022 unsigned char **ppMemory,
6023 PFORMAT_STRING pFormat,
6024 unsigned char fMustAlloc)
6026 FIXME("stub\n");
6027 return NULL;
6030 /***********************************************************************
6031 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6033 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6034 unsigned char *pMemory,
6035 PFORMAT_STRING pFormat)
6037 FIXME("stub\n");
6040 /***********************************************************************
6041 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6043 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6044 PFORMAT_STRING pFormat)
6046 FIXME("stub\n");
6047 return 0;
6050 /***********************************************************************
6051 * NdrXmitOrRepAsFree [RPCRT4.@]
6053 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6054 unsigned char *pMemory,
6055 PFORMAT_STRING pFormat)
6057 FIXME("stub\n");
6060 /***********************************************************************
6061 * NdrRangeMarshall [internal]
6063 unsigned char *WINAPI NdrRangeMarshall(
6064 PMIDL_STUB_MESSAGE pStubMsg,
6065 unsigned char *pMemory,
6066 PFORMAT_STRING pFormat)
6068 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6069 unsigned char base_type;
6071 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6073 if (pRange->type != RPC_FC_RANGE)
6075 ERR("invalid format type %x\n", pRange->type);
6076 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6077 return NULL;
6080 base_type = pRange->flags_type & 0xf;
6082 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6085 /***********************************************************************
6086 * NdrRangeUnmarshall
6088 unsigned char *WINAPI NdrRangeUnmarshall(
6089 PMIDL_STUB_MESSAGE pStubMsg,
6090 unsigned char **ppMemory,
6091 PFORMAT_STRING pFormat,
6092 unsigned char fMustAlloc)
6094 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6095 unsigned char base_type;
6097 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6099 if (pRange->type != RPC_FC_RANGE)
6101 ERR("invalid format type %x\n", pRange->type);
6102 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6103 return NULL;
6105 base_type = pRange->flags_type & 0xf;
6107 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6108 base_type, pRange->low_value, pRange->high_value);
6110 #define RANGE_UNMARSHALL(type, format_spec) \
6111 do \
6113 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6114 if (fMustAlloc || !*ppMemory) \
6115 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6116 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
6118 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6119 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6120 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6122 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
6123 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
6125 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6126 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
6127 (type)pRange->high_value); \
6128 RpcRaiseException(RPC_S_INVALID_BOUND); \
6129 return NULL; \
6131 TRACE("*ppMemory: %p\n", *ppMemory); \
6132 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6133 pStubMsg->Buffer += sizeof(type); \
6134 } while (0)
6136 switch(base_type)
6138 case RPC_FC_CHAR:
6139 case RPC_FC_SMALL:
6140 RANGE_UNMARSHALL(UCHAR, "%d");
6141 TRACE("value: 0x%02x\n", **ppMemory);
6142 break;
6143 case RPC_FC_BYTE:
6144 case RPC_FC_USMALL:
6145 RANGE_UNMARSHALL(CHAR, "%u");
6146 TRACE("value: 0x%02x\n", **ppMemory);
6147 break;
6148 case RPC_FC_WCHAR: /* FIXME: valid? */
6149 case RPC_FC_USHORT:
6150 RANGE_UNMARSHALL(USHORT, "%u");
6151 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6152 break;
6153 case RPC_FC_SHORT:
6154 RANGE_UNMARSHALL(SHORT, "%d");
6155 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6156 break;
6157 case RPC_FC_LONG:
6158 RANGE_UNMARSHALL(LONG, "%d");
6159 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6160 break;
6161 case RPC_FC_ULONG:
6162 RANGE_UNMARSHALL(ULONG, "%u");
6163 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6164 break;
6165 case RPC_FC_ENUM16:
6166 case RPC_FC_ENUM32:
6167 FIXME("Unhandled enum type\n");
6168 break;
6169 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
6170 case RPC_FC_FLOAT:
6171 case RPC_FC_DOUBLE:
6172 case RPC_FC_HYPER:
6173 default:
6174 ERR("invalid range base type: 0x%02x\n", base_type);
6175 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6178 return NULL;
6181 /***********************************************************************
6182 * NdrRangeBufferSize [internal]
6184 void WINAPI NdrRangeBufferSize(
6185 PMIDL_STUB_MESSAGE pStubMsg,
6186 unsigned char *pMemory,
6187 PFORMAT_STRING pFormat)
6189 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6190 unsigned char base_type;
6192 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6194 if (pRange->type != RPC_FC_RANGE)
6196 ERR("invalid format type %x\n", pRange->type);
6197 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6199 base_type = pRange->flags_type & 0xf;
6201 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6204 /***********************************************************************
6205 * NdrRangeMemorySize [internal]
6207 ULONG WINAPI NdrRangeMemorySize(
6208 PMIDL_STUB_MESSAGE pStubMsg,
6209 PFORMAT_STRING pFormat)
6211 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6212 unsigned char base_type;
6214 if (pRange->type != RPC_FC_RANGE)
6216 ERR("invalid format type %x\n", pRange->type);
6217 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6218 return 0;
6220 base_type = pRange->flags_type & 0xf;
6222 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6225 /***********************************************************************
6226 * NdrRangeFree [internal]
6228 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6229 unsigned char *pMemory,
6230 PFORMAT_STRING pFormat)
6232 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6234 /* nothing to do */
6237 /***********************************************************************
6238 * NdrBaseTypeMarshall [internal]
6240 static unsigned char *WINAPI NdrBaseTypeMarshall(
6241 PMIDL_STUB_MESSAGE pStubMsg,
6242 unsigned char *pMemory,
6243 PFORMAT_STRING pFormat)
6245 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6247 switch(*pFormat)
6249 case RPC_FC_BYTE:
6250 case RPC_FC_CHAR:
6251 case RPC_FC_SMALL:
6252 case RPC_FC_USMALL:
6253 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6254 TRACE("value: 0x%02x\n", *pMemory);
6255 break;
6256 case RPC_FC_WCHAR:
6257 case RPC_FC_SHORT:
6258 case RPC_FC_USHORT:
6259 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6260 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6261 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6262 break;
6263 case RPC_FC_LONG:
6264 case RPC_FC_ULONG:
6265 case RPC_FC_ERROR_STATUS_T:
6266 case RPC_FC_ENUM32:
6267 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6268 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6269 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6270 break;
6271 case RPC_FC_FLOAT:
6272 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6273 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6274 break;
6275 case RPC_FC_DOUBLE:
6276 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6277 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6278 break;
6279 case RPC_FC_HYPER:
6280 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6281 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6282 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6283 break;
6284 case RPC_FC_ENUM16:
6285 /* only 16-bits on the wire, so do a sanity check */
6286 if (*(UINT *)pMemory > SHRT_MAX)
6287 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6288 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6289 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6290 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6291 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6292 pStubMsg->Buffer += sizeof(USHORT);
6293 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6294 break;
6295 case RPC_FC_IGNORE:
6296 break;
6297 default:
6298 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6301 /* FIXME: what is the correct return value? */
6302 return NULL;
6305 /***********************************************************************
6306 * NdrBaseTypeUnmarshall [internal]
6308 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6309 PMIDL_STUB_MESSAGE pStubMsg,
6310 unsigned char **ppMemory,
6311 PFORMAT_STRING pFormat,
6312 unsigned char fMustAlloc)
6314 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6316 #define BASE_TYPE_UNMARSHALL(type) \
6317 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6318 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6320 *ppMemory = pStubMsg->Buffer; \
6321 TRACE("*ppMemory: %p\n", *ppMemory); \
6322 safe_buffer_increment(pStubMsg, sizeof(type)); \
6324 else \
6326 if (fMustAlloc) \
6327 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6328 TRACE("*ppMemory: %p\n", *ppMemory); \
6329 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6332 switch(*pFormat)
6334 case RPC_FC_BYTE:
6335 case RPC_FC_CHAR:
6336 case RPC_FC_SMALL:
6337 case RPC_FC_USMALL:
6338 BASE_TYPE_UNMARSHALL(UCHAR);
6339 TRACE("value: 0x%02x\n", **ppMemory);
6340 break;
6341 case RPC_FC_WCHAR:
6342 case RPC_FC_SHORT:
6343 case RPC_FC_USHORT:
6344 BASE_TYPE_UNMARSHALL(USHORT);
6345 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6346 break;
6347 case RPC_FC_LONG:
6348 case RPC_FC_ULONG:
6349 case RPC_FC_ERROR_STATUS_T:
6350 case RPC_FC_ENUM32:
6351 BASE_TYPE_UNMARSHALL(ULONG);
6352 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6353 break;
6354 case RPC_FC_FLOAT:
6355 BASE_TYPE_UNMARSHALL(float);
6356 TRACE("value: %f\n", **(float **)ppMemory);
6357 break;
6358 case RPC_FC_DOUBLE:
6359 BASE_TYPE_UNMARSHALL(double);
6360 TRACE("value: %f\n", **(double **)ppMemory);
6361 break;
6362 case RPC_FC_HYPER:
6363 BASE_TYPE_UNMARSHALL(ULONGLONG);
6364 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6365 break;
6366 case RPC_FC_ENUM16:
6367 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6368 if (fMustAlloc || !*ppMemory)
6369 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6370 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6371 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6372 TRACE("*ppMemory: %p\n", *ppMemory);
6373 /* 16-bits on the wire, but int in memory */
6374 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6375 pStubMsg->Buffer += sizeof(USHORT);
6376 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6377 break;
6378 case RPC_FC_IGNORE:
6379 break;
6380 default:
6381 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6383 #undef BASE_TYPE_UNMARSHALL
6385 /* FIXME: what is the correct return value? */
6387 return NULL;
6390 /***********************************************************************
6391 * NdrBaseTypeBufferSize [internal]
6393 static void WINAPI NdrBaseTypeBufferSize(
6394 PMIDL_STUB_MESSAGE pStubMsg,
6395 unsigned char *pMemory,
6396 PFORMAT_STRING pFormat)
6398 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6400 switch(*pFormat)
6402 case RPC_FC_BYTE:
6403 case RPC_FC_CHAR:
6404 case RPC_FC_SMALL:
6405 case RPC_FC_USMALL:
6406 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6407 break;
6408 case RPC_FC_WCHAR:
6409 case RPC_FC_SHORT:
6410 case RPC_FC_USHORT:
6411 case RPC_FC_ENUM16:
6412 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6413 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6414 break;
6415 case RPC_FC_LONG:
6416 case RPC_FC_ULONG:
6417 case RPC_FC_ENUM32:
6418 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6419 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6420 break;
6421 case RPC_FC_FLOAT:
6422 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6423 safe_buffer_length_increment(pStubMsg, sizeof(float));
6424 break;
6425 case RPC_FC_DOUBLE:
6426 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6427 safe_buffer_length_increment(pStubMsg, sizeof(double));
6428 break;
6429 case RPC_FC_HYPER:
6430 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6431 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6432 break;
6433 case RPC_FC_ERROR_STATUS_T:
6434 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6435 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6436 break;
6437 case RPC_FC_IGNORE:
6438 break;
6439 default:
6440 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6444 /***********************************************************************
6445 * NdrBaseTypeMemorySize [internal]
6447 static ULONG WINAPI NdrBaseTypeMemorySize(
6448 PMIDL_STUB_MESSAGE pStubMsg,
6449 PFORMAT_STRING pFormat)
6451 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6453 switch(*pFormat)
6455 case RPC_FC_BYTE:
6456 case RPC_FC_CHAR:
6457 case RPC_FC_SMALL:
6458 case RPC_FC_USMALL:
6459 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6460 pStubMsg->MemorySize += sizeof(UCHAR);
6461 return sizeof(UCHAR);
6462 case RPC_FC_WCHAR:
6463 case RPC_FC_SHORT:
6464 case RPC_FC_USHORT:
6465 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6466 pStubMsg->MemorySize += sizeof(USHORT);
6467 return sizeof(USHORT);
6468 case RPC_FC_LONG:
6469 case RPC_FC_ULONG:
6470 case RPC_FC_ENUM32:
6471 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6472 pStubMsg->MemorySize += sizeof(ULONG);
6473 return sizeof(ULONG);
6474 case RPC_FC_FLOAT:
6475 safe_buffer_increment(pStubMsg, sizeof(float));
6476 pStubMsg->MemorySize += sizeof(float);
6477 return sizeof(float);
6478 case RPC_FC_DOUBLE:
6479 safe_buffer_increment(pStubMsg, sizeof(double));
6480 pStubMsg->MemorySize += sizeof(double);
6481 return sizeof(double);
6482 case RPC_FC_HYPER:
6483 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6484 pStubMsg->MemorySize += sizeof(ULONGLONG);
6485 return sizeof(ULONGLONG);
6486 case RPC_FC_ERROR_STATUS_T:
6487 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6488 pStubMsg->MemorySize += sizeof(error_status_t);
6489 return sizeof(error_status_t);
6490 case RPC_FC_ENUM16:
6491 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6492 pStubMsg->MemorySize += sizeof(UINT);
6493 return sizeof(UINT);
6494 case RPC_FC_IGNORE:
6495 pStubMsg->MemorySize += sizeof(void *);
6496 return sizeof(void *);
6497 default:
6498 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6499 return 0;
6503 /***********************************************************************
6504 * NdrBaseTypeFree [internal]
6506 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6507 unsigned char *pMemory,
6508 PFORMAT_STRING pFormat)
6510 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6512 /* nothing to do */
6515 /***********************************************************************
6516 * NdrContextHandleBufferSize [internal]
6518 static void WINAPI NdrContextHandleBufferSize(
6519 PMIDL_STUB_MESSAGE pStubMsg,
6520 unsigned char *pMemory,
6521 PFORMAT_STRING pFormat)
6523 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6525 if (*pFormat != RPC_FC_BIND_CONTEXT)
6527 ERR("invalid format type %x\n", *pFormat);
6528 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6530 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6531 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6534 /***********************************************************************
6535 * NdrContextHandleMarshall [internal]
6537 static unsigned char *WINAPI NdrContextHandleMarshall(
6538 PMIDL_STUB_MESSAGE pStubMsg,
6539 unsigned char *pMemory,
6540 PFORMAT_STRING pFormat)
6542 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6544 if (*pFormat != RPC_FC_BIND_CONTEXT)
6546 ERR("invalid format type %x\n", *pFormat);
6547 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6549 TRACE("flags: 0x%02x\n", pFormat[1]);
6551 if (pFormat[1] & 0x80)
6552 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6553 else
6554 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6556 return NULL;
6559 /***********************************************************************
6560 * NdrContextHandleUnmarshall [internal]
6562 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6563 PMIDL_STUB_MESSAGE pStubMsg,
6564 unsigned char **ppMemory,
6565 PFORMAT_STRING pFormat,
6566 unsigned char fMustAlloc)
6568 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6569 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6571 if (*pFormat != RPC_FC_BIND_CONTEXT)
6573 ERR("invalid format type %x\n", *pFormat);
6574 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6576 TRACE("flags: 0x%02x\n", pFormat[1]);
6578 /* [out]-only or [ret] param */
6579 if ((pFormat[1] & 0x60) == 0x20)
6580 **(NDR_CCONTEXT **)ppMemory = NULL;
6581 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6583 return NULL;
6586 /***********************************************************************
6587 * NdrClientContextMarshall [RPCRT4.@]
6589 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6590 NDR_CCONTEXT ContextHandle,
6591 int fCheck)
6593 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6595 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6597 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6599 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6600 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6601 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6604 /* FIXME: what does fCheck do? */
6605 NDRCContextMarshall(ContextHandle,
6606 pStubMsg->Buffer);
6608 pStubMsg->Buffer += cbNDRContext;
6611 /***********************************************************************
6612 * NdrClientContextUnmarshall [RPCRT4.@]
6614 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6615 NDR_CCONTEXT * pContextHandle,
6616 RPC_BINDING_HANDLE BindHandle)
6618 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6620 ALIGN_POINTER(pStubMsg->Buffer, 4);
6622 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6623 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6625 NDRCContextUnmarshall(pContextHandle,
6626 BindHandle,
6627 pStubMsg->Buffer,
6628 pStubMsg->RpcMsg->DataRepresentation);
6630 pStubMsg->Buffer += cbNDRContext;
6633 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6634 NDR_SCONTEXT ContextHandle,
6635 NDR_RUNDOWN RundownRoutine )
6637 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6639 ALIGN_POINTER(pStubMsg->Buffer, 4);
6641 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6643 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6644 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6645 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6648 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6649 pStubMsg->Buffer, RundownRoutine, NULL,
6650 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6651 pStubMsg->Buffer += cbNDRContext;
6654 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6656 NDR_SCONTEXT ContextHandle;
6658 TRACE("(%p)\n", pStubMsg);
6660 ALIGN_POINTER(pStubMsg->Buffer, 4);
6662 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6664 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6665 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6666 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6669 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6670 pStubMsg->Buffer,
6671 pStubMsg->RpcMsg->DataRepresentation,
6672 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6673 pStubMsg->Buffer += cbNDRContext;
6675 return ContextHandle;
6678 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6679 unsigned char* pMemory,
6680 PFORMAT_STRING pFormat)
6682 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6685 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6686 PFORMAT_STRING pFormat)
6688 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6689 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6691 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6693 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6694 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6695 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6696 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6697 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6699 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6700 if_id = &sif->InterfaceId;
6703 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6704 pStubMsg->RpcMsg->DataRepresentation, if_id,
6705 flags);
6708 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6709 NDR_SCONTEXT ContextHandle,
6710 NDR_RUNDOWN RundownRoutine,
6711 PFORMAT_STRING pFormat)
6713 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6714 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6716 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6718 ALIGN_POINTER(pStubMsg->Buffer, 4);
6720 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6722 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6723 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6724 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6727 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6728 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6729 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6730 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6731 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6733 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6734 if_id = &sif->InterfaceId;
6737 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6738 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6739 pStubMsg->Buffer += cbNDRContext;
6742 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6743 PFORMAT_STRING pFormat)
6745 NDR_SCONTEXT ContextHandle;
6746 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6747 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6749 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6751 ALIGN_POINTER(pStubMsg->Buffer, 4);
6753 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6755 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6756 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6757 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6760 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6761 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6762 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6763 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6764 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6766 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6767 if_id = &sif->InterfaceId;
6770 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6771 pStubMsg->Buffer,
6772 pStubMsg->RpcMsg->DataRepresentation,
6773 if_id, flags);
6774 pStubMsg->Buffer += cbNDRContext;
6776 return ContextHandle;
6779 /***********************************************************************
6780 * NdrCorrelationInitialize [RPCRT4.@]
6782 * Initializes correlation validity checking.
6784 * PARAMS
6785 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6786 * pMemory [I] Pointer to memory to use as a cache.
6787 * CacheSize [I] Size of the memory pointed to by pMemory.
6788 * Flags [I] Reserved. Set to zero.
6790 * RETURNS
6791 * Nothing.
6793 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6795 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6796 pStubMsg->fHasNewCorrDesc = TRUE;
6799 /***********************************************************************
6800 * NdrCorrelationPass [RPCRT4.@]
6802 * Performs correlation validity checking.
6804 * PARAMS
6805 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6807 * RETURNS
6808 * Nothing.
6810 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6812 FIXME("(%p): stub\n", pStubMsg);
6815 /***********************************************************************
6816 * NdrCorrelationFree [RPCRT4.@]
6818 * Frees any resources used while unmarshalling parameters that need
6819 * correlation validity checking.
6821 * PARAMS
6822 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6824 * RETURNS
6825 * Nothing.
6827 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6829 FIXME("(%p): stub\n", pStubMsg);