push 0e6205f14485faf726c13701981a3210b06d24f6
[wine/hacks.git] / dlls / rpcrt4 / ndr_marshall.c
blob80e5b81f515d38fa526a543352a8ea42120b3c72
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
864 pointer_needs_unmarshaling = 0;
865 break;
866 case RPC_FC_FP:
867 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
868 TRACE("pointer_id is 0x%08x\n", pointer_id);
869 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
870 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
871 break;
872 default:
873 FIXME("unhandled ptr type=%02x\n", type);
874 RpcRaiseException(RPC_X_BAD_STUB_DATA);
875 return;
878 if (pointer_needs_unmarshaling) {
879 unsigned char *base_ptr_val = *pPointer;
880 unsigned char **current_ptr = pPointer;
881 if (pStubMsg->IsClient) {
882 TRACE("client\n");
883 /* if we aren't forcing allocation of memory then try to use the existing
884 * (source) pointer to unmarshall the data into so that [in,out]
885 * parameters behave correctly. it doesn't matter if the parameter is
886 * [out] only since in that case the pointer will be NULL. we force
887 * allocation when the source pointer is NULL here instead of in the type
888 * unmarshalling routine for the benefit of the deref code below */
889 if (!fMustAlloc) {
890 if (pSrcPointer) {
891 TRACE("setting *pPointer to %p\n", pSrcPointer);
892 *pPointer = base_ptr_val = pSrcPointer;
893 } else
894 fMustAlloc = TRUE;
896 } else {
897 TRACE("server\n");
898 /* the memory in a stub is never initialised, so we have to work out here
899 * whether we have to initialise it so we can use the optimisation of
900 * setting the pointer to the buffer, if possible, or set fMustAlloc to
901 * TRUE. */
902 if (attr & RPC_FC_P_DEREF) {
903 fMustAlloc = TRUE;
904 } else {
905 base_ptr_val = NULL;
906 *current_ptr = NULL;
910 if (attr & RPC_FC_P_ALLOCALLNODES)
911 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
913 if (attr & RPC_FC_P_DEREF) {
914 if (fMustAlloc) {
915 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
916 *pPointer = base_ptr_val;
917 current_ptr = (unsigned char **)base_ptr_val;
918 } else
919 current_ptr = *(unsigned char***)current_ptr;
920 TRACE("deref => %p\n", current_ptr);
921 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
923 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
924 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
925 else FIXME("no unmarshaller for data type=%02x\n", *desc);
927 if (type == RPC_FC_FP)
928 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
929 base_ptr_val);
932 TRACE("pointer=%p\n", *pPointer);
935 /***********************************************************************
936 * PointerBufferSize [internal]
938 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
939 unsigned char *Pointer,
940 PFORMAT_STRING pFormat)
942 unsigned type = pFormat[0], attr = pFormat[1];
943 PFORMAT_STRING desc;
944 NDR_BUFFERSIZE m;
945 int pointer_needs_sizing;
946 ULONG pointer_id;
948 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
949 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
950 pFormat += 2;
951 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
952 else desc = pFormat + *(const SHORT*)pFormat;
954 switch (type) {
955 case RPC_FC_RP: /* ref pointer (always non-null) */
956 if (!Pointer)
958 ERR("NULL ref pointer is not allowed\n");
959 RpcRaiseException(RPC_X_NULL_REF_POINTER);
961 break;
962 case RPC_FC_OP:
963 case RPC_FC_UP:
964 /* NULL pointer has no further representation */
965 if (!Pointer)
966 return;
967 break;
968 case RPC_FC_FP:
969 pointer_needs_sizing = !NdrFullPointerQueryPointer(
970 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
971 if (!pointer_needs_sizing)
972 return;
973 break;
974 default:
975 FIXME("unhandled ptr type=%02x\n", type);
976 RpcRaiseException(RPC_X_BAD_STUB_DATA);
977 return;
980 if (attr & RPC_FC_P_DEREF) {
981 Pointer = *(unsigned char**)Pointer;
982 TRACE("deref => %p\n", Pointer);
985 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
986 if (m) m(pStubMsg, Pointer, desc);
987 else FIXME("no buffersizer for data type=%02x\n", *desc);
990 /***********************************************************************
991 * PointerMemorySize [internal]
993 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
994 unsigned char *Buffer,
995 PFORMAT_STRING pFormat)
997 unsigned type = pFormat[0], attr = pFormat[1];
998 PFORMAT_STRING desc;
999 NDR_MEMORYSIZE m;
1000 DWORD pointer_id = 0;
1001 int pointer_needs_sizing;
1003 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1004 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1005 pFormat += 2;
1006 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1007 else desc = pFormat + *(const SHORT*)pFormat;
1009 switch (type) {
1010 case RPC_FC_RP: /* ref pointer (always non-null) */
1011 pointer_needs_sizing = 1;
1012 break;
1013 case RPC_FC_UP: /* unique pointer */
1014 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1015 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1016 TRACE("pointer_id is 0x%08x\n", pointer_id);
1017 if (pointer_id)
1018 pointer_needs_sizing = 1;
1019 else
1020 pointer_needs_sizing = 0;
1021 break;
1022 case RPC_FC_FP:
1024 void *pointer;
1025 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1026 TRACE("pointer_id is 0x%08x\n", pointer_id);
1027 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1028 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1029 break;
1031 default:
1032 FIXME("unhandled ptr type=%02x\n", type);
1033 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1034 return 0;
1037 if (attr & RPC_FC_P_DEREF) {
1038 TRACE("deref\n");
1041 if (pointer_needs_sizing) {
1042 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1043 if (m) m(pStubMsg, desc);
1044 else FIXME("no memorysizer for data type=%02x\n", *desc);
1047 return pStubMsg->MemorySize;
1050 /***********************************************************************
1051 * PointerFree [internal]
1053 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1054 unsigned char *Pointer,
1055 PFORMAT_STRING pFormat)
1057 unsigned type = pFormat[0], attr = pFormat[1];
1058 PFORMAT_STRING desc;
1059 NDR_FREE m;
1060 unsigned char *current_pointer = Pointer;
1062 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1063 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1064 if (attr & RPC_FC_P_DONTFREE) return;
1065 pFormat += 2;
1066 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1067 else desc = pFormat + *(const SHORT*)pFormat;
1069 if (!Pointer) return;
1071 if (type == RPC_FC_FP) {
1072 int pointer_needs_freeing = NdrFullPointerFree(
1073 pStubMsg->FullPtrXlatTables, Pointer);
1074 if (!pointer_needs_freeing)
1075 return;
1078 if (attr & RPC_FC_P_DEREF) {
1079 current_pointer = *(unsigned char**)Pointer;
1080 TRACE("deref => %p\n", current_pointer);
1083 m = NdrFreer[*desc & NDR_TABLE_MASK];
1084 if (m) m(pStubMsg, current_pointer, desc);
1086 /* this check stops us from trying to free buffer memory. we don't have to
1087 * worry about clients, since they won't call this function.
1088 * we don't have to check for the buffer being reallocated because
1089 * BufferStart and BufferEnd won't be reset when allocating memory for
1090 * sending the response. we don't have to check for the new buffer here as
1091 * it won't be used a type memory, only for buffer memory */
1092 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1093 goto notfree;
1095 if (attr & RPC_FC_P_ONSTACK) {
1096 TRACE("not freeing stack ptr %p\n", Pointer);
1097 return;
1099 TRACE("freeing %p\n", Pointer);
1100 NdrFree(pStubMsg, Pointer);
1101 return;
1102 notfree:
1103 TRACE("not freeing %p\n", Pointer);
1106 /***********************************************************************
1107 * EmbeddedPointerMarshall
1109 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1110 unsigned char *pMemory,
1111 PFORMAT_STRING pFormat)
1113 unsigned char *Mark = pStubMsg->BufferMark;
1114 unsigned rep, count, stride;
1115 unsigned i;
1116 unsigned char *saved_buffer = NULL;
1118 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1120 if (*pFormat != RPC_FC_PP) return NULL;
1121 pFormat += 2;
1123 if (pStubMsg->PointerBufferMark)
1125 saved_buffer = pStubMsg->Buffer;
1126 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1127 pStubMsg->PointerBufferMark = NULL;
1130 while (pFormat[0] != RPC_FC_END) {
1131 switch (pFormat[0]) {
1132 default:
1133 FIXME("unknown repeat type %d\n", pFormat[0]);
1134 case RPC_FC_NO_REPEAT:
1135 rep = 1;
1136 stride = 0;
1137 count = 1;
1138 pFormat += 2;
1139 break;
1140 case RPC_FC_FIXED_REPEAT:
1141 rep = *(const WORD*)&pFormat[2];
1142 stride = *(const WORD*)&pFormat[4];
1143 count = *(const WORD*)&pFormat[8];
1144 pFormat += 10;
1145 break;
1146 case RPC_FC_VARIABLE_REPEAT:
1147 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1148 stride = *(const WORD*)&pFormat[2];
1149 count = *(const WORD*)&pFormat[6];
1150 pFormat += 8;
1151 break;
1153 for (i = 0; i < rep; i++) {
1154 PFORMAT_STRING info = pFormat;
1155 unsigned char *membase = pMemory + (i * stride);
1156 unsigned char *bufbase = Mark + (i * stride);
1157 unsigned u;
1159 for (u=0; u<count; u++,info+=8) {
1160 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1161 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1162 unsigned char *saved_memory = pStubMsg->Memory;
1164 pStubMsg->Memory = pMemory;
1165 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1166 pStubMsg->Memory = saved_memory;
1169 pFormat += 8 * count;
1172 if (saved_buffer)
1174 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1175 pStubMsg->Buffer = saved_buffer;
1178 STD_OVERFLOW_CHECK(pStubMsg);
1180 return NULL;
1183 /***********************************************************************
1184 * EmbeddedPointerUnmarshall
1186 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1187 unsigned char *pDstBuffer,
1188 unsigned char *pSrcMemoryPtrs,
1189 PFORMAT_STRING pFormat,
1190 unsigned char fMustAlloc)
1192 unsigned char *Mark = pStubMsg->BufferMark;
1193 unsigned rep, count, stride;
1194 unsigned i;
1195 unsigned char *saved_buffer = NULL;
1197 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1199 if (*pFormat != RPC_FC_PP) return NULL;
1200 pFormat += 2;
1202 if (pStubMsg->PointerBufferMark)
1204 saved_buffer = pStubMsg->Buffer;
1205 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1206 pStubMsg->PointerBufferMark = NULL;
1209 while (pFormat[0] != RPC_FC_END) {
1210 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1211 switch (pFormat[0]) {
1212 default:
1213 FIXME("unknown repeat type %d\n", pFormat[0]);
1214 case RPC_FC_NO_REPEAT:
1215 rep = 1;
1216 stride = 0;
1217 count = 1;
1218 pFormat += 2;
1219 break;
1220 case RPC_FC_FIXED_REPEAT:
1221 rep = *(const WORD*)&pFormat[2];
1222 stride = *(const WORD*)&pFormat[4];
1223 count = *(const WORD*)&pFormat[8];
1224 pFormat += 10;
1225 break;
1226 case RPC_FC_VARIABLE_REPEAT:
1227 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1228 stride = *(const WORD*)&pFormat[2];
1229 count = *(const WORD*)&pFormat[6];
1230 pFormat += 8;
1231 break;
1233 for (i = 0; i < rep; i++) {
1234 PFORMAT_STRING info = pFormat;
1235 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1236 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1237 unsigned char *bufbase = Mark + (i * stride);
1238 unsigned u;
1240 for (u=0; u<count; u++,info+=8) {
1241 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1242 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1243 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1244 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1247 pFormat += 8 * count;
1250 if (saved_buffer)
1252 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1253 pStubMsg->Buffer = saved_buffer;
1256 return NULL;
1259 /***********************************************************************
1260 * EmbeddedPointerBufferSize
1262 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1263 unsigned char *pMemory,
1264 PFORMAT_STRING pFormat)
1266 unsigned rep, count, stride;
1267 unsigned i;
1268 ULONG saved_buffer_length = 0;
1270 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1272 if (pStubMsg->IgnoreEmbeddedPointers) return;
1274 if (*pFormat != RPC_FC_PP) return;
1275 pFormat += 2;
1277 if (pStubMsg->PointerLength)
1279 saved_buffer_length = pStubMsg->BufferLength;
1280 pStubMsg->BufferLength = pStubMsg->PointerLength;
1281 pStubMsg->PointerLength = 0;
1284 while (pFormat[0] != RPC_FC_END) {
1285 switch (pFormat[0]) {
1286 default:
1287 FIXME("unknown repeat type %d\n", pFormat[0]);
1288 case RPC_FC_NO_REPEAT:
1289 rep = 1;
1290 stride = 0;
1291 count = 1;
1292 pFormat += 2;
1293 break;
1294 case RPC_FC_FIXED_REPEAT:
1295 rep = *(const WORD*)&pFormat[2];
1296 stride = *(const WORD*)&pFormat[4];
1297 count = *(const WORD*)&pFormat[8];
1298 pFormat += 10;
1299 break;
1300 case RPC_FC_VARIABLE_REPEAT:
1301 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1302 stride = *(const WORD*)&pFormat[2];
1303 count = *(const WORD*)&pFormat[6];
1304 pFormat += 8;
1305 break;
1307 for (i = 0; i < rep; i++) {
1308 PFORMAT_STRING info = pFormat;
1309 unsigned char *membase = pMemory + (i * stride);
1310 unsigned u;
1312 for (u=0; u<count; u++,info+=8) {
1313 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1314 unsigned char *saved_memory = pStubMsg->Memory;
1316 pStubMsg->Memory = pMemory;
1317 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1318 pStubMsg->Memory = saved_memory;
1321 pFormat += 8 * count;
1324 if (saved_buffer_length)
1326 pStubMsg->PointerLength = pStubMsg->BufferLength;
1327 pStubMsg->BufferLength = saved_buffer_length;
1331 /***********************************************************************
1332 * EmbeddedPointerMemorySize [internal]
1334 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1335 PFORMAT_STRING pFormat)
1337 unsigned char *Mark = pStubMsg->BufferMark;
1338 unsigned rep, count, stride;
1339 unsigned i;
1340 unsigned char *saved_buffer = NULL;
1342 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1344 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1346 if (pStubMsg->PointerBufferMark)
1348 saved_buffer = pStubMsg->Buffer;
1349 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1350 pStubMsg->PointerBufferMark = NULL;
1353 if (*pFormat != RPC_FC_PP) return 0;
1354 pFormat += 2;
1356 while (pFormat[0] != RPC_FC_END) {
1357 switch (pFormat[0]) {
1358 default:
1359 FIXME("unknown repeat type %d\n", pFormat[0]);
1360 case RPC_FC_NO_REPEAT:
1361 rep = 1;
1362 stride = 0;
1363 count = 1;
1364 pFormat += 2;
1365 break;
1366 case RPC_FC_FIXED_REPEAT:
1367 rep = *(const WORD*)&pFormat[2];
1368 stride = *(const WORD*)&pFormat[4];
1369 count = *(const WORD*)&pFormat[8];
1370 pFormat += 10;
1371 break;
1372 case RPC_FC_VARIABLE_REPEAT:
1373 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1374 stride = *(const WORD*)&pFormat[2];
1375 count = *(const WORD*)&pFormat[6];
1376 pFormat += 8;
1377 break;
1379 for (i = 0; i < rep; i++) {
1380 PFORMAT_STRING info = pFormat;
1381 unsigned char *bufbase = Mark + (i * stride);
1382 unsigned u;
1383 for (u=0; u<count; u++,info+=8) {
1384 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1385 PointerMemorySize(pStubMsg, bufptr, info+4);
1388 pFormat += 8 * count;
1391 if (saved_buffer)
1393 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1394 pStubMsg->Buffer = saved_buffer;
1397 return 0;
1400 /***********************************************************************
1401 * EmbeddedPointerFree [internal]
1403 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1404 unsigned char *pMemory,
1405 PFORMAT_STRING pFormat)
1407 unsigned rep, count, stride;
1408 unsigned i;
1410 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1411 if (*pFormat != RPC_FC_PP) return;
1412 pFormat += 2;
1414 while (pFormat[0] != RPC_FC_END) {
1415 switch (pFormat[0]) {
1416 default:
1417 FIXME("unknown repeat type %d\n", pFormat[0]);
1418 case RPC_FC_NO_REPEAT:
1419 rep = 1;
1420 stride = 0;
1421 count = 1;
1422 pFormat += 2;
1423 break;
1424 case RPC_FC_FIXED_REPEAT:
1425 rep = *(const WORD*)&pFormat[2];
1426 stride = *(const WORD*)&pFormat[4];
1427 count = *(const WORD*)&pFormat[8];
1428 pFormat += 10;
1429 break;
1430 case RPC_FC_VARIABLE_REPEAT:
1431 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1432 stride = *(const WORD*)&pFormat[2];
1433 count = *(const WORD*)&pFormat[6];
1434 pFormat += 8;
1435 break;
1437 for (i = 0; i < rep; i++) {
1438 PFORMAT_STRING info = pFormat;
1439 unsigned char *membase = pMemory + (i * stride);
1440 unsigned u;
1442 for (u=0; u<count; u++,info+=8) {
1443 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1444 unsigned char *saved_memory = pStubMsg->Memory;
1446 pStubMsg->Memory = pMemory;
1447 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1448 pStubMsg->Memory = saved_memory;
1451 pFormat += 8 * count;
1455 /***********************************************************************
1456 * NdrPointerMarshall [RPCRT4.@]
1458 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1459 unsigned char *pMemory,
1460 PFORMAT_STRING pFormat)
1462 unsigned char *Buffer;
1464 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1466 /* Increment the buffer here instead of in PointerMarshall,
1467 * as that is used by embedded pointers which already handle the incrementing
1468 * the buffer, and shouldn't write any additional pointer data to the wire */
1469 if (*pFormat != RPC_FC_RP)
1471 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1472 Buffer = pStubMsg->Buffer;
1473 safe_buffer_increment(pStubMsg, 4);
1475 else
1476 Buffer = pStubMsg->Buffer;
1478 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1480 return NULL;
1483 /***********************************************************************
1484 * NdrPointerUnmarshall [RPCRT4.@]
1486 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1487 unsigned char **ppMemory,
1488 PFORMAT_STRING pFormat,
1489 unsigned char fMustAlloc)
1491 unsigned char *Buffer;
1493 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1495 /* Increment the buffer here instead of in PointerUnmarshall,
1496 * as that is used by embedded pointers which already handle the incrementing
1497 * the buffer, and shouldn't read any additional pointer data from the
1498 * buffer */
1499 if (*pFormat != RPC_FC_RP)
1501 ALIGN_POINTER(pStubMsg->Buffer, 4);
1502 Buffer = pStubMsg->Buffer;
1503 safe_buffer_increment(pStubMsg, 4);
1505 else
1506 Buffer = pStubMsg->Buffer;
1508 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1510 return NULL;
1513 /***********************************************************************
1514 * NdrPointerBufferSize [RPCRT4.@]
1516 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1517 unsigned char *pMemory,
1518 PFORMAT_STRING pFormat)
1520 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1522 /* Increment the buffer length here instead of in PointerBufferSize,
1523 * as that is used by embedded pointers which already handle the buffer
1524 * length, and shouldn't write anything more to the wire */
1525 if (*pFormat != RPC_FC_RP)
1527 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1528 safe_buffer_length_increment(pStubMsg, 4);
1531 PointerBufferSize(pStubMsg, pMemory, pFormat);
1534 /***********************************************************************
1535 * NdrPointerMemorySize [RPCRT4.@]
1537 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1538 PFORMAT_STRING pFormat)
1540 /* unsigned size = *(LPWORD)(pFormat+2); */
1541 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1542 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1543 return 0;
1546 /***********************************************************************
1547 * NdrPointerFree [RPCRT4.@]
1549 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1550 unsigned char *pMemory,
1551 PFORMAT_STRING pFormat)
1553 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1554 PointerFree(pStubMsg, pMemory, pFormat);
1557 /***********************************************************************
1558 * NdrSimpleTypeMarshall [RPCRT4.@]
1560 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1561 unsigned char FormatChar )
1563 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1566 /***********************************************************************
1567 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1569 * Unmarshall a base type.
1571 * NOTES
1572 * Doesn't check that the buffer is long enough before copying, so the caller
1573 * should do this.
1575 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1576 unsigned char FormatChar )
1578 #define BASE_TYPE_UNMARSHALL(type) \
1579 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1580 TRACE("pMemory: %p\n", pMemory); \
1581 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1582 pStubMsg->Buffer += sizeof(type);
1584 switch(FormatChar)
1586 case RPC_FC_BYTE:
1587 case RPC_FC_CHAR:
1588 case RPC_FC_SMALL:
1589 case RPC_FC_USMALL:
1590 BASE_TYPE_UNMARSHALL(UCHAR);
1591 TRACE("value: 0x%02x\n", *pMemory);
1592 break;
1593 case RPC_FC_WCHAR:
1594 case RPC_FC_SHORT:
1595 case RPC_FC_USHORT:
1596 BASE_TYPE_UNMARSHALL(USHORT);
1597 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1598 break;
1599 case RPC_FC_LONG:
1600 case RPC_FC_ULONG:
1601 case RPC_FC_ERROR_STATUS_T:
1602 case RPC_FC_ENUM32:
1603 BASE_TYPE_UNMARSHALL(ULONG);
1604 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1605 break;
1606 case RPC_FC_FLOAT:
1607 BASE_TYPE_UNMARSHALL(float);
1608 TRACE("value: %f\n", *(float *)pMemory);
1609 break;
1610 case RPC_FC_DOUBLE:
1611 BASE_TYPE_UNMARSHALL(double);
1612 TRACE("value: %f\n", *(double *)pMemory);
1613 break;
1614 case RPC_FC_HYPER:
1615 BASE_TYPE_UNMARSHALL(ULONGLONG);
1616 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1617 break;
1618 case RPC_FC_ENUM16:
1619 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1620 TRACE("pMemory: %p\n", pMemory);
1621 /* 16-bits on the wire, but int in memory */
1622 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1623 pStubMsg->Buffer += sizeof(USHORT);
1624 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1625 break;
1626 case RPC_FC_IGNORE:
1627 break;
1628 default:
1629 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1631 #undef BASE_TYPE_UNMARSHALL
1634 /***********************************************************************
1635 * NdrSimpleStructMarshall [RPCRT4.@]
1637 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1638 unsigned char *pMemory,
1639 PFORMAT_STRING pFormat)
1641 unsigned size = *(const WORD*)(pFormat+2);
1642 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1644 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1646 pStubMsg->BufferMark = pStubMsg->Buffer;
1647 safe_copy_to_buffer(pStubMsg, pMemory, size);
1649 if (pFormat[0] != RPC_FC_STRUCT)
1650 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1652 return NULL;
1655 /***********************************************************************
1656 * NdrSimpleStructUnmarshall [RPCRT4.@]
1658 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1659 unsigned char **ppMemory,
1660 PFORMAT_STRING pFormat,
1661 unsigned char fMustAlloc)
1663 unsigned size = *(const WORD*)(pFormat+2);
1664 unsigned char *saved_buffer;
1665 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1667 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1669 if (fMustAlloc)
1670 *ppMemory = NdrAllocate(pStubMsg, size);
1671 else
1673 if (!pStubMsg->IsClient && !*ppMemory)
1674 /* for servers, we just point straight into the RPC buffer */
1675 *ppMemory = pStubMsg->Buffer;
1678 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1679 safe_buffer_increment(pStubMsg, size);
1680 if (pFormat[0] == RPC_FC_PSTRUCT)
1681 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1683 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1684 if (*ppMemory != saved_buffer)
1685 memcpy(*ppMemory, saved_buffer, size);
1687 return NULL;
1690 /***********************************************************************
1691 * NdrSimpleStructBufferSize [RPCRT4.@]
1693 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1694 unsigned char *pMemory,
1695 PFORMAT_STRING pFormat)
1697 unsigned size = *(const WORD*)(pFormat+2);
1698 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1700 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1702 safe_buffer_length_increment(pStubMsg, size);
1703 if (pFormat[0] != RPC_FC_STRUCT)
1704 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1707 /***********************************************************************
1708 * NdrSimpleStructMemorySize [RPCRT4.@]
1710 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1711 PFORMAT_STRING pFormat)
1713 unsigned short size = *(const WORD *)(pFormat+2);
1715 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1717 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1718 pStubMsg->MemorySize += size;
1719 safe_buffer_increment(pStubMsg, size);
1721 if (pFormat[0] != RPC_FC_STRUCT)
1722 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1723 return pStubMsg->MemorySize;
1726 /***********************************************************************
1727 * NdrSimpleStructFree [RPCRT4.@]
1729 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1730 unsigned char *pMemory,
1731 PFORMAT_STRING pFormat)
1733 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1734 if (pFormat[0] != RPC_FC_STRUCT)
1735 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1738 /* Array helpers */
1740 static inline void array_compute_and_size_conformance(
1741 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1742 PFORMAT_STRING pFormat)
1744 switch (fc)
1746 case RPC_FC_CARRAY:
1747 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1748 SizeConformance(pStubMsg);
1749 break;
1750 case RPC_FC_CVARRAY:
1751 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1752 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1753 SizeConformance(pStubMsg);
1754 break;
1755 case RPC_FC_C_CSTRING:
1756 case RPC_FC_C_WSTRING:
1757 if (pFormat[0] == RPC_FC_C_CSTRING)
1759 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1760 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1762 else
1764 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1765 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1768 if (fc == RPC_FC_STRING_SIZED)
1769 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1770 else
1771 pStubMsg->MaxCount = pStubMsg->ActualCount;
1773 SizeConformance(pStubMsg);
1774 break;
1775 default:
1776 ERR("unknown array format 0x%x\n", fc);
1777 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1781 static inline void array_buffer_size(
1782 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1783 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1785 DWORD size;
1786 DWORD esize;
1787 unsigned char alignment;
1789 switch (fc)
1791 case RPC_FC_CARRAY:
1792 esize = *(const WORD*)(pFormat+2);
1793 alignment = pFormat[1] + 1;
1795 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1797 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1799 size = safe_multiply(esize, pStubMsg->MaxCount);
1800 /* conformance value plus array */
1801 safe_buffer_length_increment(pStubMsg, size);
1803 if (fHasPointers)
1804 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1805 break;
1806 case RPC_FC_CVARRAY:
1807 esize = *(const WORD*)(pFormat+2);
1808 alignment = pFormat[1] + 1;
1810 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1811 pFormat = SkipConformance(pStubMsg, pFormat);
1813 SizeVariance(pStubMsg);
1815 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1817 size = safe_multiply(esize, pStubMsg->ActualCount);
1818 safe_buffer_length_increment(pStubMsg, size);
1820 if (fHasPointers)
1821 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1822 break;
1823 case RPC_FC_C_CSTRING:
1824 case RPC_FC_C_WSTRING:
1825 if (fc == RPC_FC_C_CSTRING)
1826 esize = 1;
1827 else
1828 esize = 2;
1830 SizeVariance(pStubMsg);
1832 size = safe_multiply(esize, pStubMsg->ActualCount);
1833 safe_buffer_length_increment(pStubMsg, size);
1834 break;
1835 default:
1836 ERR("unknown array format 0x%x\n", fc);
1837 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1841 static inline void array_compute_and_write_conformance(
1842 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1843 PFORMAT_STRING pFormat)
1845 switch (fc)
1847 case RPC_FC_CARRAY:
1848 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1849 WriteConformance(pStubMsg);
1850 break;
1851 case RPC_FC_CVARRAY:
1852 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1853 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1854 WriteConformance(pStubMsg);
1855 break;
1856 case RPC_FC_C_CSTRING:
1857 case RPC_FC_C_WSTRING:
1858 if (fc == RPC_FC_C_CSTRING)
1860 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1861 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1863 else
1865 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1866 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1868 if (pFormat[1] == RPC_FC_STRING_SIZED)
1869 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1870 else
1871 pStubMsg->MaxCount = pStubMsg->ActualCount;
1872 pStubMsg->Offset = 0;
1873 WriteConformance(pStubMsg);
1874 break;
1875 default:
1876 ERR("unknown array format 0x%x\n", fc);
1877 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1881 static inline void array_write_variance_and_marshall(
1882 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1883 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1885 DWORD size;
1886 DWORD esize;
1887 unsigned char alignment;
1889 switch (fc)
1891 case RPC_FC_CARRAY:
1892 esize = *(const WORD*)(pFormat+2);
1893 alignment = pFormat[1] + 1;
1895 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1897 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1899 size = safe_multiply(esize, pStubMsg->MaxCount);
1900 if (fHasPointers)
1901 pStubMsg->BufferMark = pStubMsg->Buffer;
1902 safe_copy_to_buffer(pStubMsg, pMemory, size);
1904 if (fHasPointers)
1905 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1906 break;
1907 case RPC_FC_CVARRAY:
1908 esize = *(const WORD*)(pFormat+2);
1909 alignment = pFormat[1] + 1;
1911 /* conformance */
1912 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1913 /* variance */
1914 pFormat = SkipConformance(pStubMsg, pFormat);
1916 WriteVariance(pStubMsg);
1918 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1920 size = safe_multiply(esize, pStubMsg->ActualCount);
1922 if (fHasPointers)
1923 pStubMsg->BufferMark = pStubMsg->Buffer;
1924 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
1926 if (fHasPointers)
1927 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1928 break;
1929 case RPC_FC_C_CSTRING:
1930 case RPC_FC_C_WSTRING:
1931 if (fc == RPC_FC_C_CSTRING)
1932 esize = 1;
1933 else
1934 esize = 2;
1936 WriteVariance(pStubMsg);
1938 size = safe_multiply(esize, pStubMsg->ActualCount);
1939 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
1940 break;
1941 default:
1942 ERR("unknown array format 0x%x\n", fc);
1943 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1947 static inline ULONG array_read_conformance(
1948 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
1950 DWORD esize;
1952 switch (fc)
1954 case RPC_FC_CARRAY:
1955 esize = *(const WORD*)(pFormat+2);
1956 pFormat = ReadConformance(pStubMsg, pFormat+4);
1957 return safe_multiply(esize, pStubMsg->MaxCount);
1958 case RPC_FC_CVARRAY:
1959 esize = *(const WORD*)(pFormat+2);
1960 pFormat = ReadConformance(pStubMsg, pFormat+4);
1961 return safe_multiply(esize, pStubMsg->MaxCount);
1962 case RPC_FC_C_CSTRING:
1963 case RPC_FC_C_WSTRING:
1964 if (fc == RPC_FC_C_CSTRING)
1965 esize = 1;
1966 else
1967 esize = 2;
1969 if (pFormat[1] == RPC_FC_STRING_SIZED)
1970 ReadConformance(pStubMsg, pFormat + 2);
1971 else
1972 ReadConformance(pStubMsg, NULL);
1973 return safe_multiply(esize, pStubMsg->MaxCount);
1974 default:
1975 ERR("unknown array format 0x%x\n", fc);
1976 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1980 static inline ULONG array_read_variance_and_unmarshall(
1981 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
1982 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
1983 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
1985 ULONG bufsize, memsize;
1986 WORD esize;
1987 unsigned char alignment;
1988 unsigned char *saved_buffer;
1989 ULONG offset;
1991 switch (fc)
1993 case RPC_FC_CARRAY:
1994 esize = *(const WORD*)(pFormat+2);
1995 alignment = pFormat[1] + 1;
1997 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
1999 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2001 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2003 if (fUnmarshall)
2005 if (fMustAlloc)
2006 *ppMemory = NdrAllocate(pStubMsg, memsize);
2007 else
2009 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2010 /* for servers, we just point straight into the RPC buffer */
2011 *ppMemory = pStubMsg->Buffer;
2014 saved_buffer = pStubMsg->Buffer;
2015 safe_buffer_increment(pStubMsg, bufsize);
2017 pStubMsg->BufferMark = saved_buffer;
2018 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2020 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2021 if (*ppMemory != saved_buffer)
2022 memcpy(*ppMemory, saved_buffer, bufsize);
2024 return bufsize;
2025 case RPC_FC_CVARRAY:
2026 esize = *(const WORD*)(pFormat+2);
2027 alignment = pFormat[1] + 1;
2029 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2031 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2033 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2035 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2036 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2038 if (fUnmarshall)
2040 offset = pStubMsg->Offset;
2042 if (!fMustAlloc && !*ppMemory)
2043 fMustAlloc = TRUE;
2044 if (fMustAlloc)
2045 *ppMemory = NdrAllocate(pStubMsg, memsize);
2046 saved_buffer = pStubMsg->Buffer;
2047 safe_buffer_increment(pStubMsg, bufsize);
2049 pStubMsg->BufferMark = saved_buffer;
2050 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2051 fMustAlloc);
2053 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2055 return bufsize;
2056 case RPC_FC_C_CSTRING:
2057 case RPC_FC_C_WSTRING:
2058 if (fc == RPC_FC_C_CSTRING)
2059 esize = 1;
2060 else
2061 esize = 2;
2063 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2065 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2067 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2068 pStubMsg->ActualCount, pStubMsg->MaxCount);
2069 RpcRaiseException(RPC_S_INVALID_BOUND);
2071 if (pStubMsg->Offset)
2073 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2074 RpcRaiseException(RPC_S_INVALID_BOUND);
2077 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2078 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2080 validate_string_data(pStubMsg, bufsize, esize);
2082 if (fUnmarshall)
2084 if (fMustAlloc)
2085 *ppMemory = NdrAllocate(pStubMsg, memsize);
2086 else
2088 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2089 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2090 /* if the data in the RPC buffer is big enough, we just point
2091 * straight into it */
2092 *ppMemory = pStubMsg->Buffer;
2093 else if (!*ppMemory)
2094 *ppMemory = NdrAllocate(pStubMsg, memsize);
2097 if (*ppMemory == pStubMsg->Buffer)
2098 safe_buffer_increment(pStubMsg, bufsize);
2099 else
2100 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2102 if (*pFormat == RPC_FC_C_CSTRING)
2103 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2104 else
2105 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2107 return bufsize;
2108 default:
2109 ERR("unknown array format 0x%x\n", fc);
2110 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2114 static inline void array_memory_size(
2115 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2116 unsigned char fHasPointers)
2118 ULONG bufsize, memsize;
2119 DWORD esize;
2120 unsigned char alignment;
2122 switch (fc)
2124 case RPC_FC_CARRAY:
2125 esize = *(const WORD*)(pFormat+2);
2126 alignment = pFormat[1] + 1;
2128 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2130 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2131 pStubMsg->MemorySize += memsize;
2133 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2134 if (fHasPointers)
2135 pStubMsg->BufferMark = pStubMsg->Buffer;
2136 safe_buffer_increment(pStubMsg, bufsize);
2138 if (fHasPointers)
2139 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2140 break;
2141 case RPC_FC_CVARRAY:
2142 esize = *(const WORD*)(pFormat+2);
2143 alignment = pFormat[1] + 1;
2145 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2147 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2149 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2150 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2151 pStubMsg->MemorySize += memsize;
2153 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2154 if (fHasPointers)
2155 pStubMsg->BufferMark = pStubMsg->Buffer;
2156 safe_buffer_increment(pStubMsg, bufsize);
2158 if (fHasPointers)
2159 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2160 break;
2161 case RPC_FC_C_CSTRING:
2162 case RPC_FC_C_WSTRING:
2163 if (fc == RPC_FC_C_CSTRING)
2164 esize = 1;
2165 else
2166 esize = 2;
2168 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2170 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2172 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2173 pStubMsg->ActualCount, pStubMsg->MaxCount);
2174 RpcRaiseException(RPC_S_INVALID_BOUND);
2176 if (pStubMsg->Offset)
2178 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2179 RpcRaiseException(RPC_S_INVALID_BOUND);
2182 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2183 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2185 validate_string_data(pStubMsg, bufsize, esize);
2187 safe_buffer_increment(pStubMsg, bufsize);
2188 pStubMsg->MemorySize += memsize;
2189 break;
2190 default:
2191 ERR("unknown array format 0x%x\n", fc);
2192 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2196 static inline void array_free(
2197 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2198 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2200 switch (fc)
2202 case RPC_FC_CARRAY:
2203 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2204 if (fHasPointers)
2205 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2206 break;
2207 case RPC_FC_CVARRAY:
2208 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2209 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2210 if (fHasPointers)
2211 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2212 break;
2213 case RPC_FC_C_CSTRING:
2214 case RPC_FC_C_WSTRING:
2215 /* No embedded pointers so nothing to do */
2216 break;
2217 default:
2218 ERR("unknown array format 0x%x\n", fc);
2219 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2224 * NdrConformantString:
2226 * What MS calls a ConformantString is, in DCE terminology,
2227 * a Varying-Conformant String.
2229 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2230 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2231 * into unmarshalled string)
2232 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2234 * data: CHARTYPE[maxlen]
2236 * ], where CHARTYPE is the appropriate character type (specified externally)
2240 /***********************************************************************
2241 * NdrConformantStringMarshall [RPCRT4.@]
2243 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2244 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2246 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2248 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2249 ERR("Unhandled string type: %#x\n", pFormat[0]);
2250 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2253 /* allow compiler to optimise inline function by passing constant into
2254 * these functions */
2255 if (pFormat[0] == RPC_FC_C_CSTRING) {
2256 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2257 pFormat);
2258 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2259 pFormat, TRUE /* fHasPointers */);
2260 } else {
2261 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2262 pFormat);
2263 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2264 pFormat, TRUE /* fHasPointers */);
2267 return NULL;
2270 /***********************************************************************
2271 * NdrConformantStringBufferSize [RPCRT4.@]
2273 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2274 unsigned char* pMemory, PFORMAT_STRING pFormat)
2276 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2278 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2279 ERR("Unhandled string type: %#x\n", pFormat[0]);
2280 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2283 /* allow compiler to optimise inline function by passing constant into
2284 * these functions */
2285 if (pFormat[0] == RPC_FC_C_CSTRING) {
2286 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2287 pFormat);
2288 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2289 TRUE /* fHasPointers */);
2290 } else {
2291 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2292 pFormat);
2293 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2294 TRUE /* fHasPointers */);
2298 /************************************************************************
2299 * NdrConformantStringMemorySize [RPCRT4.@]
2301 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2302 PFORMAT_STRING pFormat )
2304 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2306 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2307 ERR("Unhandled string type: %#x\n", pFormat[0]);
2308 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2311 /* allow compiler to optimise inline function by passing constant into
2312 * these functions */
2313 if (pFormat[0] == RPC_FC_C_CSTRING) {
2314 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2315 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2316 TRUE /* fHasPointers */);
2317 } else {
2318 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2319 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2320 TRUE /* fHasPointers */);
2323 return pStubMsg->MemorySize;
2326 /************************************************************************
2327 * NdrConformantStringUnmarshall [RPCRT4.@]
2329 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2330 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2332 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2333 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2335 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2336 ERR("Unhandled string type: %#x\n", *pFormat);
2337 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2340 /* allow compiler to optimise inline function by passing constant into
2341 * these functions */
2342 if (pFormat[0] == RPC_FC_C_CSTRING) {
2343 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2344 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2345 pFormat, fMustAlloc,
2346 TRUE /* fUseBufferMemoryServer */,
2347 TRUE /* fUnmarshall */);
2348 } else {
2349 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2350 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2351 pFormat, fMustAlloc,
2352 TRUE /* fUseBufferMemoryServer */,
2353 TRUE /* fUnmarshall */);
2356 return NULL;
2359 /***********************************************************************
2360 * NdrNonConformantStringMarshall [RPCRT4.@]
2362 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2363 unsigned char *pMemory,
2364 PFORMAT_STRING pFormat)
2366 ULONG esize, size, maxsize;
2368 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2370 maxsize = *(USHORT *)&pFormat[2];
2372 if (*pFormat == RPC_FC_CSTRING)
2374 ULONG i;
2375 const char *str = (const char *)pMemory;
2376 for (i = 0; i < maxsize && *str; i++, str++)
2378 TRACE("string=%s\n", debugstr_an(str, i));
2379 pStubMsg->ActualCount = i + 1;
2380 esize = 1;
2382 else if (*pFormat == RPC_FC_WSTRING)
2384 ULONG i;
2385 const WCHAR *str = (const WCHAR *)pMemory;
2386 for (i = 0; i < maxsize && *str; i++, str++)
2388 TRACE("string=%s\n", debugstr_wn(str, i));
2389 pStubMsg->ActualCount = i + 1;
2390 esize = 2;
2392 else
2394 ERR("Unhandled string type: %#x\n", *pFormat);
2395 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2398 pStubMsg->Offset = 0;
2399 WriteVariance(pStubMsg);
2401 size = safe_multiply(esize, pStubMsg->ActualCount);
2402 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2404 return NULL;
2407 /***********************************************************************
2408 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2410 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2411 unsigned char **ppMemory,
2412 PFORMAT_STRING pFormat,
2413 unsigned char fMustAlloc)
2415 ULONG bufsize, memsize, esize, maxsize;
2417 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2418 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2420 maxsize = *(USHORT *)&pFormat[2];
2422 ReadVariance(pStubMsg, NULL, maxsize);
2423 if (pStubMsg->Offset)
2425 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2426 RpcRaiseException(RPC_S_INVALID_BOUND);
2429 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2430 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2431 else
2433 ERR("Unhandled string type: %#x\n", *pFormat);
2434 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2437 memsize = esize * maxsize;
2438 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2440 validate_string_data(pStubMsg, bufsize, esize);
2442 if (fMustAlloc || !*ppMemory)
2443 *ppMemory = NdrAllocate(pStubMsg, memsize);
2445 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2447 if (*pFormat == RPC_FC_CSTRING) {
2448 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2450 else if (*pFormat == RPC_FC_WSTRING) {
2451 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2454 return NULL;
2457 /***********************************************************************
2458 * NdrNonConformantStringBufferSize [RPCRT4.@]
2460 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2461 unsigned char *pMemory,
2462 PFORMAT_STRING pFormat)
2464 ULONG esize, maxsize;
2466 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2468 maxsize = *(USHORT *)&pFormat[2];
2470 SizeVariance(pStubMsg);
2472 if (*pFormat == RPC_FC_CSTRING)
2474 ULONG i;
2475 const char *str = (const char *)pMemory;
2476 for (i = 0; i < maxsize && *str; i++, str++)
2478 TRACE("string=%s\n", debugstr_an(str, i));
2479 pStubMsg->ActualCount = i + 1;
2480 esize = 1;
2482 else if (*pFormat == RPC_FC_WSTRING)
2484 ULONG i;
2485 const WCHAR *str = (const WCHAR *)pMemory;
2486 for (i = 0; i < maxsize && *str; i++, str++)
2488 TRACE("string=%s\n", debugstr_wn(str, i));
2489 pStubMsg->ActualCount = i + 1;
2490 esize = 2;
2492 else
2494 ERR("Unhandled string type: %#x\n", *pFormat);
2495 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2498 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2501 /***********************************************************************
2502 * NdrNonConformantStringMemorySize [RPCRT4.@]
2504 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2505 PFORMAT_STRING pFormat)
2507 ULONG bufsize, memsize, esize, maxsize;
2509 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2511 maxsize = *(USHORT *)&pFormat[2];
2513 ReadVariance(pStubMsg, NULL, maxsize);
2515 if (pStubMsg->Offset)
2517 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2518 RpcRaiseException(RPC_S_INVALID_BOUND);
2521 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2522 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2523 else
2525 ERR("Unhandled string type: %#x\n", *pFormat);
2526 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2529 memsize = esize * maxsize;
2530 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2532 validate_string_data(pStubMsg, bufsize, esize);
2534 safe_buffer_increment(pStubMsg, bufsize);
2535 pStubMsg->MemorySize += memsize;
2537 return pStubMsg->MemorySize;
2540 /* Complex types */
2542 #include "pshpack1.h"
2543 typedef struct
2545 unsigned char type;
2546 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2547 ULONG low_value;
2548 ULONG high_value;
2549 } NDR_RANGE;
2550 #include "poppack.h"
2552 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2553 PFORMAT_STRING pFormat)
2555 switch (*pFormat) {
2556 case RPC_FC_STRUCT:
2557 case RPC_FC_PSTRUCT:
2558 case RPC_FC_CSTRUCT:
2559 case RPC_FC_BOGUS_STRUCT:
2560 case RPC_FC_SMFARRAY:
2561 case RPC_FC_SMVARRAY:
2562 case RPC_FC_CSTRING:
2563 return *(const WORD*)&pFormat[2];
2564 case RPC_FC_USER_MARSHAL:
2565 return *(const WORD*)&pFormat[4];
2566 case RPC_FC_RANGE: {
2567 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2568 case RPC_FC_BYTE:
2569 case RPC_FC_CHAR:
2570 case RPC_FC_SMALL:
2571 case RPC_FC_USMALL:
2572 return sizeof(UCHAR);
2573 case RPC_FC_WCHAR:
2574 case RPC_FC_SHORT:
2575 case RPC_FC_USHORT:
2576 return sizeof(USHORT);
2577 case RPC_FC_LONG:
2578 case RPC_FC_ULONG:
2579 case RPC_FC_ENUM32:
2580 return sizeof(ULONG);
2581 case RPC_FC_FLOAT:
2582 return sizeof(float);
2583 case RPC_FC_DOUBLE:
2584 return sizeof(double);
2585 case RPC_FC_HYPER:
2586 return sizeof(ULONGLONG);
2587 case RPC_FC_ENUM16:
2588 return sizeof(UINT);
2589 default:
2590 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2591 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2594 case RPC_FC_NON_ENCAPSULATED_UNION:
2595 pFormat += 2;
2596 if (pStubMsg->fHasNewCorrDesc)
2597 pFormat += 6;
2598 else
2599 pFormat += 4;
2601 pFormat += *(const SHORT*)pFormat;
2602 return *(const SHORT*)pFormat;
2603 case RPC_FC_IP:
2604 return sizeof(void *);
2605 case RPC_FC_WSTRING:
2606 return *(const WORD*)&pFormat[2] * 2;
2607 default:
2608 FIXME("unhandled embedded type %02x\n", *pFormat);
2610 return 0;
2614 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2615 PFORMAT_STRING pFormat)
2617 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2619 if (!m)
2621 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2622 return 0;
2625 return m(pStubMsg, pFormat);
2629 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2630 unsigned char *pMemory,
2631 PFORMAT_STRING pFormat,
2632 PFORMAT_STRING pPointer)
2634 PFORMAT_STRING desc;
2635 NDR_MARSHALL m;
2636 unsigned long size;
2638 while (*pFormat != RPC_FC_END) {
2639 switch (*pFormat) {
2640 case RPC_FC_BYTE:
2641 case RPC_FC_CHAR:
2642 case RPC_FC_SMALL:
2643 case RPC_FC_USMALL:
2644 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2645 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2646 pMemory += 1;
2647 break;
2648 case RPC_FC_WCHAR:
2649 case RPC_FC_SHORT:
2650 case RPC_FC_USHORT:
2651 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2652 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2653 pMemory += 2;
2654 break;
2655 case RPC_FC_ENUM16:
2656 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2657 if (32767 < *(DWORD*)pMemory)
2658 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2659 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2660 pMemory += 4;
2661 break;
2662 case RPC_FC_LONG:
2663 case RPC_FC_ULONG:
2664 case RPC_FC_ENUM32:
2665 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2666 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2667 pMemory += 4;
2668 break;
2669 case RPC_FC_HYPER:
2670 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2671 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2672 pMemory += 8;
2673 break;
2674 case RPC_FC_POINTER:
2676 unsigned char *saved_buffer;
2677 int pointer_buffer_mark_set = 0;
2678 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2679 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2680 if (*pPointer != RPC_FC_RP)
2681 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2682 saved_buffer = pStubMsg->Buffer;
2683 if (pStubMsg->PointerBufferMark)
2685 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2686 pStubMsg->PointerBufferMark = NULL;
2687 pointer_buffer_mark_set = 1;
2689 else if (*pPointer != RPC_FC_RP)
2690 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2691 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2692 if (pointer_buffer_mark_set)
2694 STD_OVERFLOW_CHECK(pStubMsg);
2695 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2696 pStubMsg->Buffer = saved_buffer;
2697 if (*pPointer != RPC_FC_RP)
2698 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2700 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2701 pPointer += 4;
2702 pMemory += 4;
2703 break;
2705 case RPC_FC_ALIGNM4:
2706 ALIGN_POINTER(pMemory, 4);
2707 break;
2708 case RPC_FC_ALIGNM8:
2709 ALIGN_POINTER(pMemory, 8);
2710 break;
2711 case RPC_FC_STRUCTPAD1:
2712 case RPC_FC_STRUCTPAD2:
2713 case RPC_FC_STRUCTPAD3:
2714 case RPC_FC_STRUCTPAD4:
2715 case RPC_FC_STRUCTPAD5:
2716 case RPC_FC_STRUCTPAD6:
2717 case RPC_FC_STRUCTPAD7:
2718 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2719 break;
2720 case RPC_FC_EMBEDDED_COMPLEX:
2721 pMemory += pFormat[1];
2722 pFormat += 2;
2723 desc = pFormat + *(const SHORT*)pFormat;
2724 size = EmbeddedComplexSize(pStubMsg, desc);
2725 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2726 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2727 if (m)
2729 /* for some reason interface pointers aren't generated as
2730 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2731 * they still need the derefencing treatment that pointers are
2732 * given */
2733 if (*desc == RPC_FC_IP)
2734 m(pStubMsg, *(unsigned char **)pMemory, desc);
2735 else
2736 m(pStubMsg, pMemory, desc);
2738 else FIXME("no marshaller for embedded type %02x\n", *desc);
2739 pMemory += size;
2740 pFormat += 2;
2741 continue;
2742 case RPC_FC_PAD:
2743 break;
2744 default:
2745 FIXME("unhandled format 0x%02x\n", *pFormat);
2747 pFormat++;
2750 return pMemory;
2753 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2754 unsigned char *pMemory,
2755 PFORMAT_STRING pFormat,
2756 PFORMAT_STRING pPointer,
2757 unsigned char fMustAlloc)
2759 PFORMAT_STRING desc;
2760 NDR_UNMARSHALL m;
2761 unsigned long size;
2763 while (*pFormat != RPC_FC_END) {
2764 switch (*pFormat) {
2765 case RPC_FC_BYTE:
2766 case RPC_FC_CHAR:
2767 case RPC_FC_SMALL:
2768 case RPC_FC_USMALL:
2769 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2770 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2771 pMemory += 1;
2772 break;
2773 case RPC_FC_WCHAR:
2774 case RPC_FC_SHORT:
2775 case RPC_FC_USHORT:
2776 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2777 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2778 pMemory += 2;
2779 break;
2780 case RPC_FC_ENUM16:
2781 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2782 *(DWORD*)pMemory &= 0xffff;
2783 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2784 if (32767 < *(DWORD*)pMemory)
2785 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2786 pMemory += 4;
2787 break;
2788 case RPC_FC_LONG:
2789 case RPC_FC_ULONG:
2790 case RPC_FC_ENUM32:
2791 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2792 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2793 pMemory += 4;
2794 break;
2795 case RPC_FC_HYPER:
2796 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2797 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2798 pMemory += 8;
2799 break;
2800 case RPC_FC_POINTER:
2802 unsigned char *saved_buffer;
2803 int pointer_buffer_mark_set = 0;
2804 TRACE("pointer => %p\n", pMemory);
2805 if (*pPointer != RPC_FC_RP)
2806 ALIGN_POINTER(pStubMsg->Buffer, 4);
2807 saved_buffer = pStubMsg->Buffer;
2808 if (pStubMsg->PointerBufferMark)
2810 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2811 pStubMsg->PointerBufferMark = NULL;
2812 pointer_buffer_mark_set = 1;
2814 else if (*pPointer != RPC_FC_RP)
2815 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2817 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2818 if (pointer_buffer_mark_set)
2820 STD_OVERFLOW_CHECK(pStubMsg);
2821 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2822 pStubMsg->Buffer = saved_buffer;
2823 if (*pPointer != RPC_FC_RP)
2824 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2826 pPointer += 4;
2827 pMemory += 4;
2828 break;
2830 case RPC_FC_ALIGNM4:
2831 ALIGN_POINTER_CLEAR(pMemory, 4);
2832 break;
2833 case RPC_FC_ALIGNM8:
2834 ALIGN_POINTER_CLEAR(pMemory, 8);
2835 break;
2836 case RPC_FC_STRUCTPAD1:
2837 case RPC_FC_STRUCTPAD2:
2838 case RPC_FC_STRUCTPAD3:
2839 case RPC_FC_STRUCTPAD4:
2840 case RPC_FC_STRUCTPAD5:
2841 case RPC_FC_STRUCTPAD6:
2842 case RPC_FC_STRUCTPAD7:
2843 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2844 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2845 break;
2846 case RPC_FC_EMBEDDED_COMPLEX:
2847 pMemory += pFormat[1];
2848 pFormat += 2;
2849 desc = pFormat + *(const SHORT*)pFormat;
2850 size = EmbeddedComplexSize(pStubMsg, desc);
2851 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2852 if (fMustAlloc)
2853 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2854 * since the type is part of the memory block that is encompassed by
2855 * the whole complex type. Memory is forced to allocate when pointers
2856 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2857 * clearing the memory we pass in to the unmarshaller */
2858 memset(pMemory, 0, size);
2859 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2860 if (m)
2862 /* for some reason interface pointers aren't generated as
2863 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2864 * they still need the derefencing treatment that pointers are
2865 * given */
2866 if (*desc == RPC_FC_IP)
2867 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2868 else
2869 m(pStubMsg, &pMemory, desc, FALSE);
2871 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2872 pMemory += size;
2873 pFormat += 2;
2874 continue;
2875 case RPC_FC_PAD:
2876 break;
2877 default:
2878 FIXME("unhandled format %d\n", *pFormat);
2880 pFormat++;
2883 return pMemory;
2886 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2887 unsigned char *pMemory,
2888 PFORMAT_STRING pFormat,
2889 PFORMAT_STRING pPointer)
2891 PFORMAT_STRING desc;
2892 NDR_BUFFERSIZE m;
2893 unsigned long size;
2895 while (*pFormat != RPC_FC_END) {
2896 switch (*pFormat) {
2897 case RPC_FC_BYTE:
2898 case RPC_FC_CHAR:
2899 case RPC_FC_SMALL:
2900 case RPC_FC_USMALL:
2901 safe_buffer_length_increment(pStubMsg, 1);
2902 pMemory += 1;
2903 break;
2904 case RPC_FC_WCHAR:
2905 case RPC_FC_SHORT:
2906 case RPC_FC_USHORT:
2907 safe_buffer_length_increment(pStubMsg, 2);
2908 pMemory += 2;
2909 break;
2910 case RPC_FC_ENUM16:
2911 safe_buffer_length_increment(pStubMsg, 2);
2912 pMemory += 4;
2913 break;
2914 case RPC_FC_LONG:
2915 case RPC_FC_ULONG:
2916 case RPC_FC_ENUM32:
2917 safe_buffer_length_increment(pStubMsg, 4);
2918 pMemory += 4;
2919 break;
2920 case RPC_FC_HYPER:
2921 safe_buffer_length_increment(pStubMsg, 8);
2922 pMemory += 8;
2923 break;
2924 case RPC_FC_POINTER:
2925 if (!pStubMsg->IgnoreEmbeddedPointers)
2927 int saved_buffer_length = pStubMsg->BufferLength;
2928 pStubMsg->BufferLength = pStubMsg->PointerLength;
2929 pStubMsg->PointerLength = 0;
2930 if(!pStubMsg->BufferLength)
2931 ERR("BufferLength == 0??\n");
2932 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2933 pStubMsg->PointerLength = pStubMsg->BufferLength;
2934 pStubMsg->BufferLength = saved_buffer_length;
2936 if (*pPointer != RPC_FC_RP)
2938 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2939 safe_buffer_length_increment(pStubMsg, 4);
2941 pPointer += 4;
2942 pMemory += 4;
2943 break;
2944 case RPC_FC_ALIGNM4:
2945 ALIGN_POINTER(pMemory, 4);
2946 break;
2947 case RPC_FC_ALIGNM8:
2948 ALIGN_POINTER(pMemory, 8);
2949 break;
2950 case RPC_FC_STRUCTPAD1:
2951 case RPC_FC_STRUCTPAD2:
2952 case RPC_FC_STRUCTPAD3:
2953 case RPC_FC_STRUCTPAD4:
2954 case RPC_FC_STRUCTPAD5:
2955 case RPC_FC_STRUCTPAD6:
2956 case RPC_FC_STRUCTPAD7:
2957 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2958 break;
2959 case RPC_FC_EMBEDDED_COMPLEX:
2960 pMemory += pFormat[1];
2961 pFormat += 2;
2962 desc = pFormat + *(const SHORT*)pFormat;
2963 size = EmbeddedComplexSize(pStubMsg, desc);
2964 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2965 if (m)
2967 /* for some reason interface pointers aren't generated as
2968 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2969 * they still need the derefencing treatment that pointers are
2970 * given */
2971 if (*desc == RPC_FC_IP)
2972 m(pStubMsg, *(unsigned char **)pMemory, desc);
2973 else
2974 m(pStubMsg, pMemory, desc);
2976 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2977 pMemory += size;
2978 pFormat += 2;
2979 continue;
2980 case RPC_FC_PAD:
2981 break;
2982 default:
2983 FIXME("unhandled format 0x%02x\n", *pFormat);
2985 pFormat++;
2988 return pMemory;
2991 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2992 unsigned char *pMemory,
2993 PFORMAT_STRING pFormat,
2994 PFORMAT_STRING pPointer)
2996 PFORMAT_STRING desc;
2997 NDR_FREE m;
2998 unsigned long size;
3000 while (*pFormat != RPC_FC_END) {
3001 switch (*pFormat) {
3002 case RPC_FC_BYTE:
3003 case RPC_FC_CHAR:
3004 case RPC_FC_SMALL:
3005 case RPC_FC_USMALL:
3006 pMemory += 1;
3007 break;
3008 case RPC_FC_WCHAR:
3009 case RPC_FC_SHORT:
3010 case RPC_FC_USHORT:
3011 pMemory += 2;
3012 break;
3013 case RPC_FC_LONG:
3014 case RPC_FC_ULONG:
3015 case RPC_FC_ENUM16:
3016 case RPC_FC_ENUM32:
3017 pMemory += 4;
3018 break;
3019 case RPC_FC_HYPER:
3020 pMemory += 8;
3021 break;
3022 case RPC_FC_POINTER:
3023 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3024 pPointer += 4;
3025 pMemory += 4;
3026 break;
3027 case RPC_FC_ALIGNM4:
3028 ALIGN_POINTER(pMemory, 4);
3029 break;
3030 case RPC_FC_ALIGNM8:
3031 ALIGN_POINTER(pMemory, 8);
3032 break;
3033 case RPC_FC_STRUCTPAD1:
3034 case RPC_FC_STRUCTPAD2:
3035 case RPC_FC_STRUCTPAD3:
3036 case RPC_FC_STRUCTPAD4:
3037 case RPC_FC_STRUCTPAD5:
3038 case RPC_FC_STRUCTPAD6:
3039 case RPC_FC_STRUCTPAD7:
3040 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3041 break;
3042 case RPC_FC_EMBEDDED_COMPLEX:
3043 pMemory += pFormat[1];
3044 pFormat += 2;
3045 desc = pFormat + *(const SHORT*)pFormat;
3046 size = EmbeddedComplexSize(pStubMsg, desc);
3047 m = NdrFreer[*desc & NDR_TABLE_MASK];
3048 if (m)
3050 /* for some reason interface pointers aren't generated as
3051 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3052 * they still need the derefencing treatment that pointers are
3053 * given */
3054 if (*desc == RPC_FC_IP)
3055 m(pStubMsg, *(unsigned char **)pMemory, desc);
3056 else
3057 m(pStubMsg, pMemory, desc);
3059 pMemory += size;
3060 pFormat += 2;
3061 continue;
3062 case RPC_FC_PAD:
3063 break;
3064 default:
3065 FIXME("unhandled format 0x%02x\n", *pFormat);
3067 pFormat++;
3070 return pMemory;
3073 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3074 PFORMAT_STRING pFormat,
3075 PFORMAT_STRING pPointer)
3077 PFORMAT_STRING desc;
3078 unsigned long size = 0;
3080 while (*pFormat != RPC_FC_END) {
3081 switch (*pFormat) {
3082 case RPC_FC_BYTE:
3083 case RPC_FC_CHAR:
3084 case RPC_FC_SMALL:
3085 case RPC_FC_USMALL:
3086 size += 1;
3087 safe_buffer_increment(pStubMsg, 1);
3088 break;
3089 case RPC_FC_WCHAR:
3090 case RPC_FC_SHORT:
3091 case RPC_FC_USHORT:
3092 size += 2;
3093 safe_buffer_increment(pStubMsg, 2);
3094 break;
3095 case RPC_FC_ENUM16:
3096 size += 4;
3097 safe_buffer_increment(pStubMsg, 2);
3098 break;
3099 case RPC_FC_LONG:
3100 case RPC_FC_ULONG:
3101 case RPC_FC_ENUM32:
3102 size += 4;
3103 safe_buffer_increment(pStubMsg, 4);
3104 break;
3105 case RPC_FC_HYPER:
3106 size += 8;
3107 safe_buffer_increment(pStubMsg, 8);
3108 break;
3109 case RPC_FC_POINTER:
3111 unsigned char *saved_buffer;
3112 int pointer_buffer_mark_set = 0;
3113 if (*pPointer != RPC_FC_RP)
3114 ALIGN_POINTER(pStubMsg->Buffer, 4);
3115 saved_buffer = pStubMsg->Buffer;
3116 if (pStubMsg->PointerBufferMark)
3118 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3119 pStubMsg->PointerBufferMark = NULL;
3120 pointer_buffer_mark_set = 1;
3122 else if (*pPointer != RPC_FC_RP)
3123 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3125 if (!pStubMsg->IgnoreEmbeddedPointers)
3126 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3127 if (pointer_buffer_mark_set)
3129 STD_OVERFLOW_CHECK(pStubMsg);
3130 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3131 pStubMsg->Buffer = saved_buffer;
3132 if (*pPointer != RPC_FC_RP)
3133 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3135 pPointer += 4;
3136 size += 4;
3137 break;
3139 case RPC_FC_ALIGNM4:
3140 ALIGN_LENGTH(size, 4);
3141 ALIGN_POINTER(pStubMsg->Buffer, 4);
3142 break;
3143 case RPC_FC_ALIGNM8:
3144 ALIGN_LENGTH(size, 8);
3145 ALIGN_POINTER(pStubMsg->Buffer, 8);
3146 break;
3147 case RPC_FC_STRUCTPAD1:
3148 case RPC_FC_STRUCTPAD2:
3149 case RPC_FC_STRUCTPAD3:
3150 case RPC_FC_STRUCTPAD4:
3151 case RPC_FC_STRUCTPAD5:
3152 case RPC_FC_STRUCTPAD6:
3153 case RPC_FC_STRUCTPAD7:
3154 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3155 break;
3156 case RPC_FC_EMBEDDED_COMPLEX:
3157 size += pFormat[1];
3158 pFormat += 2;
3159 desc = pFormat + *(const SHORT*)pFormat;
3160 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3161 pFormat += 2;
3162 continue;
3163 case RPC_FC_PAD:
3164 break;
3165 default:
3166 FIXME("unhandled format 0x%02x\n", *pFormat);
3168 pFormat++;
3171 return size;
3174 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
3175 PFORMAT_STRING pFormat)
3177 PFORMAT_STRING desc;
3178 unsigned long size = 0;
3180 while (*pFormat != RPC_FC_END) {
3181 switch (*pFormat) {
3182 case RPC_FC_BYTE:
3183 case RPC_FC_CHAR:
3184 case RPC_FC_SMALL:
3185 case RPC_FC_USMALL:
3186 size += 1;
3187 break;
3188 case RPC_FC_WCHAR:
3189 case RPC_FC_SHORT:
3190 case RPC_FC_USHORT:
3191 size += 2;
3192 break;
3193 case RPC_FC_LONG:
3194 case RPC_FC_ULONG:
3195 case RPC_FC_ENUM16:
3196 case RPC_FC_ENUM32:
3197 size += 4;
3198 break;
3199 case RPC_FC_HYPER:
3200 size += 8;
3201 break;
3202 case RPC_FC_POINTER:
3203 size += sizeof(void *);
3204 break;
3205 case RPC_FC_ALIGNM4:
3206 ALIGN_LENGTH(size, 4);
3207 break;
3208 case RPC_FC_ALIGNM8:
3209 ALIGN_LENGTH(size, 8);
3210 break;
3211 case RPC_FC_STRUCTPAD1:
3212 case RPC_FC_STRUCTPAD2:
3213 case RPC_FC_STRUCTPAD3:
3214 case RPC_FC_STRUCTPAD4:
3215 case RPC_FC_STRUCTPAD5:
3216 case RPC_FC_STRUCTPAD6:
3217 case RPC_FC_STRUCTPAD7:
3218 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3219 break;
3220 case RPC_FC_EMBEDDED_COMPLEX:
3221 size += pFormat[1];
3222 pFormat += 2;
3223 desc = pFormat + *(const SHORT*)pFormat;
3224 size += EmbeddedComplexSize(pStubMsg, desc);
3225 pFormat += 2;
3226 continue;
3227 case RPC_FC_PAD:
3228 break;
3229 default:
3230 FIXME("unhandled format 0x%02x\n", *pFormat);
3232 pFormat++;
3235 return size;
3238 /***********************************************************************
3239 * NdrComplexStructMarshall [RPCRT4.@]
3241 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3242 unsigned char *pMemory,
3243 PFORMAT_STRING pFormat)
3245 PFORMAT_STRING conf_array = NULL;
3246 PFORMAT_STRING pointer_desc = NULL;
3247 unsigned char *OldMemory = pStubMsg->Memory;
3248 int pointer_buffer_mark_set = 0;
3249 ULONG count = 0;
3250 ULONG max_count = 0;
3251 ULONG offset = 0;
3253 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3255 if (!pStubMsg->PointerBufferMark)
3257 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3258 /* save buffer length */
3259 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3261 /* get the buffer pointer after complex array data, but before
3262 * pointer data */
3263 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3264 pStubMsg->IgnoreEmbeddedPointers = 1;
3265 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3266 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3268 /* save it for use by embedded pointer code later */
3269 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3270 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
3271 pointer_buffer_mark_set = 1;
3273 /* restore the original buffer length */
3274 pStubMsg->BufferLength = saved_buffer_length;
3277 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3279 pFormat += 4;
3280 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3281 pFormat += 2;
3282 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3283 pFormat += 2;
3285 pStubMsg->Memory = pMemory;
3287 if (conf_array)
3289 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3290 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3291 pMemory + struct_size, conf_array);
3292 /* these could be changed in ComplexMarshall so save them for later */
3293 max_count = pStubMsg->MaxCount;
3294 count = pStubMsg->ActualCount;
3295 offset = pStubMsg->Offset;
3298 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3300 if (conf_array)
3302 pStubMsg->MaxCount = max_count;
3303 pStubMsg->ActualCount = count;
3304 pStubMsg->Offset = offset;
3305 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3306 conf_array, TRUE /* fHasPointers */);
3309 pStubMsg->Memory = OldMemory;
3311 if (pointer_buffer_mark_set)
3313 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3314 pStubMsg->PointerBufferMark = NULL;
3317 STD_OVERFLOW_CHECK(pStubMsg);
3319 return NULL;
3322 /***********************************************************************
3323 * NdrComplexStructUnmarshall [RPCRT4.@]
3325 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3326 unsigned char **ppMemory,
3327 PFORMAT_STRING pFormat,
3328 unsigned char fMustAlloc)
3330 unsigned size = *(const WORD*)(pFormat+2);
3331 PFORMAT_STRING conf_array = NULL;
3332 PFORMAT_STRING pointer_desc = NULL;
3333 unsigned char *pMemory;
3334 int pointer_buffer_mark_set = 0;
3335 ULONG count = 0;
3336 ULONG max_count = 0;
3337 ULONG offset = 0;
3338 ULONG array_size = 0;
3340 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3342 if (!pStubMsg->PointerBufferMark)
3344 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3345 /* save buffer pointer */
3346 unsigned char *saved_buffer = pStubMsg->Buffer;
3348 /* get the buffer pointer after complex array data, but before
3349 * pointer data */
3350 pStubMsg->IgnoreEmbeddedPointers = 1;
3351 NdrComplexStructMemorySize(pStubMsg, pFormat);
3352 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3354 /* save it for use by embedded pointer code later */
3355 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3356 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
3357 pointer_buffer_mark_set = 1;
3359 /* restore the original buffer */
3360 pStubMsg->Buffer = saved_buffer;
3363 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3365 pFormat += 4;
3366 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3367 pFormat += 2;
3368 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3369 pFormat += 2;
3371 if (conf_array)
3373 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3374 size += array_size;
3376 /* these could be changed in ComplexMarshall so save them for later */
3377 max_count = pStubMsg->MaxCount;
3378 count = pStubMsg->ActualCount;
3379 offset = pStubMsg->Offset;
3382 if (fMustAlloc || !*ppMemory)
3383 *ppMemory = NdrAllocate(pStubMsg, size);
3385 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3387 if (conf_array)
3389 pStubMsg->MaxCount = max_count;
3390 pStubMsg->ActualCount = count;
3391 pStubMsg->Offset = offset;
3392 if (fMustAlloc)
3393 memset(pMemory, 0, array_size);
3394 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3395 conf_array, FALSE,
3396 FALSE /* fUseBufferMemoryServer */,
3397 TRUE /* fUnmarshall */);
3400 if (pointer_buffer_mark_set)
3402 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3403 pStubMsg->PointerBufferMark = NULL;
3406 return NULL;
3409 /***********************************************************************
3410 * NdrComplexStructBufferSize [RPCRT4.@]
3412 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3413 unsigned char *pMemory,
3414 PFORMAT_STRING pFormat)
3416 PFORMAT_STRING conf_array = NULL;
3417 PFORMAT_STRING pointer_desc = NULL;
3418 unsigned char *OldMemory = pStubMsg->Memory;
3419 int pointer_length_set = 0;
3420 ULONG count = 0;
3421 ULONG max_count = 0;
3422 ULONG offset = 0;
3424 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3426 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3428 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3430 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3431 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3433 /* get the buffer length after complex struct data, but before
3434 * pointer data */
3435 pStubMsg->IgnoreEmbeddedPointers = 1;
3436 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3437 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3439 /* save it for use by embedded pointer code later */
3440 pStubMsg->PointerLength = pStubMsg->BufferLength;
3441 pointer_length_set = 1;
3442 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
3444 /* restore the original buffer length */
3445 pStubMsg->BufferLength = saved_buffer_length;
3448 pFormat += 4;
3449 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3450 pFormat += 2;
3451 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3452 pFormat += 2;
3454 pStubMsg->Memory = pMemory;
3456 if (conf_array)
3458 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3459 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3460 conf_array);
3462 /* these could be changed in ComplexMarshall so save them for later */
3463 max_count = pStubMsg->MaxCount;
3464 count = pStubMsg->ActualCount;
3465 offset = pStubMsg->Offset;
3468 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3470 if (conf_array)
3472 pStubMsg->MaxCount = max_count;
3473 pStubMsg->ActualCount = count;
3474 pStubMsg->Offset = offset;
3475 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3476 TRUE /* fHasPointers */);
3479 pStubMsg->Memory = OldMemory;
3481 if(pointer_length_set)
3483 pStubMsg->BufferLength = pStubMsg->PointerLength;
3484 pStubMsg->PointerLength = 0;
3489 /***********************************************************************
3490 * NdrComplexStructMemorySize [RPCRT4.@]
3492 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3493 PFORMAT_STRING pFormat)
3495 unsigned size = *(const WORD*)(pFormat+2);
3496 PFORMAT_STRING conf_array = NULL;
3497 PFORMAT_STRING pointer_desc = NULL;
3498 ULONG count = 0;
3499 ULONG max_count = 0;
3500 ULONG offset = 0;
3502 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3504 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3506 pFormat += 4;
3507 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3508 pFormat += 2;
3509 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3510 pFormat += 2;
3512 if (conf_array)
3514 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3516 /* these could be changed in ComplexStructMemorySize so save them for
3517 * later */
3518 max_count = pStubMsg->MaxCount;
3519 count = pStubMsg->ActualCount;
3520 offset = pStubMsg->Offset;
3523 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3525 if (conf_array)
3527 pStubMsg->MaxCount = max_count;
3528 pStubMsg->ActualCount = count;
3529 pStubMsg->Offset = offset;
3530 array_memory_size(conf_array[0], pStubMsg, conf_array,
3531 TRUE /* fHasPointers */);
3534 return size;
3537 /***********************************************************************
3538 * NdrComplexStructFree [RPCRT4.@]
3540 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3541 unsigned char *pMemory,
3542 PFORMAT_STRING pFormat)
3544 PFORMAT_STRING conf_array = NULL;
3545 PFORMAT_STRING pointer_desc = NULL;
3546 unsigned char *OldMemory = pStubMsg->Memory;
3548 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3550 pFormat += 4;
3551 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3552 pFormat += 2;
3553 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3554 pFormat += 2;
3556 pStubMsg->Memory = pMemory;
3558 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3560 if (conf_array)
3561 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3562 TRUE /* fHasPointers */);
3564 pStubMsg->Memory = OldMemory;
3567 /***********************************************************************
3568 * NdrConformantArrayMarshall [RPCRT4.@]
3570 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3571 unsigned char *pMemory,
3572 PFORMAT_STRING pFormat)
3574 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3575 if (pFormat[0] != RPC_FC_CARRAY)
3577 ERR("invalid format = 0x%x\n", pFormat[0]);
3578 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3581 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3582 pFormat);
3583 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3584 TRUE /* fHasPointers */);
3586 return NULL;
3589 /***********************************************************************
3590 * NdrConformantArrayUnmarshall [RPCRT4.@]
3592 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3593 unsigned char **ppMemory,
3594 PFORMAT_STRING pFormat,
3595 unsigned char fMustAlloc)
3597 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3598 if (pFormat[0] != RPC_FC_CARRAY)
3600 ERR("invalid format = 0x%x\n", pFormat[0]);
3601 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3604 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3605 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3606 fMustAlloc,
3607 TRUE /* fUseBufferMemoryServer */,
3608 TRUE /* fUnmarshall */);
3610 return NULL;
3613 /***********************************************************************
3614 * NdrConformantArrayBufferSize [RPCRT4.@]
3616 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3617 unsigned char *pMemory,
3618 PFORMAT_STRING pFormat)
3620 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3621 if (pFormat[0] != RPC_FC_CARRAY)
3623 ERR("invalid format = 0x%x\n", pFormat[0]);
3624 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3627 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3628 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3629 TRUE /* fHasPointers */);
3632 /***********************************************************************
3633 * NdrConformantArrayMemorySize [RPCRT4.@]
3635 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3636 PFORMAT_STRING pFormat)
3638 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3639 if (pFormat[0] != RPC_FC_CARRAY)
3641 ERR("invalid format = 0x%x\n", pFormat[0]);
3642 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3645 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3646 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3648 return pStubMsg->MemorySize;
3651 /***********************************************************************
3652 * NdrConformantArrayFree [RPCRT4.@]
3654 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3655 unsigned char *pMemory,
3656 PFORMAT_STRING pFormat)
3658 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3659 if (pFormat[0] != RPC_FC_CARRAY)
3661 ERR("invalid format = 0x%x\n", pFormat[0]);
3662 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3665 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3666 TRUE /* fHasPointers */);
3670 /***********************************************************************
3671 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3673 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3674 unsigned char* pMemory,
3675 PFORMAT_STRING pFormat )
3677 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3679 if (pFormat[0] != RPC_FC_CVARRAY)
3681 ERR("invalid format type %x\n", pFormat[0]);
3682 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3683 return NULL;
3686 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3687 pFormat);
3688 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3689 pFormat, TRUE /* fHasPointers */);
3691 return NULL;
3695 /***********************************************************************
3696 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3698 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3699 unsigned char** ppMemory,
3700 PFORMAT_STRING pFormat,
3701 unsigned char fMustAlloc )
3703 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3705 if (pFormat[0] != RPC_FC_CVARRAY)
3707 ERR("invalid format type %x\n", pFormat[0]);
3708 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3709 return NULL;
3712 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3713 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3714 pFormat, fMustAlloc,
3715 TRUE /* fUseBufferMemoryServer */,
3716 TRUE /* fUnmarshall */);
3718 return NULL;
3722 /***********************************************************************
3723 * NdrConformantVaryingArrayFree [RPCRT4.@]
3725 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3726 unsigned char* pMemory,
3727 PFORMAT_STRING pFormat )
3729 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3731 if (pFormat[0] != RPC_FC_CVARRAY)
3733 ERR("invalid format type %x\n", pFormat[0]);
3734 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3735 return;
3738 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3739 TRUE /* fHasPointers */);
3743 /***********************************************************************
3744 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3746 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3747 unsigned char* pMemory, PFORMAT_STRING pFormat )
3749 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3751 if (pFormat[0] != RPC_FC_CVARRAY)
3753 ERR("invalid format type %x\n", pFormat[0]);
3754 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3755 return;
3758 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3759 pFormat);
3760 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3761 TRUE /* fHasPointers */);
3765 /***********************************************************************
3766 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3768 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3769 PFORMAT_STRING pFormat )
3771 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3773 if (pFormat[0] != RPC_FC_CVARRAY)
3775 ERR("invalid format type %x\n", pFormat[0]);
3776 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3777 return pStubMsg->MemorySize;
3780 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3781 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3782 TRUE /* fHasPointers */);
3784 return pStubMsg->MemorySize;
3788 /***********************************************************************
3789 * NdrComplexArrayMarshall [RPCRT4.@]
3791 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3792 unsigned char *pMemory,
3793 PFORMAT_STRING pFormat)
3795 ULONG i, count, def;
3796 BOOL variance_present;
3797 unsigned char alignment;
3798 int pointer_buffer_mark_set = 0;
3800 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3802 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3804 ERR("invalid format type %x\n", pFormat[0]);
3805 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3806 return NULL;
3809 alignment = pFormat[1] + 1;
3811 if (!pStubMsg->PointerBufferMark)
3813 /* save buffer fields that may be changed by buffer sizer functions
3814 * and that may be needed later on */
3815 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3816 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3817 unsigned long saved_max_count = pStubMsg->MaxCount;
3818 unsigned long saved_offset = pStubMsg->Offset;
3819 unsigned long saved_actual_count = pStubMsg->ActualCount;
3821 /* get the buffer pointer after complex array data, but before
3822 * pointer data */
3823 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3824 pStubMsg->IgnoreEmbeddedPointers = 1;
3825 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3826 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3828 /* save it for use by embedded pointer code later */
3829 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3830 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3831 pointer_buffer_mark_set = 1;
3833 /* restore fields */
3834 pStubMsg->ActualCount = saved_actual_count;
3835 pStubMsg->Offset = saved_offset;
3836 pStubMsg->MaxCount = saved_max_count;
3837 pStubMsg->BufferLength = saved_buffer_length;
3840 def = *(const WORD*)&pFormat[2];
3841 pFormat += 4;
3843 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3844 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3846 variance_present = IsConformanceOrVariancePresent(pFormat);
3847 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3848 TRACE("variance = %d\n", pStubMsg->ActualCount);
3850 WriteConformance(pStubMsg);
3851 if (variance_present)
3852 WriteVariance(pStubMsg);
3854 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3856 count = pStubMsg->ActualCount;
3857 for (i = 0; i < count; i++)
3858 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3860 STD_OVERFLOW_CHECK(pStubMsg);
3862 if (pointer_buffer_mark_set)
3864 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3865 pStubMsg->PointerBufferMark = NULL;
3868 return NULL;
3871 /***********************************************************************
3872 * NdrComplexArrayUnmarshall [RPCRT4.@]
3874 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3875 unsigned char **ppMemory,
3876 PFORMAT_STRING pFormat,
3877 unsigned char fMustAlloc)
3879 ULONG i, count, size;
3880 unsigned char alignment;
3881 unsigned char *pMemory;
3882 unsigned char *saved_buffer;
3883 int pointer_buffer_mark_set = 0;
3884 int saved_ignore_embedded;
3886 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3888 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3890 ERR("invalid format type %x\n", pFormat[0]);
3891 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3892 return NULL;
3895 alignment = pFormat[1] + 1;
3897 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3898 /* save buffer pointer */
3899 saved_buffer = pStubMsg->Buffer;
3900 /* get the buffer pointer after complex array data, but before
3901 * pointer data */
3902 pStubMsg->IgnoreEmbeddedPointers = 1;
3903 pStubMsg->MemorySize = 0;
3904 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3905 size = pStubMsg->MemorySize;
3906 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3908 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3909 if (!pStubMsg->PointerBufferMark)
3911 /* save it for use by embedded pointer code later */
3912 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3913 pointer_buffer_mark_set = 1;
3915 /* restore the original buffer */
3916 pStubMsg->Buffer = saved_buffer;
3918 pFormat += 4;
3920 pFormat = ReadConformance(pStubMsg, pFormat);
3921 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3923 if (fMustAlloc || !*ppMemory)
3924 *ppMemory = NdrAllocate(pStubMsg, size);
3926 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3928 pMemory = *ppMemory;
3929 count = pStubMsg->ActualCount;
3930 for (i = 0; i < count; i++)
3931 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3933 if (pointer_buffer_mark_set)
3935 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3936 pStubMsg->PointerBufferMark = NULL;
3939 return NULL;
3942 /***********************************************************************
3943 * NdrComplexArrayBufferSize [RPCRT4.@]
3945 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3946 unsigned char *pMemory,
3947 PFORMAT_STRING pFormat)
3949 ULONG i, count, def;
3950 unsigned char alignment;
3951 BOOL variance_present;
3952 int pointer_length_set = 0;
3954 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3956 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3958 ERR("invalid format type %x\n", pFormat[0]);
3959 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3960 return;
3963 alignment = pFormat[1] + 1;
3965 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3967 /* save buffer fields that may be changed by buffer sizer functions
3968 * and that may be needed later on */
3969 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3970 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3971 unsigned long saved_max_count = pStubMsg->MaxCount;
3972 unsigned long saved_offset = pStubMsg->Offset;
3973 unsigned long saved_actual_count = pStubMsg->ActualCount;
3975 /* get the buffer pointer after complex array data, but before
3976 * pointer data */
3977 pStubMsg->IgnoreEmbeddedPointers = 1;
3978 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3979 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3981 /* save it for use by embedded pointer code later */
3982 pStubMsg->PointerLength = pStubMsg->BufferLength;
3983 pointer_length_set = 1;
3985 /* restore fields */
3986 pStubMsg->ActualCount = saved_actual_count;
3987 pStubMsg->Offset = saved_offset;
3988 pStubMsg->MaxCount = saved_max_count;
3989 pStubMsg->BufferLength = saved_buffer_length;
3991 def = *(const WORD*)&pFormat[2];
3992 pFormat += 4;
3994 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3995 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3996 SizeConformance(pStubMsg);
3998 variance_present = IsConformanceOrVariancePresent(pFormat);
3999 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4000 TRACE("variance = %d\n", pStubMsg->ActualCount);
4002 if (variance_present)
4003 SizeVariance(pStubMsg);
4005 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4007 count = pStubMsg->ActualCount;
4008 for (i = 0; i < count; i++)
4009 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4011 if(pointer_length_set)
4013 pStubMsg->BufferLength = pStubMsg->PointerLength;
4014 pStubMsg->PointerLength = 0;
4018 /***********************************************************************
4019 * NdrComplexArrayMemorySize [RPCRT4.@]
4021 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4022 PFORMAT_STRING pFormat)
4024 ULONG i, count, esize, SavedMemorySize, MemorySize;
4025 unsigned char alignment;
4027 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4029 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4031 ERR("invalid format type %x\n", pFormat[0]);
4032 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4033 return 0;
4036 alignment = pFormat[1] + 1;
4038 pFormat += 4;
4040 pFormat = ReadConformance(pStubMsg, pFormat);
4041 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4043 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4045 SavedMemorySize = pStubMsg->MemorySize;
4047 esize = ComplexStructSize(pStubMsg, pFormat);
4049 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4051 count = pStubMsg->ActualCount;
4052 for (i = 0; i < count; i++)
4053 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4055 pStubMsg->MemorySize = SavedMemorySize;
4057 pStubMsg->MemorySize += MemorySize;
4058 return MemorySize;
4061 /***********************************************************************
4062 * NdrComplexArrayFree [RPCRT4.@]
4064 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4065 unsigned char *pMemory,
4066 PFORMAT_STRING pFormat)
4068 ULONG i, count, def;
4070 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4072 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4074 ERR("invalid format type %x\n", pFormat[0]);
4075 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4076 return;
4079 def = *(const WORD*)&pFormat[2];
4080 pFormat += 4;
4082 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4083 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4085 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4086 TRACE("variance = %d\n", pStubMsg->ActualCount);
4088 count = pStubMsg->ActualCount;
4089 for (i = 0; i < count; i++)
4090 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4093 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4094 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4095 USER_MARSHAL_CB *umcb)
4097 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4098 pStubMsg->RpcMsg->DataRepresentation);
4099 umcb->pStubMsg = pStubMsg;
4100 umcb->pReserve = NULL;
4101 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4102 umcb->CBType = cbtype;
4103 umcb->pFormat = pFormat;
4104 umcb->pTypeFormat = NULL /* FIXME */;
4107 #define USER_MARSHAL_PTR_PREFIX \
4108 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4109 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4111 /***********************************************************************
4112 * NdrUserMarshalMarshall [RPCRT4.@]
4114 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4115 unsigned char *pMemory,
4116 PFORMAT_STRING pFormat)
4118 unsigned flags = pFormat[1];
4119 unsigned index = *(const WORD*)&pFormat[2];
4120 unsigned char *saved_buffer = NULL;
4121 USER_MARSHAL_CB umcb;
4123 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4124 TRACE("index=%d\n", index);
4126 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4128 if (flags & USER_MARSHAL_POINTER)
4130 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4131 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4132 pStubMsg->Buffer += 4;
4133 if (pStubMsg->PointerBufferMark)
4135 saved_buffer = pStubMsg->Buffer;
4136 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4137 pStubMsg->PointerBufferMark = NULL;
4139 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4141 else
4142 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4144 pStubMsg->Buffer =
4145 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4146 &umcb.Flags, pStubMsg->Buffer, pMemory);
4148 if (saved_buffer)
4150 STD_OVERFLOW_CHECK(pStubMsg);
4151 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4152 pStubMsg->Buffer = saved_buffer;
4155 STD_OVERFLOW_CHECK(pStubMsg);
4157 return NULL;
4160 /***********************************************************************
4161 * NdrUserMarshalUnmarshall [RPCRT4.@]
4163 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4164 unsigned char **ppMemory,
4165 PFORMAT_STRING pFormat,
4166 unsigned char fMustAlloc)
4168 unsigned flags = pFormat[1];
4169 unsigned index = *(const WORD*)&pFormat[2];
4170 DWORD memsize = *(const WORD*)&pFormat[4];
4171 unsigned char *saved_buffer = NULL;
4172 USER_MARSHAL_CB umcb;
4174 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4175 TRACE("index=%d\n", index);
4177 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4179 if (flags & USER_MARSHAL_POINTER)
4181 ALIGN_POINTER(pStubMsg->Buffer, 4);
4182 /* skip pointer prefix */
4183 pStubMsg->Buffer += 4;
4184 if (pStubMsg->PointerBufferMark)
4186 saved_buffer = pStubMsg->Buffer;
4187 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4188 pStubMsg->PointerBufferMark = NULL;
4190 ALIGN_POINTER(pStubMsg->Buffer, 8);
4192 else
4193 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4195 if (fMustAlloc || !*ppMemory)
4196 *ppMemory = NdrAllocate(pStubMsg, memsize);
4198 pStubMsg->Buffer =
4199 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4200 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4202 if (saved_buffer)
4204 STD_OVERFLOW_CHECK(pStubMsg);
4205 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4206 pStubMsg->Buffer = saved_buffer;
4209 return NULL;
4212 /***********************************************************************
4213 * NdrUserMarshalBufferSize [RPCRT4.@]
4215 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4216 unsigned char *pMemory,
4217 PFORMAT_STRING pFormat)
4219 unsigned flags = pFormat[1];
4220 unsigned index = *(const WORD*)&pFormat[2];
4221 DWORD bufsize = *(const WORD*)&pFormat[6];
4222 USER_MARSHAL_CB umcb;
4223 unsigned long saved_buffer_length = 0;
4225 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4226 TRACE("index=%d\n", index);
4228 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4230 if (flags & USER_MARSHAL_POINTER)
4232 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4233 /* skip pointer prefix */
4234 safe_buffer_length_increment(pStubMsg, 4);
4235 if (pStubMsg->IgnoreEmbeddedPointers)
4236 return;
4237 if (pStubMsg->PointerLength)
4239 saved_buffer_length = pStubMsg->BufferLength;
4240 pStubMsg->BufferLength = pStubMsg->PointerLength;
4241 pStubMsg->PointerLength = 0;
4243 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4245 else
4246 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4248 if (bufsize) {
4249 TRACE("size=%d\n", bufsize);
4250 safe_buffer_length_increment(pStubMsg, bufsize);
4252 else
4253 pStubMsg->BufferLength =
4254 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4255 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4257 if (saved_buffer_length)
4259 pStubMsg->PointerLength = pStubMsg->BufferLength;
4260 pStubMsg->BufferLength = saved_buffer_length;
4265 /***********************************************************************
4266 * NdrUserMarshalMemorySize [RPCRT4.@]
4268 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4269 PFORMAT_STRING pFormat)
4271 unsigned flags = pFormat[1];
4272 unsigned index = *(const WORD*)&pFormat[2];
4273 DWORD memsize = *(const WORD*)&pFormat[4];
4274 DWORD bufsize = *(const WORD*)&pFormat[6];
4276 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4277 TRACE("index=%d\n", index);
4279 pStubMsg->MemorySize += memsize;
4281 if (flags & USER_MARSHAL_POINTER)
4283 ALIGN_POINTER(pStubMsg->Buffer, 4);
4284 /* skip pointer prefix */
4285 pStubMsg->Buffer += 4;
4286 if (pStubMsg->IgnoreEmbeddedPointers)
4287 return pStubMsg->MemorySize;
4288 ALIGN_POINTER(pStubMsg->Buffer, 8);
4290 else
4291 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4293 if (!bufsize)
4294 FIXME("not implemented for varying buffer size\n");
4296 pStubMsg->Buffer += bufsize;
4298 return pStubMsg->MemorySize;
4301 /***********************************************************************
4302 * NdrUserMarshalFree [RPCRT4.@]
4304 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4305 unsigned char *pMemory,
4306 PFORMAT_STRING pFormat)
4308 /* unsigned flags = pFormat[1]; */
4309 unsigned index = *(const WORD*)&pFormat[2];
4310 USER_MARSHAL_CB umcb;
4312 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4313 TRACE("index=%d\n", index);
4315 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4317 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4318 &umcb.Flags, pMemory);
4321 /***********************************************************************
4322 * NdrClearOutParameters [RPCRT4.@]
4324 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4325 PFORMAT_STRING pFormat,
4326 void *ArgAddr)
4328 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4331 /***********************************************************************
4332 * NdrConvert [RPCRT4.@]
4334 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4336 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4337 /* FIXME: since this stub doesn't do any converting, the proper behavior
4338 is to raise an exception */
4341 /***********************************************************************
4342 * NdrConvert2 [RPCRT4.@]
4344 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4346 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4347 pStubMsg, pFormat, NumberParams);
4348 /* FIXME: since this stub doesn't do any converting, the proper behavior
4349 is to raise an exception */
4352 #include "pshpack1.h"
4353 typedef struct _NDR_CSTRUCT_FORMAT
4355 unsigned char type;
4356 unsigned char alignment;
4357 unsigned short memory_size;
4358 short offset_to_array_description;
4359 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4360 #include "poppack.h"
4362 /***********************************************************************
4363 * NdrConformantStructMarshall [RPCRT4.@]
4365 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4366 unsigned char *pMemory,
4367 PFORMAT_STRING pFormat)
4369 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4370 PFORMAT_STRING pCArrayFormat;
4371 ULONG esize, bufsize;
4373 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4375 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4376 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4378 ERR("invalid format type %x\n", pCStructFormat->type);
4379 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4380 return NULL;
4383 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4384 pCStructFormat->offset_to_array_description;
4385 if (*pCArrayFormat != RPC_FC_CARRAY)
4387 ERR("invalid array format type %x\n", pCStructFormat->type);
4388 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4389 return NULL;
4391 esize = *(const WORD*)(pCArrayFormat+2);
4393 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4394 pCArrayFormat + 4, 0);
4396 WriteConformance(pStubMsg);
4398 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4400 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4402 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4403 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4405 ERR("integer overflow of memory_size %u with bufsize %u\n",
4406 pCStructFormat->memory_size, bufsize);
4407 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4409 /* copy constant sized part of struct */
4410 pStubMsg->BufferMark = pStubMsg->Buffer;
4411 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4413 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4414 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4416 return NULL;
4419 /***********************************************************************
4420 * NdrConformantStructUnmarshall [RPCRT4.@]
4422 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4423 unsigned char **ppMemory,
4424 PFORMAT_STRING pFormat,
4425 unsigned char fMustAlloc)
4427 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4428 PFORMAT_STRING pCArrayFormat;
4429 ULONG esize, bufsize;
4430 unsigned char *saved_buffer;
4432 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4434 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4435 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4437 ERR("invalid format type %x\n", pCStructFormat->type);
4438 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4439 return NULL;
4441 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4442 pCStructFormat->offset_to_array_description;
4443 if (*pCArrayFormat != RPC_FC_CARRAY)
4445 ERR("invalid array format type %x\n", pCStructFormat->type);
4446 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4447 return NULL;
4449 esize = *(const WORD*)(pCArrayFormat+2);
4451 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4453 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4455 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4457 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4458 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4460 ERR("integer overflow of memory_size %u with bufsize %u\n",
4461 pCStructFormat->memory_size, bufsize);
4462 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4465 if (fMustAlloc)
4467 SIZE_T size = pCStructFormat->memory_size + bufsize;
4468 *ppMemory = NdrAllocate(pStubMsg, size);
4470 else
4472 if (!pStubMsg->IsClient && !*ppMemory)
4473 /* for servers, we just point straight into the RPC buffer */
4474 *ppMemory = pStubMsg->Buffer;
4477 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4478 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4479 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4480 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4482 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4483 if (*ppMemory != saved_buffer)
4484 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4486 return NULL;
4489 /***********************************************************************
4490 * NdrConformantStructBufferSize [RPCRT4.@]
4492 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4493 unsigned char *pMemory,
4494 PFORMAT_STRING pFormat)
4496 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4497 PFORMAT_STRING pCArrayFormat;
4498 ULONG esize;
4500 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4502 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4503 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4505 ERR("invalid format type %x\n", pCStructFormat->type);
4506 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4507 return;
4509 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4510 pCStructFormat->offset_to_array_description;
4511 if (*pCArrayFormat != RPC_FC_CARRAY)
4513 ERR("invalid array format type %x\n", pCStructFormat->type);
4514 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4515 return;
4517 esize = *(const WORD*)(pCArrayFormat+2);
4519 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4520 SizeConformance(pStubMsg);
4522 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4524 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4526 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4527 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4529 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4530 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4533 /***********************************************************************
4534 * NdrConformantStructMemorySize [RPCRT4.@]
4536 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4537 PFORMAT_STRING pFormat)
4539 FIXME("stub\n");
4540 return 0;
4543 /***********************************************************************
4544 * NdrConformantStructFree [RPCRT4.@]
4546 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4547 unsigned char *pMemory,
4548 PFORMAT_STRING pFormat)
4550 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4551 PFORMAT_STRING pCArrayFormat;
4553 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4555 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4556 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4558 ERR("invalid format type %x\n", pCStructFormat->type);
4559 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4560 return;
4563 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4564 pCStructFormat->offset_to_array_description;
4565 if (*pCArrayFormat != RPC_FC_CARRAY)
4567 ERR("invalid array format type %x\n", pCStructFormat->type);
4568 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4569 return;
4572 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4573 pCArrayFormat + 4, 0);
4575 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4577 /* copy constant sized part of struct */
4578 pStubMsg->BufferMark = pStubMsg->Buffer;
4580 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4581 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4584 /***********************************************************************
4585 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4587 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4588 unsigned char *pMemory,
4589 PFORMAT_STRING pFormat)
4591 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4592 PFORMAT_STRING pCVArrayFormat;
4594 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4596 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4597 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4599 ERR("invalid format type %x\n", pCVStructFormat->type);
4600 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4601 return NULL;
4604 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4605 pCVStructFormat->offset_to_array_description;
4607 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4608 pMemory + pCVStructFormat->memory_size,
4609 pCVArrayFormat);
4611 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4613 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4615 /* write constant sized part */
4616 pStubMsg->BufferMark = pStubMsg->Buffer;
4617 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4619 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4620 pMemory + pCVStructFormat->memory_size,
4621 pCVArrayFormat, FALSE /* fHasPointers */);
4623 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4625 return NULL;
4628 /***********************************************************************
4629 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4631 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4632 unsigned char **ppMemory,
4633 PFORMAT_STRING pFormat,
4634 unsigned char fMustAlloc)
4636 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4637 PFORMAT_STRING pCVArrayFormat;
4638 ULONG memsize, bufsize;
4639 unsigned char *saved_buffer, *saved_array_buffer;
4640 ULONG offset;
4641 unsigned char *array_memory;
4643 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4645 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4646 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4648 ERR("invalid format type %x\n", pCVStructFormat->type);
4649 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4650 return NULL;
4653 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4654 pCVStructFormat->offset_to_array_description;
4656 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4657 pCVArrayFormat);
4659 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4661 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4663 /* work out how much memory to allocate if we need to do so */
4664 if (!*ppMemory || fMustAlloc)
4666 SIZE_T size = pCVStructFormat->memory_size + memsize;
4667 *ppMemory = NdrAllocate(pStubMsg, size);
4670 /* mark the start of the constant data */
4671 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4672 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4674 array_memory = *ppMemory + pCVStructFormat->memory_size;
4675 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4676 &array_memory, pCVArrayFormat,
4677 FALSE /* fMustAlloc */,
4678 FALSE /* fUseServerBufferMemory */,
4679 FALSE /* fUnmarshall */);
4681 /* save offset in case unmarshalling pointers changes it */
4682 offset = pStubMsg->Offset;
4684 /* mark the start of the array data */
4685 saved_array_buffer = pStubMsg->Buffer;
4686 safe_buffer_increment(pStubMsg, bufsize);
4688 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4690 /* copy the constant data */
4691 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4692 /* copy the array data */
4693 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4694 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4695 saved_array_buffer, bufsize);
4697 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4698 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4699 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4700 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4702 return NULL;
4705 /***********************************************************************
4706 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4708 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4709 unsigned char *pMemory,
4710 PFORMAT_STRING pFormat)
4712 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4713 PFORMAT_STRING pCVArrayFormat;
4715 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4717 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4718 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4720 ERR("invalid format type %x\n", pCVStructFormat->type);
4721 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4722 return;
4725 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4726 pCVStructFormat->offset_to_array_description;
4727 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4728 pMemory + pCVStructFormat->memory_size,
4729 pCVArrayFormat);
4731 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4733 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4735 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4737 array_buffer_size(*pCVArrayFormat, pStubMsg,
4738 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4739 FALSE /* fHasPointers */);
4741 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4744 /***********************************************************************
4745 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4747 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4748 PFORMAT_STRING pFormat)
4750 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4751 PFORMAT_STRING pCVArrayFormat;
4753 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4755 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4756 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4758 ERR("invalid format type %x\n", pCVStructFormat->type);
4759 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4760 return 0;
4763 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4764 pCVStructFormat->offset_to_array_description;
4765 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4767 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4769 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4771 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4772 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4773 FALSE /* fHasPointers */);
4775 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4777 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4779 return pStubMsg->MemorySize;
4782 /***********************************************************************
4783 * NdrConformantVaryingStructFree [RPCRT4.@]
4785 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4786 unsigned char *pMemory,
4787 PFORMAT_STRING pFormat)
4789 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4790 PFORMAT_STRING pCVArrayFormat;
4792 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4794 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4795 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4797 ERR("invalid format type %x\n", pCVStructFormat->type);
4798 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4799 return;
4802 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4803 pCVStructFormat->offset_to_array_description;
4804 array_free(*pCVArrayFormat, pStubMsg,
4805 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4806 FALSE /* fHasPointers */);
4808 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4810 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4813 #include "pshpack1.h"
4814 typedef struct
4816 unsigned char type;
4817 unsigned char alignment;
4818 unsigned short total_size;
4819 } NDR_SMFARRAY_FORMAT;
4821 typedef struct
4823 unsigned char type;
4824 unsigned char alignment;
4825 unsigned long total_size;
4826 } NDR_LGFARRAY_FORMAT;
4827 #include "poppack.h"
4829 /***********************************************************************
4830 * NdrFixedArrayMarshall [RPCRT4.@]
4832 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4833 unsigned char *pMemory,
4834 PFORMAT_STRING pFormat)
4836 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4837 unsigned long total_size;
4839 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4841 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4842 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4844 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4845 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4846 return NULL;
4849 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4851 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4853 total_size = pSmFArrayFormat->total_size;
4854 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4856 else
4858 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4859 total_size = pLgFArrayFormat->total_size;
4860 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4863 pStubMsg->BufferMark = pStubMsg->Buffer;
4864 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4866 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4868 return NULL;
4871 /***********************************************************************
4872 * NdrFixedArrayUnmarshall [RPCRT4.@]
4874 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4875 unsigned char **ppMemory,
4876 PFORMAT_STRING pFormat,
4877 unsigned char fMustAlloc)
4879 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4880 unsigned long total_size;
4881 unsigned char *saved_buffer;
4883 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4885 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4886 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4888 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4889 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4890 return NULL;
4893 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4895 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4897 total_size = pSmFArrayFormat->total_size;
4898 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4900 else
4902 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4903 total_size = pLgFArrayFormat->total_size;
4904 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4907 if (fMustAlloc)
4908 *ppMemory = NdrAllocate(pStubMsg, total_size);
4909 else
4911 if (!pStubMsg->IsClient && !*ppMemory)
4912 /* for servers, we just point straight into the RPC buffer */
4913 *ppMemory = pStubMsg->Buffer;
4916 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4917 safe_buffer_increment(pStubMsg, total_size);
4918 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4920 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4921 if (*ppMemory != saved_buffer)
4922 memcpy(*ppMemory, saved_buffer, total_size);
4924 return NULL;
4927 /***********************************************************************
4928 * NdrFixedArrayBufferSize [RPCRT4.@]
4930 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4931 unsigned char *pMemory,
4932 PFORMAT_STRING pFormat)
4934 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4935 unsigned long total_size;
4937 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4939 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4940 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4942 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4943 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4944 return;
4947 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4949 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4951 total_size = pSmFArrayFormat->total_size;
4952 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4954 else
4956 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4957 total_size = pLgFArrayFormat->total_size;
4958 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4960 safe_buffer_length_increment(pStubMsg, total_size);
4962 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4965 /***********************************************************************
4966 * NdrFixedArrayMemorySize [RPCRT4.@]
4968 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4969 PFORMAT_STRING pFormat)
4971 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4972 ULONG total_size;
4974 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4976 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4977 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4979 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4980 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4981 return 0;
4984 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4986 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4988 total_size = pSmFArrayFormat->total_size;
4989 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4991 else
4993 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4994 total_size = pLgFArrayFormat->total_size;
4995 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4997 pStubMsg->BufferMark = pStubMsg->Buffer;
4998 safe_buffer_increment(pStubMsg, total_size);
4999 pStubMsg->MemorySize += total_size;
5001 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5003 return total_size;
5006 /***********************************************************************
5007 * NdrFixedArrayFree [RPCRT4.@]
5009 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5010 unsigned char *pMemory,
5011 PFORMAT_STRING pFormat)
5013 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5015 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5017 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5018 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5020 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5021 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5022 return;
5025 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5026 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5027 else
5029 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5030 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5033 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5036 /***********************************************************************
5037 * NdrVaryingArrayMarshall [RPCRT4.@]
5039 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5040 unsigned char *pMemory,
5041 PFORMAT_STRING pFormat)
5043 unsigned char alignment;
5044 DWORD elements, esize;
5045 ULONG bufsize;
5047 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5049 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5050 (pFormat[0] != RPC_FC_LGVARRAY))
5052 ERR("invalid format type %x\n", pFormat[0]);
5053 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5054 return NULL;
5057 alignment = pFormat[1] + 1;
5059 if (pFormat[0] == RPC_FC_SMVARRAY)
5061 pFormat += 2;
5062 pFormat += sizeof(WORD);
5063 elements = *(const WORD*)pFormat;
5064 pFormat += sizeof(WORD);
5066 else
5068 pFormat += 2;
5069 pFormat += sizeof(DWORD);
5070 elements = *(const DWORD*)pFormat;
5071 pFormat += sizeof(DWORD);
5074 esize = *(const WORD*)pFormat;
5075 pFormat += sizeof(WORD);
5077 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5078 if ((pStubMsg->ActualCount > elements) ||
5079 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5081 RpcRaiseException(RPC_S_INVALID_BOUND);
5082 return NULL;
5085 WriteVariance(pStubMsg);
5087 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5089 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5090 pStubMsg->BufferMark = pStubMsg->Buffer;
5091 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5093 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5095 return NULL;
5098 /***********************************************************************
5099 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5101 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5102 unsigned char **ppMemory,
5103 PFORMAT_STRING pFormat,
5104 unsigned char fMustAlloc)
5106 unsigned char alignment;
5107 DWORD size, elements, esize;
5108 ULONG bufsize;
5109 unsigned char *saved_buffer;
5110 ULONG offset;
5112 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5114 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5115 (pFormat[0] != RPC_FC_LGVARRAY))
5117 ERR("invalid format type %x\n", pFormat[0]);
5118 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5119 return NULL;
5122 alignment = pFormat[1] + 1;
5124 if (pFormat[0] == RPC_FC_SMVARRAY)
5126 pFormat += 2;
5127 size = *(const WORD*)pFormat;
5128 pFormat += sizeof(WORD);
5129 elements = *(const WORD*)pFormat;
5130 pFormat += sizeof(WORD);
5132 else
5134 pFormat += 2;
5135 size = *(const DWORD*)pFormat;
5136 pFormat += sizeof(DWORD);
5137 elements = *(const DWORD*)pFormat;
5138 pFormat += sizeof(DWORD);
5141 esize = *(const WORD*)pFormat;
5142 pFormat += sizeof(WORD);
5144 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5146 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5148 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5149 offset = pStubMsg->Offset;
5151 if (!*ppMemory || fMustAlloc)
5152 *ppMemory = NdrAllocate(pStubMsg, size);
5153 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5154 safe_buffer_increment(pStubMsg, bufsize);
5156 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5158 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5160 return NULL;
5163 /***********************************************************************
5164 * NdrVaryingArrayBufferSize [RPCRT4.@]
5166 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5167 unsigned char *pMemory,
5168 PFORMAT_STRING pFormat)
5170 unsigned char alignment;
5171 DWORD elements, esize;
5173 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5175 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5176 (pFormat[0] != RPC_FC_LGVARRAY))
5178 ERR("invalid format type %x\n", pFormat[0]);
5179 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5180 return;
5183 alignment = pFormat[1] + 1;
5185 if (pFormat[0] == RPC_FC_SMVARRAY)
5187 pFormat += 2;
5188 pFormat += sizeof(WORD);
5189 elements = *(const WORD*)pFormat;
5190 pFormat += sizeof(WORD);
5192 else
5194 pFormat += 2;
5195 pFormat += sizeof(DWORD);
5196 elements = *(const DWORD*)pFormat;
5197 pFormat += sizeof(DWORD);
5200 esize = *(const WORD*)pFormat;
5201 pFormat += sizeof(WORD);
5203 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5204 if ((pStubMsg->ActualCount > elements) ||
5205 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5207 RpcRaiseException(RPC_S_INVALID_BOUND);
5208 return;
5211 SizeVariance(pStubMsg);
5213 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5215 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5217 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5220 /***********************************************************************
5221 * NdrVaryingArrayMemorySize [RPCRT4.@]
5223 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5224 PFORMAT_STRING pFormat)
5226 unsigned char alignment;
5227 DWORD size, elements, esize;
5229 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5231 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5232 (pFormat[0] != RPC_FC_LGVARRAY))
5234 ERR("invalid format type %x\n", pFormat[0]);
5235 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5236 return 0;
5239 alignment = pFormat[1] + 1;
5241 if (pFormat[0] == RPC_FC_SMVARRAY)
5243 pFormat += 2;
5244 size = *(const WORD*)pFormat;
5245 pFormat += sizeof(WORD);
5246 elements = *(const WORD*)pFormat;
5247 pFormat += sizeof(WORD);
5249 else
5251 pFormat += 2;
5252 size = *(const DWORD*)pFormat;
5253 pFormat += sizeof(DWORD);
5254 elements = *(const DWORD*)pFormat;
5255 pFormat += sizeof(DWORD);
5258 esize = *(const WORD*)pFormat;
5259 pFormat += sizeof(WORD);
5261 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5263 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5265 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5266 pStubMsg->MemorySize += size;
5268 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5270 return pStubMsg->MemorySize;
5273 /***********************************************************************
5274 * NdrVaryingArrayFree [RPCRT4.@]
5276 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5277 unsigned char *pMemory,
5278 PFORMAT_STRING pFormat)
5280 DWORD elements;
5282 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5284 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5285 (pFormat[0] != RPC_FC_LGVARRAY))
5287 ERR("invalid format type %x\n", pFormat[0]);
5288 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5289 return;
5292 if (pFormat[0] == RPC_FC_SMVARRAY)
5294 pFormat += 2;
5295 pFormat += sizeof(WORD);
5296 elements = *(const WORD*)pFormat;
5297 pFormat += sizeof(WORD);
5299 else
5301 pFormat += 2;
5302 pFormat += sizeof(DWORD);
5303 elements = *(const DWORD*)pFormat;
5304 pFormat += sizeof(DWORD);
5307 pFormat += sizeof(WORD);
5309 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5310 if ((pStubMsg->ActualCount > elements) ||
5311 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5313 RpcRaiseException(RPC_S_INVALID_BOUND);
5314 return;
5317 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5320 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5322 switch (fc)
5324 case RPC_FC_BYTE:
5325 case RPC_FC_CHAR:
5326 case RPC_FC_SMALL:
5327 case RPC_FC_USMALL:
5328 return *pMemory;
5329 case RPC_FC_WCHAR:
5330 case RPC_FC_SHORT:
5331 case RPC_FC_USHORT:
5332 case RPC_FC_ENUM16:
5333 return *(const USHORT *)pMemory;
5334 case RPC_FC_LONG:
5335 case RPC_FC_ULONG:
5336 case RPC_FC_ENUM32:
5337 return *(const ULONG *)pMemory;
5338 default:
5339 FIXME("Unhandled base type: 0x%02x\n", fc);
5340 return 0;
5344 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5345 unsigned long discriminant,
5346 PFORMAT_STRING pFormat)
5348 unsigned short num_arms, arm, type;
5350 num_arms = *(const SHORT*)pFormat & 0x0fff;
5351 pFormat += 2;
5352 for(arm = 0; arm < num_arms; arm++)
5354 if(discriminant == *(const ULONG*)pFormat)
5356 pFormat += 4;
5357 break;
5359 pFormat += 6;
5362 type = *(const unsigned short*)pFormat;
5363 TRACE("type %04x\n", type);
5364 if(arm == num_arms) /* default arm extras */
5366 if(type == 0xffff)
5368 ERR("no arm for 0x%lx and no default case\n", discriminant);
5369 RpcRaiseException(RPC_S_INVALID_TAG);
5370 return NULL;
5372 if(type == 0)
5374 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5375 return NULL;
5378 return pFormat;
5381 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5383 unsigned short type;
5385 pFormat += 2;
5387 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5388 if(!pFormat)
5389 return NULL;
5391 type = *(const unsigned short*)pFormat;
5392 if((type & 0xff00) == 0x8000)
5394 unsigned char basetype = LOBYTE(type);
5395 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5397 else
5399 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5400 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5401 if (m)
5403 unsigned char *saved_buffer = NULL;
5404 int pointer_buffer_mark_set = 0;
5405 switch(*desc)
5407 case RPC_FC_RP:
5408 case RPC_FC_UP:
5409 case RPC_FC_OP:
5410 case RPC_FC_FP:
5411 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5412 saved_buffer = pStubMsg->Buffer;
5413 if (pStubMsg->PointerBufferMark)
5415 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5416 pStubMsg->PointerBufferMark = NULL;
5417 pointer_buffer_mark_set = 1;
5419 else
5420 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5422 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5423 if (pointer_buffer_mark_set)
5425 STD_OVERFLOW_CHECK(pStubMsg);
5426 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5427 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5429 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5430 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5431 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5433 pStubMsg->Buffer = saved_buffer + 4;
5435 break;
5436 default:
5437 m(pStubMsg, pMemory, desc);
5440 else FIXME("no marshaller for embedded type %02x\n", *desc);
5442 return NULL;
5445 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5446 unsigned char **ppMemory,
5447 ULONG discriminant,
5448 PFORMAT_STRING pFormat,
5449 unsigned char fMustAlloc)
5451 unsigned short type;
5453 pFormat += 2;
5455 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5456 if(!pFormat)
5457 return NULL;
5459 type = *(const unsigned short*)pFormat;
5460 if((type & 0xff00) == 0x8000)
5462 unsigned char basetype = LOBYTE(type);
5463 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5465 else
5467 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5468 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5469 if (m)
5471 unsigned char *saved_buffer = NULL;
5472 int pointer_buffer_mark_set = 0;
5473 switch(*desc)
5475 case RPC_FC_RP:
5476 case RPC_FC_UP:
5477 case RPC_FC_OP:
5478 case RPC_FC_FP:
5479 **(void***)ppMemory = NULL;
5480 ALIGN_POINTER(pStubMsg->Buffer, 4);
5481 saved_buffer = pStubMsg->Buffer;
5482 if (pStubMsg->PointerBufferMark)
5484 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5485 pStubMsg->PointerBufferMark = NULL;
5486 pointer_buffer_mark_set = 1;
5488 else
5489 pStubMsg->Buffer += 4; /* for pointer ID */
5491 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5493 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5494 saved_buffer, pStubMsg->BufferEnd);
5495 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5498 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5499 if (pointer_buffer_mark_set)
5501 STD_OVERFLOW_CHECK(pStubMsg);
5502 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5503 pStubMsg->Buffer = saved_buffer + 4;
5505 break;
5506 default:
5507 m(pStubMsg, ppMemory, desc, fMustAlloc);
5510 else FIXME("no marshaller for embedded type %02x\n", *desc);
5512 return NULL;
5515 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5516 unsigned char *pMemory,
5517 ULONG discriminant,
5518 PFORMAT_STRING pFormat)
5520 unsigned short type;
5522 pFormat += 2;
5524 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5525 if(!pFormat)
5526 return;
5528 type = *(const unsigned short*)pFormat;
5529 if((type & 0xff00) == 0x8000)
5531 unsigned char basetype = LOBYTE(type);
5532 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5534 else
5536 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5537 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5538 if (m)
5540 switch(*desc)
5542 case RPC_FC_RP:
5543 case RPC_FC_UP:
5544 case RPC_FC_OP:
5545 case RPC_FC_FP:
5546 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5547 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5548 if (!pStubMsg->IgnoreEmbeddedPointers)
5550 int saved_buffer_length = pStubMsg->BufferLength;
5551 pStubMsg->BufferLength = pStubMsg->PointerLength;
5552 pStubMsg->PointerLength = 0;
5553 if(!pStubMsg->BufferLength)
5554 ERR("BufferLength == 0??\n");
5555 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5556 pStubMsg->PointerLength = pStubMsg->BufferLength;
5557 pStubMsg->BufferLength = saved_buffer_length;
5559 break;
5560 default:
5561 m(pStubMsg, pMemory, desc);
5564 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5568 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5569 ULONG discriminant,
5570 PFORMAT_STRING pFormat)
5572 unsigned short type, size;
5574 size = *(const unsigned short*)pFormat;
5575 pStubMsg->Memory += size;
5576 pFormat += 2;
5578 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5579 if(!pFormat)
5580 return 0;
5582 type = *(const unsigned short*)pFormat;
5583 if((type & 0xff00) == 0x8000)
5585 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5587 else
5589 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5590 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5591 unsigned char *saved_buffer;
5592 if (m)
5594 switch(*desc)
5596 case RPC_FC_RP:
5597 case RPC_FC_UP:
5598 case RPC_FC_OP:
5599 case RPC_FC_FP:
5600 ALIGN_POINTER(pStubMsg->Buffer, 4);
5601 saved_buffer = pStubMsg->Buffer;
5602 safe_buffer_increment(pStubMsg, 4);
5603 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5604 pStubMsg->MemorySize += 4;
5605 if (!pStubMsg->IgnoreEmbeddedPointers)
5606 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5607 break;
5608 default:
5609 return m(pStubMsg, desc);
5612 else FIXME("no marshaller for embedded type %02x\n", *desc);
5615 TRACE("size %d\n", size);
5616 return size;
5619 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5620 unsigned char *pMemory,
5621 ULONG discriminant,
5622 PFORMAT_STRING pFormat)
5624 unsigned short type;
5626 pFormat += 2;
5628 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5629 if(!pFormat)
5630 return;
5632 type = *(const unsigned short*)pFormat;
5633 if((type & 0xff00) != 0x8000)
5635 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5636 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5637 if (m)
5639 switch(*desc)
5641 case RPC_FC_RP:
5642 case RPC_FC_UP:
5643 case RPC_FC_OP:
5644 case RPC_FC_FP:
5645 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5646 break;
5647 default:
5648 m(pStubMsg, pMemory, desc);
5654 /***********************************************************************
5655 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5657 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5658 unsigned char *pMemory,
5659 PFORMAT_STRING pFormat)
5661 unsigned char switch_type;
5662 unsigned char increment;
5663 ULONG switch_value;
5665 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5666 pFormat++;
5668 switch_type = *pFormat & 0xf;
5669 increment = (*pFormat & 0xf0) >> 4;
5670 pFormat++;
5672 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5674 switch_value = get_discriminant(switch_type, pMemory);
5675 TRACE("got switch value 0x%x\n", switch_value);
5677 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5678 pMemory += increment;
5680 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5683 /***********************************************************************
5684 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5686 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5687 unsigned char **ppMemory,
5688 PFORMAT_STRING pFormat,
5689 unsigned char fMustAlloc)
5691 unsigned char switch_type;
5692 unsigned char increment;
5693 ULONG switch_value;
5694 unsigned short size;
5695 unsigned char *pMemoryArm;
5697 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5698 pFormat++;
5700 switch_type = *pFormat & 0xf;
5701 increment = (*pFormat & 0xf0) >> 4;
5702 pFormat++;
5704 ALIGN_POINTER(pStubMsg->Buffer, increment);
5705 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5706 TRACE("got switch value 0x%x\n", switch_value);
5708 size = *(const unsigned short*)pFormat + increment;
5709 if(!*ppMemory || fMustAlloc)
5710 *ppMemory = NdrAllocate(pStubMsg, size);
5712 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5713 pMemoryArm = *ppMemory + increment;
5715 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5718 /***********************************************************************
5719 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5721 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5722 unsigned char *pMemory,
5723 PFORMAT_STRING pFormat)
5725 unsigned char switch_type;
5726 unsigned char increment;
5727 ULONG switch_value;
5729 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5730 pFormat++;
5732 switch_type = *pFormat & 0xf;
5733 increment = (*pFormat & 0xf0) >> 4;
5734 pFormat++;
5736 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5737 switch_value = get_discriminant(switch_type, pMemory);
5738 TRACE("got switch value 0x%x\n", switch_value);
5740 /* Add discriminant size */
5741 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5742 pMemory += increment;
5744 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5747 /***********************************************************************
5748 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5750 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5751 PFORMAT_STRING pFormat)
5753 unsigned char switch_type;
5754 unsigned char increment;
5755 ULONG switch_value;
5757 switch_type = *pFormat & 0xf;
5758 increment = (*pFormat & 0xf0) >> 4;
5759 pFormat++;
5761 ALIGN_POINTER(pStubMsg->Buffer, increment);
5762 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5763 TRACE("got switch value 0x%x\n", switch_value);
5765 pStubMsg->Memory += increment;
5767 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5770 /***********************************************************************
5771 * NdrEncapsulatedUnionFree [RPCRT4.@]
5773 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5774 unsigned char *pMemory,
5775 PFORMAT_STRING pFormat)
5777 unsigned char switch_type;
5778 unsigned char increment;
5779 ULONG switch_value;
5781 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5782 pFormat++;
5784 switch_type = *pFormat & 0xf;
5785 increment = (*pFormat & 0xf0) >> 4;
5786 pFormat++;
5788 switch_value = get_discriminant(switch_type, pMemory);
5789 TRACE("got switch value 0x%x\n", switch_value);
5791 pMemory += increment;
5793 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5796 /***********************************************************************
5797 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5799 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5800 unsigned char *pMemory,
5801 PFORMAT_STRING pFormat)
5803 unsigned char switch_type;
5805 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5806 pFormat++;
5808 switch_type = *pFormat;
5809 pFormat++;
5811 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5812 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5813 /* Marshall discriminant */
5814 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5816 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5819 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5820 PFORMAT_STRING *ppFormat)
5822 long discriminant = 0;
5824 switch(**ppFormat)
5826 case RPC_FC_BYTE:
5827 case RPC_FC_CHAR:
5828 case RPC_FC_SMALL:
5829 case RPC_FC_USMALL:
5831 UCHAR d;
5832 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5833 discriminant = d;
5834 break;
5836 case RPC_FC_WCHAR:
5837 case RPC_FC_SHORT:
5838 case RPC_FC_USHORT:
5840 USHORT d;
5841 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5842 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5843 discriminant = d;
5844 break;
5846 case RPC_FC_LONG:
5847 case RPC_FC_ULONG:
5849 ULONG d;
5850 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5851 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5852 discriminant = d;
5853 break;
5855 default:
5856 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5858 (*ppFormat)++;
5860 if (pStubMsg->fHasNewCorrDesc)
5861 *ppFormat += 6;
5862 else
5863 *ppFormat += 4;
5864 return discriminant;
5867 /**********************************************************************
5868 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5870 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5871 unsigned char **ppMemory,
5872 PFORMAT_STRING pFormat,
5873 unsigned char fMustAlloc)
5875 long discriminant;
5876 unsigned short size;
5878 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5879 pFormat++;
5881 /* Unmarshall discriminant */
5882 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5883 TRACE("unmarshalled discriminant %lx\n", discriminant);
5885 pFormat += *(const SHORT*)pFormat;
5887 size = *(const unsigned short*)pFormat;
5889 if(!*ppMemory || fMustAlloc)
5890 *ppMemory = NdrAllocate(pStubMsg, size);
5892 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5895 /***********************************************************************
5896 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5898 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5899 unsigned char *pMemory,
5900 PFORMAT_STRING pFormat)
5902 unsigned char switch_type;
5904 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5905 pFormat++;
5907 switch_type = *pFormat;
5908 pFormat++;
5910 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5911 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5912 /* Add discriminant size */
5913 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5915 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5918 /***********************************************************************
5919 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5921 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5922 PFORMAT_STRING pFormat)
5924 ULONG discriminant;
5926 pFormat++;
5927 /* Unmarshall discriminant */
5928 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5929 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5931 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5934 /***********************************************************************
5935 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5937 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5938 unsigned char *pMemory,
5939 PFORMAT_STRING pFormat)
5941 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5942 pFormat++;
5943 pFormat++;
5945 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5946 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5948 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5951 /***********************************************************************
5952 * NdrByteCountPointerMarshall [RPCRT4.@]
5954 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5955 unsigned char *pMemory,
5956 PFORMAT_STRING pFormat)
5958 FIXME("stub\n");
5959 return NULL;
5962 /***********************************************************************
5963 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5965 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5966 unsigned char **ppMemory,
5967 PFORMAT_STRING pFormat,
5968 unsigned char fMustAlloc)
5970 FIXME("stub\n");
5971 return NULL;
5974 /***********************************************************************
5975 * NdrByteCountPointerBufferSize [RPCRT4.@]
5977 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5978 unsigned char *pMemory,
5979 PFORMAT_STRING pFormat)
5981 FIXME("stub\n");
5984 /***********************************************************************
5985 * NdrByteCountPointerMemorySize [RPCRT4.@]
5987 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5988 PFORMAT_STRING pFormat)
5990 FIXME("stub\n");
5991 return 0;
5994 /***********************************************************************
5995 * NdrByteCountPointerFree [RPCRT4.@]
5997 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5998 unsigned char *pMemory,
5999 PFORMAT_STRING pFormat)
6001 FIXME("stub\n");
6004 /***********************************************************************
6005 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6007 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6008 unsigned char *pMemory,
6009 PFORMAT_STRING pFormat)
6011 FIXME("stub\n");
6012 return NULL;
6015 /***********************************************************************
6016 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6018 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6019 unsigned char **ppMemory,
6020 PFORMAT_STRING pFormat,
6021 unsigned char fMustAlloc)
6023 FIXME("stub\n");
6024 return NULL;
6027 /***********************************************************************
6028 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6030 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6031 unsigned char *pMemory,
6032 PFORMAT_STRING pFormat)
6034 FIXME("stub\n");
6037 /***********************************************************************
6038 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6040 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6041 PFORMAT_STRING pFormat)
6043 FIXME("stub\n");
6044 return 0;
6047 /***********************************************************************
6048 * NdrXmitOrRepAsFree [RPCRT4.@]
6050 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6051 unsigned char *pMemory,
6052 PFORMAT_STRING pFormat)
6054 FIXME("stub\n");
6057 /***********************************************************************
6058 * NdrRangeMarshall [internal]
6060 unsigned char *WINAPI NdrRangeMarshall(
6061 PMIDL_STUB_MESSAGE pStubMsg,
6062 unsigned char *pMemory,
6063 PFORMAT_STRING pFormat)
6065 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6066 unsigned char base_type;
6068 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6070 if (pRange->type != RPC_FC_RANGE)
6072 ERR("invalid format type %x\n", pRange->type);
6073 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6074 return NULL;
6077 base_type = pRange->flags_type & 0xf;
6079 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6082 /***********************************************************************
6083 * NdrRangeUnmarshall
6085 unsigned char *WINAPI NdrRangeUnmarshall(
6086 PMIDL_STUB_MESSAGE pStubMsg,
6087 unsigned char **ppMemory,
6088 PFORMAT_STRING pFormat,
6089 unsigned char fMustAlloc)
6091 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6092 unsigned char base_type;
6094 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6096 if (pRange->type != RPC_FC_RANGE)
6098 ERR("invalid format type %x\n", pRange->type);
6099 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6100 return NULL;
6102 base_type = pRange->flags_type & 0xf;
6104 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6105 base_type, pRange->low_value, pRange->high_value);
6107 #define RANGE_UNMARSHALL(type, format_spec) \
6108 do \
6110 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6111 if (fMustAlloc || !*ppMemory) \
6112 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6113 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
6115 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6116 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6117 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6119 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
6120 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
6122 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6123 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
6124 (type)pRange->high_value); \
6125 RpcRaiseException(RPC_S_INVALID_BOUND); \
6126 return NULL; \
6128 TRACE("*ppMemory: %p\n", *ppMemory); \
6129 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6130 pStubMsg->Buffer += sizeof(type); \
6131 } while (0)
6133 switch(base_type)
6135 case RPC_FC_CHAR:
6136 case RPC_FC_SMALL:
6137 RANGE_UNMARSHALL(UCHAR, "%d");
6138 TRACE("value: 0x%02x\n", **ppMemory);
6139 break;
6140 case RPC_FC_BYTE:
6141 case RPC_FC_USMALL:
6142 RANGE_UNMARSHALL(CHAR, "%u");
6143 TRACE("value: 0x%02x\n", **ppMemory);
6144 break;
6145 case RPC_FC_WCHAR: /* FIXME: valid? */
6146 case RPC_FC_USHORT:
6147 RANGE_UNMARSHALL(USHORT, "%u");
6148 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6149 break;
6150 case RPC_FC_SHORT:
6151 RANGE_UNMARSHALL(SHORT, "%d");
6152 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6153 break;
6154 case RPC_FC_LONG:
6155 RANGE_UNMARSHALL(LONG, "%d");
6156 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6157 break;
6158 case RPC_FC_ULONG:
6159 RANGE_UNMARSHALL(ULONG, "%u");
6160 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6161 break;
6162 case RPC_FC_ENUM16:
6163 case RPC_FC_ENUM32:
6164 FIXME("Unhandled enum type\n");
6165 break;
6166 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
6167 case RPC_FC_FLOAT:
6168 case RPC_FC_DOUBLE:
6169 case RPC_FC_HYPER:
6170 default:
6171 ERR("invalid range base type: 0x%02x\n", base_type);
6172 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6175 return NULL;
6178 /***********************************************************************
6179 * NdrRangeBufferSize [internal]
6181 void WINAPI NdrRangeBufferSize(
6182 PMIDL_STUB_MESSAGE pStubMsg,
6183 unsigned char *pMemory,
6184 PFORMAT_STRING pFormat)
6186 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6187 unsigned char base_type;
6189 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6191 if (pRange->type != RPC_FC_RANGE)
6193 ERR("invalid format type %x\n", pRange->type);
6194 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6196 base_type = pRange->flags_type & 0xf;
6198 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6201 /***********************************************************************
6202 * NdrRangeMemorySize [internal]
6204 ULONG WINAPI NdrRangeMemorySize(
6205 PMIDL_STUB_MESSAGE pStubMsg,
6206 PFORMAT_STRING pFormat)
6208 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6209 unsigned char base_type;
6211 if (pRange->type != RPC_FC_RANGE)
6213 ERR("invalid format type %x\n", pRange->type);
6214 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6215 return 0;
6217 base_type = pRange->flags_type & 0xf;
6219 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6222 /***********************************************************************
6223 * NdrRangeFree [internal]
6225 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6226 unsigned char *pMemory,
6227 PFORMAT_STRING pFormat)
6229 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6231 /* nothing to do */
6234 /***********************************************************************
6235 * NdrBaseTypeMarshall [internal]
6237 static unsigned char *WINAPI NdrBaseTypeMarshall(
6238 PMIDL_STUB_MESSAGE pStubMsg,
6239 unsigned char *pMemory,
6240 PFORMAT_STRING pFormat)
6242 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6244 switch(*pFormat)
6246 case RPC_FC_BYTE:
6247 case RPC_FC_CHAR:
6248 case RPC_FC_SMALL:
6249 case RPC_FC_USMALL:
6250 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6251 TRACE("value: 0x%02x\n", *pMemory);
6252 break;
6253 case RPC_FC_WCHAR:
6254 case RPC_FC_SHORT:
6255 case RPC_FC_USHORT:
6256 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6257 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6258 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6259 break;
6260 case RPC_FC_LONG:
6261 case RPC_FC_ULONG:
6262 case RPC_FC_ERROR_STATUS_T:
6263 case RPC_FC_ENUM32:
6264 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6265 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6266 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6267 break;
6268 case RPC_FC_FLOAT:
6269 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6270 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6271 break;
6272 case RPC_FC_DOUBLE:
6273 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6274 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6275 break;
6276 case RPC_FC_HYPER:
6277 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6278 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6279 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6280 break;
6281 case RPC_FC_ENUM16:
6282 /* only 16-bits on the wire, so do a sanity check */
6283 if (*(UINT *)pMemory > SHRT_MAX)
6284 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6285 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6286 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6287 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6288 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6289 pStubMsg->Buffer += sizeof(USHORT);
6290 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6291 break;
6292 case RPC_FC_IGNORE:
6293 break;
6294 default:
6295 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6298 /* FIXME: what is the correct return value? */
6299 return NULL;
6302 /***********************************************************************
6303 * NdrBaseTypeUnmarshall [internal]
6305 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6306 PMIDL_STUB_MESSAGE pStubMsg,
6307 unsigned char **ppMemory,
6308 PFORMAT_STRING pFormat,
6309 unsigned char fMustAlloc)
6311 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6313 #define BASE_TYPE_UNMARSHALL(type) \
6314 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6315 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6317 *ppMemory = pStubMsg->Buffer; \
6318 TRACE("*ppMemory: %p\n", *ppMemory); \
6319 safe_buffer_increment(pStubMsg, sizeof(type)); \
6321 else \
6323 if (fMustAlloc) \
6324 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6325 TRACE("*ppMemory: %p\n", *ppMemory); \
6326 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6329 switch(*pFormat)
6331 case RPC_FC_BYTE:
6332 case RPC_FC_CHAR:
6333 case RPC_FC_SMALL:
6334 case RPC_FC_USMALL:
6335 BASE_TYPE_UNMARSHALL(UCHAR);
6336 TRACE("value: 0x%02x\n", **ppMemory);
6337 break;
6338 case RPC_FC_WCHAR:
6339 case RPC_FC_SHORT:
6340 case RPC_FC_USHORT:
6341 BASE_TYPE_UNMARSHALL(USHORT);
6342 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6343 break;
6344 case RPC_FC_LONG:
6345 case RPC_FC_ULONG:
6346 case RPC_FC_ERROR_STATUS_T:
6347 case RPC_FC_ENUM32:
6348 BASE_TYPE_UNMARSHALL(ULONG);
6349 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6350 break;
6351 case RPC_FC_FLOAT:
6352 BASE_TYPE_UNMARSHALL(float);
6353 TRACE("value: %f\n", **(float **)ppMemory);
6354 break;
6355 case RPC_FC_DOUBLE:
6356 BASE_TYPE_UNMARSHALL(double);
6357 TRACE("value: %f\n", **(double **)ppMemory);
6358 break;
6359 case RPC_FC_HYPER:
6360 BASE_TYPE_UNMARSHALL(ULONGLONG);
6361 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6362 break;
6363 case RPC_FC_ENUM16:
6364 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6365 if (fMustAlloc || !*ppMemory)
6366 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6367 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6368 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6369 TRACE("*ppMemory: %p\n", *ppMemory);
6370 /* 16-bits on the wire, but int in memory */
6371 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6372 pStubMsg->Buffer += sizeof(USHORT);
6373 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6374 break;
6375 case RPC_FC_IGNORE:
6376 break;
6377 default:
6378 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6380 #undef BASE_TYPE_UNMARSHALL
6382 /* FIXME: what is the correct return value? */
6384 return NULL;
6387 /***********************************************************************
6388 * NdrBaseTypeBufferSize [internal]
6390 static void WINAPI NdrBaseTypeBufferSize(
6391 PMIDL_STUB_MESSAGE pStubMsg,
6392 unsigned char *pMemory,
6393 PFORMAT_STRING pFormat)
6395 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6397 switch(*pFormat)
6399 case RPC_FC_BYTE:
6400 case RPC_FC_CHAR:
6401 case RPC_FC_SMALL:
6402 case RPC_FC_USMALL:
6403 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6404 break;
6405 case RPC_FC_WCHAR:
6406 case RPC_FC_SHORT:
6407 case RPC_FC_USHORT:
6408 case RPC_FC_ENUM16:
6409 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6410 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6411 break;
6412 case RPC_FC_LONG:
6413 case RPC_FC_ULONG:
6414 case RPC_FC_ENUM32:
6415 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6416 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6417 break;
6418 case RPC_FC_FLOAT:
6419 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6420 safe_buffer_length_increment(pStubMsg, sizeof(float));
6421 break;
6422 case RPC_FC_DOUBLE:
6423 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6424 safe_buffer_length_increment(pStubMsg, sizeof(double));
6425 break;
6426 case RPC_FC_HYPER:
6427 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6428 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6429 break;
6430 case RPC_FC_ERROR_STATUS_T:
6431 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6432 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6433 break;
6434 case RPC_FC_IGNORE:
6435 break;
6436 default:
6437 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6441 /***********************************************************************
6442 * NdrBaseTypeMemorySize [internal]
6444 static ULONG WINAPI NdrBaseTypeMemorySize(
6445 PMIDL_STUB_MESSAGE pStubMsg,
6446 PFORMAT_STRING pFormat)
6448 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6450 switch(*pFormat)
6452 case RPC_FC_BYTE:
6453 case RPC_FC_CHAR:
6454 case RPC_FC_SMALL:
6455 case RPC_FC_USMALL:
6456 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6457 pStubMsg->MemorySize += sizeof(UCHAR);
6458 return sizeof(UCHAR);
6459 case RPC_FC_WCHAR:
6460 case RPC_FC_SHORT:
6461 case RPC_FC_USHORT:
6462 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6463 pStubMsg->MemorySize += sizeof(USHORT);
6464 return sizeof(USHORT);
6465 case RPC_FC_LONG:
6466 case RPC_FC_ULONG:
6467 case RPC_FC_ENUM32:
6468 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6469 pStubMsg->MemorySize += sizeof(ULONG);
6470 return sizeof(ULONG);
6471 case RPC_FC_FLOAT:
6472 safe_buffer_increment(pStubMsg, sizeof(float));
6473 pStubMsg->MemorySize += sizeof(float);
6474 return sizeof(float);
6475 case RPC_FC_DOUBLE:
6476 safe_buffer_increment(pStubMsg, sizeof(double));
6477 pStubMsg->MemorySize += sizeof(double);
6478 return sizeof(double);
6479 case RPC_FC_HYPER:
6480 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6481 pStubMsg->MemorySize += sizeof(ULONGLONG);
6482 return sizeof(ULONGLONG);
6483 case RPC_FC_ERROR_STATUS_T:
6484 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6485 pStubMsg->MemorySize += sizeof(error_status_t);
6486 return sizeof(error_status_t);
6487 case RPC_FC_ENUM16:
6488 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6489 pStubMsg->MemorySize += sizeof(UINT);
6490 return sizeof(UINT);
6491 case RPC_FC_IGNORE:
6492 pStubMsg->MemorySize += sizeof(void *);
6493 return sizeof(void *);
6494 default:
6495 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6496 return 0;
6500 /***********************************************************************
6501 * NdrBaseTypeFree [internal]
6503 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6504 unsigned char *pMemory,
6505 PFORMAT_STRING pFormat)
6507 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6509 /* nothing to do */
6512 /***********************************************************************
6513 * NdrContextHandleBufferSize [internal]
6515 static void WINAPI NdrContextHandleBufferSize(
6516 PMIDL_STUB_MESSAGE pStubMsg,
6517 unsigned char *pMemory,
6518 PFORMAT_STRING pFormat)
6520 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6522 if (*pFormat != RPC_FC_BIND_CONTEXT)
6524 ERR("invalid format type %x\n", *pFormat);
6525 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6527 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6528 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6531 /***********************************************************************
6532 * NdrContextHandleMarshall [internal]
6534 static unsigned char *WINAPI NdrContextHandleMarshall(
6535 PMIDL_STUB_MESSAGE pStubMsg,
6536 unsigned char *pMemory,
6537 PFORMAT_STRING pFormat)
6539 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6541 if (*pFormat != RPC_FC_BIND_CONTEXT)
6543 ERR("invalid format type %x\n", *pFormat);
6544 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6546 TRACE("flags: 0x%02x\n", pFormat[1]);
6548 if (pFormat[1] & 0x80)
6549 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6550 else
6551 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6553 return NULL;
6556 /***********************************************************************
6557 * NdrContextHandleUnmarshall [internal]
6559 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6560 PMIDL_STUB_MESSAGE pStubMsg,
6561 unsigned char **ppMemory,
6562 PFORMAT_STRING pFormat,
6563 unsigned char fMustAlloc)
6565 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6566 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6568 if (*pFormat != RPC_FC_BIND_CONTEXT)
6570 ERR("invalid format type %x\n", *pFormat);
6571 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6573 TRACE("flags: 0x%02x\n", pFormat[1]);
6575 /* [out]-only or [ret] param */
6576 if ((pFormat[1] & 0x60) == 0x20)
6577 **(NDR_CCONTEXT **)ppMemory = NULL;
6578 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6580 return NULL;
6583 /***********************************************************************
6584 * NdrClientContextMarshall [RPCRT4.@]
6586 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6587 NDR_CCONTEXT ContextHandle,
6588 int fCheck)
6590 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6592 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6594 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6596 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6597 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6598 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6601 /* FIXME: what does fCheck do? */
6602 NDRCContextMarshall(ContextHandle,
6603 pStubMsg->Buffer);
6605 pStubMsg->Buffer += cbNDRContext;
6608 /***********************************************************************
6609 * NdrClientContextUnmarshall [RPCRT4.@]
6611 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6612 NDR_CCONTEXT * pContextHandle,
6613 RPC_BINDING_HANDLE BindHandle)
6615 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6617 ALIGN_POINTER(pStubMsg->Buffer, 4);
6619 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6620 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6622 NDRCContextUnmarshall(pContextHandle,
6623 BindHandle,
6624 pStubMsg->Buffer,
6625 pStubMsg->RpcMsg->DataRepresentation);
6627 pStubMsg->Buffer += cbNDRContext;
6630 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6631 NDR_SCONTEXT ContextHandle,
6632 NDR_RUNDOWN RundownRoutine )
6634 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6636 ALIGN_POINTER(pStubMsg->Buffer, 4);
6638 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6640 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6641 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6642 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6645 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6646 pStubMsg->Buffer, RundownRoutine, NULL,
6647 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6648 pStubMsg->Buffer += cbNDRContext;
6651 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6653 NDR_SCONTEXT ContextHandle;
6655 TRACE("(%p)\n", pStubMsg);
6657 ALIGN_POINTER(pStubMsg->Buffer, 4);
6659 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6661 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6662 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6663 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6666 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6667 pStubMsg->Buffer,
6668 pStubMsg->RpcMsg->DataRepresentation,
6669 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6670 pStubMsg->Buffer += cbNDRContext;
6672 return ContextHandle;
6675 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6676 unsigned char* pMemory,
6677 PFORMAT_STRING pFormat)
6679 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6682 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6683 PFORMAT_STRING pFormat)
6685 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6686 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6688 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6690 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6691 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6692 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6693 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6694 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6696 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6697 if_id = &sif->InterfaceId;
6700 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6701 pStubMsg->RpcMsg->DataRepresentation, if_id,
6702 flags);
6705 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6706 NDR_SCONTEXT ContextHandle,
6707 NDR_RUNDOWN RundownRoutine,
6708 PFORMAT_STRING pFormat)
6710 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6711 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6713 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6715 ALIGN_POINTER(pStubMsg->Buffer, 4);
6717 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6719 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6720 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6721 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6724 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6725 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6726 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6727 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6728 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6730 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6731 if_id = &sif->InterfaceId;
6734 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6735 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6736 pStubMsg->Buffer += cbNDRContext;
6739 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6740 PFORMAT_STRING pFormat)
6742 NDR_SCONTEXT ContextHandle;
6743 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6744 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6746 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6748 ALIGN_POINTER(pStubMsg->Buffer, 4);
6750 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6752 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6753 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6754 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6757 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6758 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6759 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6760 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6761 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6763 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6764 if_id = &sif->InterfaceId;
6767 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6768 pStubMsg->Buffer,
6769 pStubMsg->RpcMsg->DataRepresentation,
6770 if_id, flags);
6771 pStubMsg->Buffer += cbNDRContext;
6773 return ContextHandle;
6776 /***********************************************************************
6777 * NdrCorrelationInitialize [RPCRT4.@]
6779 * Initializes correlation validity checking.
6781 * PARAMS
6782 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6783 * pMemory [I] Pointer to memory to use as a cache.
6784 * CacheSize [I] Size of the memory pointed to by pMemory.
6785 * Flags [I] Reserved. Set to zero.
6787 * RETURNS
6788 * Nothing.
6790 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6792 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6793 pStubMsg->fHasNewCorrDesc = TRUE;
6796 /***********************************************************************
6797 * NdrCorrelationPass [RPCRT4.@]
6799 * Performs correlation validity checking.
6801 * PARAMS
6802 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6804 * RETURNS
6805 * Nothing.
6807 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6809 FIXME("(%p): stub\n", pStubMsg);
6812 /***********************************************************************
6813 * NdrCorrelationFree [RPCRT4.@]
6815 * Frees any resources used while unmarshalling parameters that need
6816 * correlation validity checking.
6818 * PARAMS
6819 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6821 * RETURNS
6822 * Nothing.
6824 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6826 FIXME("(%p): stub\n", pStubMsg);