rpcrt4: Use RpcMsg->Buffer instead of BufferStart since the latter isn't always set.
[wine/multimedia.git] / dlls / rpcrt4 / ndr_marshall.c
blobe983f610525b7c590a03a9c9635f4589226454b2
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)))
63 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
64 (MAKELONG( \
65 MAKEWORD(*(pchar), *((pchar)+1)), \
66 MAKEWORD(*((pchar)+2), *((pchar)+3))))
67 #endif
69 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
70 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
71 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
72 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
73 *(pchar) = HIBYTE(HIWORD(uint32)))
75 #define BIG_ENDIAN_UINT32_READ(pchar) \
76 (MAKELONG( \
77 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
78 MAKEWORD(*((pchar)+1), *(pchar))))
80 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
81 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
82 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
83 # define NDR_LOCAL_UINT32_READ(pchar) \
84 BIG_ENDIAN_UINT32_READ(pchar)
85 #else
86 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
87 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
88 # define NDR_LOCAL_UINT32_READ(pchar) \
89 LITTLE_ENDIAN_UINT32_READ(pchar)
90 #endif
92 /* _Align must be the desired alignment,
93 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
94 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
95 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
96 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
97 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
98 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
99 do { \
100 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
101 ALIGN_POINTER(_Ptr, _Align); \
102 } while(0)
104 #define STD_OVERFLOW_CHECK(_Msg) do { \
105 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
106 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
107 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
108 } while (0)
110 #define NDR_POINTER_ID_BASE 0x20000
111 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
112 #define NDR_TABLE_SIZE 128
113 #define NDR_TABLE_MASK 127
115 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
116 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
117 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
121 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
122 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
123 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
125 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING);
126 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
127 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
128 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
130 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
132 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
134 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
135 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
136 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
137 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
138 /* 0x10 */
139 NdrBaseTypeMarshall,
140 /* 0x11 */
141 NdrPointerMarshall, NdrPointerMarshall,
142 NdrPointerMarshall, NdrPointerMarshall,
143 /* 0x15 */
144 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
145 NdrConformantStructMarshall, NdrConformantStructMarshall,
146 NdrConformantVaryingStructMarshall,
147 NdrComplexStructMarshall,
148 /* 0x1b */
149 NdrConformantArrayMarshall,
150 NdrConformantVaryingArrayMarshall,
151 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
152 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
153 NdrComplexArrayMarshall,
154 /* 0x22 */
155 NdrConformantStringMarshall, 0, 0,
156 NdrConformantStringMarshall,
157 NdrNonConformantStringMarshall, 0, 0, 0,
158 /* 0x2a */
159 NdrEncapsulatedUnionMarshall,
160 NdrNonEncapsulatedUnionMarshall,
161 NdrByteCountPointerMarshall,
162 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
163 /* 0x2f */
164 NdrInterfacePointerMarshall,
165 /* 0x30 */
166 NdrContextHandleMarshall,
167 /* 0xb1 */
168 0, 0, 0,
169 NdrUserMarshalMarshall,
170 0, 0,
171 /* 0xb7 */
172 NdrRangeMarshall
174 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
176 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
177 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
178 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
179 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
180 /* 0x10 */
181 NdrBaseTypeUnmarshall,
182 /* 0x11 */
183 NdrPointerUnmarshall, NdrPointerUnmarshall,
184 NdrPointerUnmarshall, NdrPointerUnmarshall,
185 /* 0x15 */
186 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
187 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
188 NdrConformantVaryingStructUnmarshall,
189 NdrComplexStructUnmarshall,
190 /* 0x1b */
191 NdrConformantArrayUnmarshall,
192 NdrConformantVaryingArrayUnmarshall,
193 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
194 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
195 NdrComplexArrayUnmarshall,
196 /* 0x22 */
197 NdrConformantStringUnmarshall, 0, 0,
198 NdrConformantStringUnmarshall,
199 NdrNonConformantStringUnmarshall, 0, 0, 0,
200 /* 0x2a */
201 NdrEncapsulatedUnionUnmarshall,
202 NdrNonEncapsulatedUnionUnmarshall,
203 NdrByteCountPointerUnmarshall,
204 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
205 /* 0x2f */
206 NdrInterfacePointerUnmarshall,
207 /* 0x30 */
208 NdrContextHandleUnmarshall,
209 /* 0xb1 */
210 0, 0, 0,
211 NdrUserMarshalUnmarshall,
212 0, 0,
213 /* 0xb7 */
214 NdrRangeUnmarshall
216 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
218 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
219 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
220 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
221 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
222 /* 0x10 */
223 NdrBaseTypeBufferSize,
224 /* 0x11 */
225 NdrPointerBufferSize, NdrPointerBufferSize,
226 NdrPointerBufferSize, NdrPointerBufferSize,
227 /* 0x15 */
228 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
229 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
230 NdrConformantVaryingStructBufferSize,
231 NdrComplexStructBufferSize,
232 /* 0x1b */
233 NdrConformantArrayBufferSize,
234 NdrConformantVaryingArrayBufferSize,
235 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
236 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
237 NdrComplexArrayBufferSize,
238 /* 0x22 */
239 NdrConformantStringBufferSize, 0, 0,
240 NdrConformantStringBufferSize,
241 NdrNonConformantStringBufferSize, 0, 0, 0,
242 /* 0x2a */
243 NdrEncapsulatedUnionBufferSize,
244 NdrNonEncapsulatedUnionBufferSize,
245 NdrByteCountPointerBufferSize,
246 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
247 /* 0x2f */
248 NdrInterfacePointerBufferSize,
249 /* 0x30 */
250 NdrContextHandleBufferSize,
251 /* 0xb1 */
252 0, 0, 0,
253 NdrUserMarshalBufferSize,
254 0, 0,
255 /* 0xb7 */
256 NdrRangeBufferSize
258 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
260 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
261 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
262 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
263 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
264 /* 0x10 */
265 NdrBaseTypeMemorySize,
266 /* 0x11 */
267 NdrPointerMemorySize, NdrPointerMemorySize,
268 NdrPointerMemorySize, NdrPointerMemorySize,
269 /* 0x15 */
270 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
271 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
272 NdrConformantVaryingStructMemorySize,
273 NdrComplexStructMemorySize,
274 /* 0x1b */
275 NdrConformantArrayMemorySize,
276 NdrConformantVaryingArrayMemorySize,
277 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
278 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
279 NdrComplexArrayMemorySize,
280 /* 0x22 */
281 NdrConformantStringMemorySize, 0, 0,
282 NdrConformantStringMemorySize,
283 NdrNonConformantStringMemorySize, 0, 0, 0,
284 /* 0x2a */
285 NdrEncapsulatedUnionMemorySize,
286 NdrNonEncapsulatedUnionMemorySize,
287 NdrByteCountPointerMemorySize,
288 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
289 /* 0x2f */
290 NdrInterfacePointerMemorySize,
291 /* 0x30 */
293 /* 0xb1 */
294 0, 0, 0,
295 NdrUserMarshalMemorySize,
296 0, 0,
297 /* 0xb7 */
298 NdrRangeMemorySize
300 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
302 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
303 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
304 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
305 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
306 /* 0x10 */
307 NdrBaseTypeFree,
308 /* 0x11 */
309 NdrPointerFree, NdrPointerFree,
310 NdrPointerFree, NdrPointerFree,
311 /* 0x15 */
312 NdrSimpleStructFree, NdrSimpleStructFree,
313 NdrConformantStructFree, NdrConformantStructFree,
314 NdrConformantVaryingStructFree,
315 NdrComplexStructFree,
316 /* 0x1b */
317 NdrConformantArrayFree,
318 NdrConformantVaryingArrayFree,
319 NdrFixedArrayFree, NdrFixedArrayFree,
320 NdrVaryingArrayFree, NdrVaryingArrayFree,
321 NdrComplexArrayFree,
322 /* 0x22 */
323 0, 0, 0,
324 0, 0, 0, 0, 0,
325 /* 0x2a */
326 NdrEncapsulatedUnionFree,
327 NdrNonEncapsulatedUnionFree,
329 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
330 /* 0x2f */
331 NdrInterfacePointerFree,
332 /* 0x30 */
334 /* 0xb1 */
335 0, 0, 0,
336 NdrUserMarshalFree,
337 0, 0,
338 /* 0xb7 */
339 NdrRangeFree
342 typedef struct _NDR_MEMORY_LIST
344 ULONG magic;
345 ULONG size;
346 ULONG reserved;
347 struct _NDR_MEMORY_LIST *next;
348 } NDR_MEMORY_LIST;
350 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
352 /***********************************************************************
353 * NdrAllocate [RPCRT4.@]
355 * Allocates a block of memory using pStubMsg->pfnAllocate.
357 * PARAMS
358 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
359 * len [I] Size of memory block to allocate.
361 * RETURNS
362 * The memory block of size len that was allocated.
364 * NOTES
365 * The memory block is always 8-byte aligned.
366 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
367 * exception is raised.
369 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
371 SIZE_T aligned_len;
372 SIZE_T adjusted_len;
373 void *p;
374 NDR_MEMORY_LIST *mem_list;
376 aligned_len = ALIGNED_LENGTH(len, 8);
377 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
378 /* check for overflow */
379 if (adjusted_len < len)
381 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
382 RpcRaiseException(RPC_X_BAD_STUB_DATA);
385 p = pStubMsg->pfnAllocate(adjusted_len);
386 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
388 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
389 mem_list->magic = MEML_MAGIC;
390 mem_list->size = aligned_len;
391 mem_list->reserved = 0;
392 mem_list->next = pStubMsg->pMemoryList;
393 pStubMsg->pMemoryList = mem_list;
395 TRACE("-- %p\n", p);
396 return p;
399 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
401 TRACE("(%p, %p)\n", pStubMsg, Pointer);
403 pStubMsg->pfnFree(Pointer);
406 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
408 return (*(const ULONG *)pFormat != -1);
411 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
413 ALIGN_POINTER(pStubMsg->Buffer, 4);
414 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
415 RpcRaiseException(RPC_X_BAD_STUB_DATA);
416 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
417 pStubMsg->Buffer += 4;
418 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
419 if (pStubMsg->fHasNewCorrDesc)
420 return pFormat+6;
421 else
422 return pFormat+4;
425 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
427 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
429 pStubMsg->Offset = 0;
430 pStubMsg->ActualCount = pStubMsg->MaxCount;
431 goto done;
434 ALIGN_POINTER(pStubMsg->Buffer, 4);
435 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
436 RpcRaiseException(RPC_X_BAD_STUB_DATA);
437 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
438 pStubMsg->Buffer += 4;
439 TRACE("offset is %d\n", pStubMsg->Offset);
440 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
441 pStubMsg->Buffer += 4;
442 TRACE("variance is %d\n", pStubMsg->ActualCount);
444 if ((pStubMsg->ActualCount > MaxValue) ||
445 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
447 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
448 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
449 RpcRaiseException(RPC_S_INVALID_BOUND);
450 return NULL;
453 done:
454 if (pStubMsg->fHasNewCorrDesc)
455 return pFormat+6;
456 else
457 return pFormat+4;
460 /* writes the conformance value to the buffer */
461 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
463 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
464 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
465 RpcRaiseException(RPC_X_BAD_STUB_DATA);
466 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
467 pStubMsg->Buffer += 4;
470 /* writes the variance values to the buffer */
471 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
473 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
474 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
475 RpcRaiseException(RPC_X_BAD_STUB_DATA);
476 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
477 pStubMsg->Buffer += 4;
478 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
479 pStubMsg->Buffer += 4;
482 /* requests buffer space for the conformance value */
483 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
485 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
486 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
487 RpcRaiseException(RPC_X_BAD_STUB_DATA);
488 pStubMsg->BufferLength += 4;
491 /* requests buffer space for the variance values */
492 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
494 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
495 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
496 RpcRaiseException(RPC_X_BAD_STUB_DATA);
497 pStubMsg->BufferLength += 8;
500 PFORMAT_STRING ComputeConformanceOrVariance(
501 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
502 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
504 BYTE dtype = pFormat[0] & 0xf;
505 short ofs = *(const short *)&pFormat[2];
506 LPVOID ptr = NULL;
507 DWORD data = 0;
509 if (!IsConformanceOrVariancePresent(pFormat)) {
510 /* null descriptor */
511 *pCount = def;
512 goto finish_conf;
515 switch (pFormat[0] & 0xf0) {
516 case RPC_FC_NORMAL_CONFORMANCE:
517 TRACE("normal conformance, ofs=%d\n", ofs);
518 ptr = pMemory;
519 break;
520 case RPC_FC_POINTER_CONFORMANCE:
521 TRACE("pointer conformance, ofs=%d\n", ofs);
522 ptr = pStubMsg->Memory;
523 break;
524 case RPC_FC_TOP_LEVEL_CONFORMANCE:
525 TRACE("toplevel conformance, ofs=%d\n", ofs);
526 if (pStubMsg->StackTop) {
527 ptr = pStubMsg->StackTop;
529 else {
530 /* -Os mode, *pCount is already set */
531 goto finish_conf;
533 break;
534 case RPC_FC_CONSTANT_CONFORMANCE:
535 data = ofs | ((DWORD)pFormat[1] << 16);
536 TRACE("constant conformance, val=%d\n", data);
537 *pCount = data;
538 goto finish_conf;
539 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
540 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
541 if (pStubMsg->StackTop) {
542 ptr = pStubMsg->StackTop;
544 else {
545 /* ? */
546 goto done_conf_grab;
548 break;
549 default:
550 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
553 switch (pFormat[1]) {
554 case RPC_FC_DEREFERENCE:
555 ptr = *(LPVOID*)((char *)ptr + ofs);
556 break;
557 case RPC_FC_CALLBACK:
559 unsigned char *old_stack_top = pStubMsg->StackTop;
560 pStubMsg->StackTop = ptr;
562 /* ofs is index into StubDesc->apfnExprEval */
563 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
564 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
566 pStubMsg->StackTop = old_stack_top;
568 /* the callback function always stores the computed value in MaxCount */
569 *pCount = pStubMsg->MaxCount;
570 goto finish_conf;
572 default:
573 ptr = (char *)ptr + ofs;
574 break;
577 switch (dtype) {
578 case RPC_FC_LONG:
579 case RPC_FC_ULONG:
580 data = *(DWORD*)ptr;
581 break;
582 case RPC_FC_SHORT:
583 data = *(SHORT*)ptr;
584 break;
585 case RPC_FC_USHORT:
586 data = *(USHORT*)ptr;
587 break;
588 case RPC_FC_CHAR:
589 case RPC_FC_SMALL:
590 data = *(CHAR*)ptr;
591 break;
592 case RPC_FC_BYTE:
593 case RPC_FC_USMALL:
594 data = *(UCHAR*)ptr;
595 break;
596 default:
597 FIXME("unknown conformance data type %x\n", dtype);
598 goto done_conf_grab;
600 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
602 done_conf_grab:
603 switch (pFormat[1]) {
604 case RPC_FC_DEREFERENCE: /* already handled */
605 case 0: /* no op */
606 *pCount = data;
607 break;
608 case RPC_FC_ADD_1:
609 *pCount = data + 1;
610 break;
611 case RPC_FC_SUB_1:
612 *pCount = data - 1;
613 break;
614 case RPC_FC_MULT_2:
615 *pCount = data * 2;
616 break;
617 case RPC_FC_DIV_2:
618 *pCount = data / 2;
619 break;
620 default:
621 FIXME("unknown conformance op %d\n", pFormat[1]);
622 goto finish_conf;
625 finish_conf:
626 TRACE("resulting conformance is %ld\n", *pCount);
627 if (pStubMsg->fHasNewCorrDesc)
628 return pFormat+6;
629 else
630 return pFormat+4;
633 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
634 PFORMAT_STRING pFormat)
636 if (IsConformanceOrVariancePresent(pFormat))
638 if (pStubMsg->fHasNewCorrDesc)
639 pFormat += 6;
640 else
641 pFormat += 4;
643 return pFormat;
646 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
647 * the result overflows 32-bits */
648 static inline ULONG safe_multiply(ULONG a, ULONG b)
650 ULONGLONG ret = (ULONGLONG)a * b;
651 if (ret > 0xffffffff)
653 RpcRaiseException(RPC_S_INVALID_BOUND);
654 return 0;
656 return ret;
659 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
661 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
662 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
663 RpcRaiseException(RPC_X_BAD_STUB_DATA);
664 pStubMsg->Buffer += size;
667 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
669 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
671 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
672 pStubMsg->BufferLength, size);
673 RpcRaiseException(RPC_X_BAD_STUB_DATA);
675 pStubMsg->BufferLength += size;
678 /* copies data from the buffer, checking that there is enough data in the buffer
679 * to do so */
680 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
682 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
683 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
685 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
686 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
687 RpcRaiseException(RPC_X_BAD_STUB_DATA);
689 if (p == pStubMsg->Buffer)
690 ERR("pointer is the same as the buffer\n");
691 memcpy(p, pStubMsg->Buffer, size);
692 pStubMsg->Buffer += size;
695 /* copies data to the buffer, checking that there is enough space to do so */
696 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
698 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
699 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
701 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
702 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
703 size);
704 RpcRaiseException(RPC_X_BAD_STUB_DATA);
706 memcpy(pStubMsg->Buffer, p, size);
707 pStubMsg->Buffer += size;
710 /* verify that string data sitting in the buffer is valid and safe to
711 * unmarshall */
712 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
714 ULONG i;
716 /* verify the buffer is safe to access */
717 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
718 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
720 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
721 pStubMsg->BufferEnd, pStubMsg->Buffer);
722 RpcRaiseException(RPC_X_BAD_STUB_DATA);
725 /* strings must always have null terminating bytes */
726 if (bufsize < esize)
728 ERR("invalid string length of %d\n", bufsize / esize);
729 RpcRaiseException(RPC_S_INVALID_BOUND);
732 for (i = bufsize - esize; i < bufsize; i++)
733 if (pStubMsg->Buffer[i] != 0)
735 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
736 i, pStubMsg->Buffer[i]);
737 RpcRaiseException(RPC_S_INVALID_BOUND);
741 static inline void dump_pointer_attr(unsigned char attr)
743 if (attr & RPC_FC_P_ALLOCALLNODES)
744 TRACE(" RPC_FC_P_ALLOCALLNODES");
745 if (attr & RPC_FC_P_DONTFREE)
746 TRACE(" RPC_FC_P_DONTFREE");
747 if (attr & RPC_FC_P_ONSTACK)
748 TRACE(" RPC_FC_P_ONSTACK");
749 if (attr & RPC_FC_P_SIMPLEPOINTER)
750 TRACE(" RPC_FC_P_SIMPLEPOINTER");
751 if (attr & RPC_FC_P_DEREF)
752 TRACE(" RPC_FC_P_DEREF");
753 TRACE("\n");
756 /***********************************************************************
757 * PointerMarshall [internal]
759 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
760 unsigned char *Buffer,
761 unsigned char *Pointer,
762 PFORMAT_STRING pFormat)
764 unsigned type = pFormat[0], attr = pFormat[1];
765 PFORMAT_STRING desc;
766 NDR_MARSHALL m;
767 ULONG pointer_id;
768 int pointer_needs_marshaling;
770 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
771 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
772 pFormat += 2;
773 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
774 else desc = pFormat + *(const SHORT*)pFormat;
776 switch (type) {
777 case RPC_FC_RP: /* ref pointer (always non-null) */
778 if (!Pointer)
780 ERR("NULL ref pointer is not allowed\n");
781 RpcRaiseException(RPC_X_NULL_REF_POINTER);
783 pointer_needs_marshaling = 1;
784 break;
785 case RPC_FC_UP: /* unique pointer */
786 case RPC_FC_OP: /* object pointer - same as unique here */
787 if (Pointer)
788 pointer_needs_marshaling = 1;
789 else
790 pointer_needs_marshaling = 0;
791 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
792 TRACE("writing 0x%08x to buffer\n", pointer_id);
793 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
794 break;
795 case RPC_FC_FP:
796 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
797 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
798 TRACE("writing 0x%08x to buffer\n", pointer_id);
799 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
800 break;
801 default:
802 FIXME("unhandled ptr type=%02x\n", type);
803 RpcRaiseException(RPC_X_BAD_STUB_DATA);
804 return;
807 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
809 if (pointer_needs_marshaling) {
810 if (attr & RPC_FC_P_DEREF) {
811 Pointer = *(unsigned char**)Pointer;
812 TRACE("deref => %p\n", Pointer);
814 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
815 if (m) m(pStubMsg, Pointer, desc);
816 else FIXME("no marshaller for data type=%02x\n", *desc);
819 STD_OVERFLOW_CHECK(pStubMsg);
822 /***********************************************************************
823 * PointerUnmarshall [internal]
825 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
826 unsigned char *Buffer,
827 unsigned char **pPointer,
828 unsigned char *pSrcPointer,
829 PFORMAT_STRING pFormat,
830 unsigned char fMustAlloc)
832 unsigned type = pFormat[0], attr = pFormat[1];
833 PFORMAT_STRING desc;
834 NDR_UNMARSHALL m;
835 DWORD pointer_id = 0;
836 int pointer_needs_unmarshaling;
838 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
839 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
840 pFormat += 2;
841 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
842 else desc = pFormat + *(const SHORT*)pFormat;
844 switch (type) {
845 case RPC_FC_RP: /* ref pointer (always non-null) */
846 pointer_needs_unmarshaling = 1;
847 break;
848 case RPC_FC_UP: /* unique pointer */
849 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
850 TRACE("pointer_id is 0x%08x\n", pointer_id);
851 if (pointer_id)
852 pointer_needs_unmarshaling = 1;
853 else {
854 *pPointer = NULL;
855 pointer_needs_unmarshaling = 0;
857 break;
858 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
859 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
860 TRACE("pointer_id is 0x%08x\n", pointer_id);
861 if (!fMustAlloc && pSrcPointer)
863 FIXME("free object pointer %p\n", pSrcPointer);
864 fMustAlloc = TRUE;
866 if (pointer_id)
867 pointer_needs_unmarshaling = 1;
868 else
870 *pPointer = NULL;
871 pointer_needs_unmarshaling = 0;
873 break;
874 case RPC_FC_FP:
875 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
876 TRACE("pointer_id is 0x%08x\n", pointer_id);
877 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
878 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
879 break;
880 default:
881 FIXME("unhandled ptr type=%02x\n", type);
882 RpcRaiseException(RPC_X_BAD_STUB_DATA);
883 return;
886 if (pointer_needs_unmarshaling) {
887 unsigned char *base_ptr_val = *pPointer;
888 unsigned char **current_ptr = pPointer;
889 if (pStubMsg->IsClient) {
890 TRACE("client\n");
891 /* if we aren't forcing allocation of memory then try to use the existing
892 * (source) pointer to unmarshall the data into so that [in,out]
893 * parameters behave correctly. it doesn't matter if the parameter is
894 * [out] only since in that case the pointer will be NULL. we force
895 * allocation when the source pointer is NULL here instead of in the type
896 * unmarshalling routine for the benefit of the deref code below */
897 if (!fMustAlloc) {
898 if (pSrcPointer) {
899 TRACE("setting *pPointer to %p\n", pSrcPointer);
900 *pPointer = base_ptr_val = pSrcPointer;
901 } else
902 fMustAlloc = TRUE;
904 } else {
905 TRACE("server\n");
906 /* the memory in a stub is never initialised, so we have to work out here
907 * whether we have to initialise it so we can use the optimisation of
908 * setting the pointer to the buffer, if possible, or set fMustAlloc to
909 * TRUE. */
910 if (attr & RPC_FC_P_DEREF) {
911 fMustAlloc = TRUE;
912 } else {
913 base_ptr_val = NULL;
914 *current_ptr = NULL;
918 if (attr & RPC_FC_P_ALLOCALLNODES)
919 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
921 if (attr & RPC_FC_P_DEREF) {
922 if (fMustAlloc) {
923 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
924 *pPointer = base_ptr_val;
925 current_ptr = (unsigned char **)base_ptr_val;
926 } else
927 current_ptr = *(unsigned char***)current_ptr;
928 TRACE("deref => %p\n", current_ptr);
929 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
931 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
932 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
933 else FIXME("no unmarshaller for data type=%02x\n", *desc);
935 if (type == RPC_FC_FP)
936 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
937 base_ptr_val);
940 TRACE("pointer=%p\n", *pPointer);
943 /***********************************************************************
944 * PointerBufferSize [internal]
946 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
947 unsigned char *Pointer,
948 PFORMAT_STRING pFormat)
950 unsigned type = pFormat[0], attr = pFormat[1];
951 PFORMAT_STRING desc;
952 NDR_BUFFERSIZE m;
953 int pointer_needs_sizing;
954 ULONG pointer_id;
956 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
957 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
958 pFormat += 2;
959 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
960 else desc = pFormat + *(const SHORT*)pFormat;
962 switch (type) {
963 case RPC_FC_RP: /* ref pointer (always non-null) */
964 if (!Pointer)
966 ERR("NULL ref pointer is not allowed\n");
967 RpcRaiseException(RPC_X_NULL_REF_POINTER);
969 break;
970 case RPC_FC_OP:
971 case RPC_FC_UP:
972 /* NULL pointer has no further representation */
973 if (!Pointer)
974 return;
975 break;
976 case RPC_FC_FP:
977 pointer_needs_sizing = !NdrFullPointerQueryPointer(
978 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
979 if (!pointer_needs_sizing)
980 return;
981 break;
982 default:
983 FIXME("unhandled ptr type=%02x\n", type);
984 RpcRaiseException(RPC_X_BAD_STUB_DATA);
985 return;
988 if (attr & RPC_FC_P_DEREF) {
989 Pointer = *(unsigned char**)Pointer;
990 TRACE("deref => %p\n", Pointer);
993 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
994 if (m) m(pStubMsg, Pointer, desc);
995 else FIXME("no buffersizer for data type=%02x\n", *desc);
998 /***********************************************************************
999 * PointerMemorySize [internal]
1001 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1002 unsigned char *Buffer,
1003 PFORMAT_STRING pFormat)
1005 unsigned type = pFormat[0], attr = pFormat[1];
1006 PFORMAT_STRING desc;
1007 NDR_MEMORYSIZE m;
1008 DWORD pointer_id = 0;
1009 int pointer_needs_sizing;
1011 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1012 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1013 pFormat += 2;
1014 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1015 else desc = pFormat + *(const SHORT*)pFormat;
1017 switch (type) {
1018 case RPC_FC_RP: /* ref pointer (always non-null) */
1019 pointer_needs_sizing = 1;
1020 break;
1021 case RPC_FC_UP: /* unique pointer */
1022 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1023 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1024 TRACE("pointer_id is 0x%08x\n", pointer_id);
1025 if (pointer_id)
1026 pointer_needs_sizing = 1;
1027 else
1028 pointer_needs_sizing = 0;
1029 break;
1030 case RPC_FC_FP:
1032 void *pointer;
1033 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1034 TRACE("pointer_id is 0x%08x\n", pointer_id);
1035 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1036 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1037 break;
1039 default:
1040 FIXME("unhandled ptr type=%02x\n", type);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1042 return 0;
1045 if (attr & RPC_FC_P_DEREF) {
1046 TRACE("deref\n");
1049 if (pointer_needs_sizing) {
1050 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1051 if (m) m(pStubMsg, desc);
1052 else FIXME("no memorysizer for data type=%02x\n", *desc);
1055 return pStubMsg->MemorySize;
1058 /***********************************************************************
1059 * PointerFree [internal]
1061 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1062 unsigned char *Pointer,
1063 PFORMAT_STRING pFormat)
1065 unsigned type = pFormat[0], attr = pFormat[1];
1066 PFORMAT_STRING desc;
1067 NDR_FREE m;
1068 unsigned char *current_pointer = Pointer;
1070 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1071 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1072 if (attr & RPC_FC_P_DONTFREE) return;
1073 pFormat += 2;
1074 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1075 else desc = pFormat + *(const SHORT*)pFormat;
1077 if (!Pointer) return;
1079 if (type == RPC_FC_FP) {
1080 int pointer_needs_freeing = NdrFullPointerFree(
1081 pStubMsg->FullPtrXlatTables, Pointer);
1082 if (!pointer_needs_freeing)
1083 return;
1086 if (attr & RPC_FC_P_DEREF) {
1087 current_pointer = *(unsigned char**)Pointer;
1088 TRACE("deref => %p\n", current_pointer);
1091 m = NdrFreer[*desc & NDR_TABLE_MASK];
1092 if (m) m(pStubMsg, current_pointer, desc);
1094 /* this check stops us from trying to free buffer memory. we don't have to
1095 * worry about clients, since they won't call this function.
1096 * we don't have to check for the buffer being reallocated because
1097 * BufferStart and BufferEnd won't be reset when allocating memory for
1098 * sending the response. we don't have to check for the new buffer here as
1099 * it won't be used a type memory, only for buffer memory */
1100 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1101 goto notfree;
1103 if (attr & RPC_FC_P_ONSTACK) {
1104 TRACE("not freeing stack ptr %p\n", Pointer);
1105 return;
1107 TRACE("freeing %p\n", Pointer);
1108 NdrFree(pStubMsg, Pointer);
1109 return;
1110 notfree:
1111 TRACE("not freeing %p\n", Pointer);
1114 /***********************************************************************
1115 * EmbeddedPointerMarshall
1117 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1118 unsigned char *pMemory,
1119 PFORMAT_STRING pFormat)
1121 unsigned char *Mark = pStubMsg->BufferMark;
1122 unsigned rep, count, stride;
1123 unsigned i;
1124 unsigned char *saved_buffer = NULL;
1126 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1128 if (*pFormat != RPC_FC_PP) return NULL;
1129 pFormat += 2;
1131 if (pStubMsg->PointerBufferMark)
1133 saved_buffer = pStubMsg->Buffer;
1134 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1135 pStubMsg->PointerBufferMark = NULL;
1138 while (pFormat[0] != RPC_FC_END) {
1139 switch (pFormat[0]) {
1140 default:
1141 FIXME("unknown repeat type %d\n", pFormat[0]);
1142 case RPC_FC_NO_REPEAT:
1143 rep = 1;
1144 stride = 0;
1145 count = 1;
1146 pFormat += 2;
1147 break;
1148 case RPC_FC_FIXED_REPEAT:
1149 rep = *(const WORD*)&pFormat[2];
1150 stride = *(const WORD*)&pFormat[4];
1151 count = *(const WORD*)&pFormat[8];
1152 pFormat += 10;
1153 break;
1154 case RPC_FC_VARIABLE_REPEAT:
1155 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1156 stride = *(const WORD*)&pFormat[2];
1157 count = *(const WORD*)&pFormat[6];
1158 pFormat += 8;
1159 break;
1161 for (i = 0; i < rep; i++) {
1162 PFORMAT_STRING info = pFormat;
1163 unsigned char *membase = pMemory + (i * stride);
1164 unsigned char *bufbase = Mark + (i * stride);
1165 unsigned u;
1167 for (u=0; u<count; u++,info+=8) {
1168 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1169 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1170 unsigned char *saved_memory = pStubMsg->Memory;
1172 pStubMsg->Memory = pMemory;
1173 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1174 pStubMsg->Memory = saved_memory;
1177 pFormat += 8 * count;
1180 if (saved_buffer)
1182 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1183 pStubMsg->Buffer = saved_buffer;
1186 STD_OVERFLOW_CHECK(pStubMsg);
1188 return NULL;
1191 /***********************************************************************
1192 * EmbeddedPointerUnmarshall
1194 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1195 unsigned char *pDstBuffer,
1196 unsigned char *pSrcMemoryPtrs,
1197 PFORMAT_STRING pFormat,
1198 unsigned char fMustAlloc)
1200 unsigned char *Mark = pStubMsg->BufferMark;
1201 unsigned rep, count, stride;
1202 unsigned i;
1203 unsigned char *saved_buffer = NULL;
1205 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1207 if (*pFormat != RPC_FC_PP) return NULL;
1208 pFormat += 2;
1210 if (pStubMsg->PointerBufferMark)
1212 saved_buffer = pStubMsg->Buffer;
1213 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1214 pStubMsg->PointerBufferMark = NULL;
1217 while (pFormat[0] != RPC_FC_END) {
1218 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1219 switch (pFormat[0]) {
1220 default:
1221 FIXME("unknown repeat type %d\n", pFormat[0]);
1222 case RPC_FC_NO_REPEAT:
1223 rep = 1;
1224 stride = 0;
1225 count = 1;
1226 pFormat += 2;
1227 break;
1228 case RPC_FC_FIXED_REPEAT:
1229 rep = *(const WORD*)&pFormat[2];
1230 stride = *(const WORD*)&pFormat[4];
1231 count = *(const WORD*)&pFormat[8];
1232 pFormat += 10;
1233 break;
1234 case RPC_FC_VARIABLE_REPEAT:
1235 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1236 stride = *(const WORD*)&pFormat[2];
1237 count = *(const WORD*)&pFormat[6];
1238 pFormat += 8;
1239 break;
1241 for (i = 0; i < rep; i++) {
1242 PFORMAT_STRING info = pFormat;
1243 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1244 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1245 unsigned char *bufbase = Mark + (i * stride);
1246 unsigned u;
1248 for (u=0; u<count; u++,info+=8) {
1249 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1250 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1251 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1252 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1255 pFormat += 8 * count;
1258 if (saved_buffer)
1260 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1261 pStubMsg->Buffer = saved_buffer;
1264 return NULL;
1267 /***********************************************************************
1268 * EmbeddedPointerBufferSize
1270 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1271 unsigned char *pMemory,
1272 PFORMAT_STRING pFormat)
1274 unsigned rep, count, stride;
1275 unsigned i;
1276 ULONG saved_buffer_length = 0;
1278 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1280 if (pStubMsg->IgnoreEmbeddedPointers) return;
1282 if (*pFormat != RPC_FC_PP) return;
1283 pFormat += 2;
1285 if (pStubMsg->PointerLength)
1287 saved_buffer_length = pStubMsg->BufferLength;
1288 pStubMsg->BufferLength = pStubMsg->PointerLength;
1289 pStubMsg->PointerLength = 0;
1292 while (pFormat[0] != RPC_FC_END) {
1293 switch (pFormat[0]) {
1294 default:
1295 FIXME("unknown repeat type %d\n", pFormat[0]);
1296 case RPC_FC_NO_REPEAT:
1297 rep = 1;
1298 stride = 0;
1299 count = 1;
1300 pFormat += 2;
1301 break;
1302 case RPC_FC_FIXED_REPEAT:
1303 rep = *(const WORD*)&pFormat[2];
1304 stride = *(const WORD*)&pFormat[4];
1305 count = *(const WORD*)&pFormat[8];
1306 pFormat += 10;
1307 break;
1308 case RPC_FC_VARIABLE_REPEAT:
1309 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1310 stride = *(const WORD*)&pFormat[2];
1311 count = *(const WORD*)&pFormat[6];
1312 pFormat += 8;
1313 break;
1315 for (i = 0; i < rep; i++) {
1316 PFORMAT_STRING info = pFormat;
1317 unsigned char *membase = pMemory + (i * stride);
1318 unsigned u;
1320 for (u=0; u<count; u++,info+=8) {
1321 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1322 unsigned char *saved_memory = pStubMsg->Memory;
1324 pStubMsg->Memory = pMemory;
1325 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1326 pStubMsg->Memory = saved_memory;
1329 pFormat += 8 * count;
1332 if (saved_buffer_length)
1334 pStubMsg->PointerLength = pStubMsg->BufferLength;
1335 pStubMsg->BufferLength = saved_buffer_length;
1339 /***********************************************************************
1340 * EmbeddedPointerMemorySize [internal]
1342 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1343 PFORMAT_STRING pFormat)
1345 unsigned char *Mark = pStubMsg->BufferMark;
1346 unsigned rep, count, stride;
1347 unsigned i;
1348 unsigned char *saved_buffer = NULL;
1350 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1352 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1354 if (pStubMsg->PointerBufferMark)
1356 saved_buffer = pStubMsg->Buffer;
1357 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1358 pStubMsg->PointerBufferMark = NULL;
1361 if (*pFormat != RPC_FC_PP) return 0;
1362 pFormat += 2;
1364 while (pFormat[0] != RPC_FC_END) {
1365 switch (pFormat[0]) {
1366 default:
1367 FIXME("unknown repeat type %d\n", pFormat[0]);
1368 case RPC_FC_NO_REPEAT:
1369 rep = 1;
1370 stride = 0;
1371 count = 1;
1372 pFormat += 2;
1373 break;
1374 case RPC_FC_FIXED_REPEAT:
1375 rep = *(const WORD*)&pFormat[2];
1376 stride = *(const WORD*)&pFormat[4];
1377 count = *(const WORD*)&pFormat[8];
1378 pFormat += 10;
1379 break;
1380 case RPC_FC_VARIABLE_REPEAT:
1381 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1382 stride = *(const WORD*)&pFormat[2];
1383 count = *(const WORD*)&pFormat[6];
1384 pFormat += 8;
1385 break;
1387 for (i = 0; i < rep; i++) {
1388 PFORMAT_STRING info = pFormat;
1389 unsigned char *bufbase = Mark + (i * stride);
1390 unsigned u;
1391 for (u=0; u<count; u++,info+=8) {
1392 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1393 PointerMemorySize(pStubMsg, bufptr, info+4);
1396 pFormat += 8 * count;
1399 if (saved_buffer)
1401 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1402 pStubMsg->Buffer = saved_buffer;
1405 return 0;
1408 /***********************************************************************
1409 * EmbeddedPointerFree [internal]
1411 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1412 unsigned char *pMemory,
1413 PFORMAT_STRING pFormat)
1415 unsigned rep, count, stride;
1416 unsigned i;
1418 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1419 if (*pFormat != RPC_FC_PP) return;
1420 pFormat += 2;
1422 while (pFormat[0] != RPC_FC_END) {
1423 switch (pFormat[0]) {
1424 default:
1425 FIXME("unknown repeat type %d\n", pFormat[0]);
1426 case RPC_FC_NO_REPEAT:
1427 rep = 1;
1428 stride = 0;
1429 count = 1;
1430 pFormat += 2;
1431 break;
1432 case RPC_FC_FIXED_REPEAT:
1433 rep = *(const WORD*)&pFormat[2];
1434 stride = *(const WORD*)&pFormat[4];
1435 count = *(const WORD*)&pFormat[8];
1436 pFormat += 10;
1437 break;
1438 case RPC_FC_VARIABLE_REPEAT:
1439 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1440 stride = *(const WORD*)&pFormat[2];
1441 count = *(const WORD*)&pFormat[6];
1442 pFormat += 8;
1443 break;
1445 for (i = 0; i < rep; i++) {
1446 PFORMAT_STRING info = pFormat;
1447 unsigned char *membase = pMemory + (i * stride);
1448 unsigned u;
1450 for (u=0; u<count; u++,info+=8) {
1451 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1452 unsigned char *saved_memory = pStubMsg->Memory;
1454 pStubMsg->Memory = pMemory;
1455 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1456 pStubMsg->Memory = saved_memory;
1459 pFormat += 8 * count;
1463 /***********************************************************************
1464 * NdrPointerMarshall [RPCRT4.@]
1466 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1467 unsigned char *pMemory,
1468 PFORMAT_STRING pFormat)
1470 unsigned char *Buffer;
1472 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1474 /* Increment the buffer here instead of in PointerMarshall,
1475 * as that is used by embedded pointers which already handle the incrementing
1476 * the buffer, and shouldn't write any additional pointer data to the wire */
1477 if (*pFormat != RPC_FC_RP)
1479 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1480 Buffer = pStubMsg->Buffer;
1481 safe_buffer_increment(pStubMsg, 4);
1483 else
1484 Buffer = pStubMsg->Buffer;
1486 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1488 return NULL;
1491 /***********************************************************************
1492 * NdrPointerUnmarshall [RPCRT4.@]
1494 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1495 unsigned char **ppMemory,
1496 PFORMAT_STRING pFormat,
1497 unsigned char fMustAlloc)
1499 unsigned char *Buffer;
1501 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1503 if (*pFormat == RPC_FC_RP)
1505 Buffer = pStubMsg->Buffer;
1506 /* Do the NULL ref pointer check here because embedded pointers can be
1507 * NULL if the type the pointer is embedded in was allocated rather than
1508 * being passed in by the client */
1509 if (pStubMsg->IsClient && !*ppMemory)
1511 ERR("NULL ref pointer is not allowed\n");
1512 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1515 else
1517 /* Increment the buffer here instead of in PointerUnmarshall,
1518 * as that is used by embedded pointers which already handle the incrementing
1519 * the buffer, and shouldn't read any additional pointer data from the
1520 * buffer */
1521 ALIGN_POINTER(pStubMsg->Buffer, 4);
1522 Buffer = pStubMsg->Buffer;
1523 safe_buffer_increment(pStubMsg, 4);
1526 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1528 return NULL;
1531 /***********************************************************************
1532 * NdrPointerBufferSize [RPCRT4.@]
1534 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1535 unsigned char *pMemory,
1536 PFORMAT_STRING pFormat)
1538 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1540 /* Increment the buffer length here instead of in PointerBufferSize,
1541 * as that is used by embedded pointers which already handle the buffer
1542 * length, and shouldn't write anything more to the wire */
1543 if (*pFormat != RPC_FC_RP)
1545 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1546 safe_buffer_length_increment(pStubMsg, 4);
1549 PointerBufferSize(pStubMsg, pMemory, pFormat);
1552 /***********************************************************************
1553 * NdrPointerMemorySize [RPCRT4.@]
1555 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1556 PFORMAT_STRING pFormat)
1558 /* unsigned size = *(LPWORD)(pFormat+2); */
1559 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1560 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1561 return 0;
1564 /***********************************************************************
1565 * NdrPointerFree [RPCRT4.@]
1567 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1568 unsigned char *pMemory,
1569 PFORMAT_STRING pFormat)
1571 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1572 PointerFree(pStubMsg, pMemory, pFormat);
1575 /***********************************************************************
1576 * NdrSimpleTypeMarshall [RPCRT4.@]
1578 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1579 unsigned char FormatChar )
1581 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1584 /***********************************************************************
1585 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1587 * Unmarshall a base type.
1589 * NOTES
1590 * Doesn't check that the buffer is long enough before copying, so the caller
1591 * should do this.
1593 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1594 unsigned char FormatChar )
1596 #define BASE_TYPE_UNMARSHALL(type) \
1597 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1598 TRACE("pMemory: %p\n", pMemory); \
1599 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1600 pStubMsg->Buffer += sizeof(type);
1602 switch(FormatChar)
1604 case RPC_FC_BYTE:
1605 case RPC_FC_CHAR:
1606 case RPC_FC_SMALL:
1607 case RPC_FC_USMALL:
1608 BASE_TYPE_UNMARSHALL(UCHAR);
1609 TRACE("value: 0x%02x\n", *pMemory);
1610 break;
1611 case RPC_FC_WCHAR:
1612 case RPC_FC_SHORT:
1613 case RPC_FC_USHORT:
1614 BASE_TYPE_UNMARSHALL(USHORT);
1615 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1616 break;
1617 case RPC_FC_LONG:
1618 case RPC_FC_ULONG:
1619 case RPC_FC_ERROR_STATUS_T:
1620 case RPC_FC_ENUM32:
1621 BASE_TYPE_UNMARSHALL(ULONG);
1622 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1623 break;
1624 case RPC_FC_FLOAT:
1625 BASE_TYPE_UNMARSHALL(float);
1626 TRACE("value: %f\n", *(float *)pMemory);
1627 break;
1628 case RPC_FC_DOUBLE:
1629 BASE_TYPE_UNMARSHALL(double);
1630 TRACE("value: %f\n", *(double *)pMemory);
1631 break;
1632 case RPC_FC_HYPER:
1633 BASE_TYPE_UNMARSHALL(ULONGLONG);
1634 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1635 break;
1636 case RPC_FC_ENUM16:
1637 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1638 TRACE("pMemory: %p\n", pMemory);
1639 /* 16-bits on the wire, but int in memory */
1640 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1641 pStubMsg->Buffer += sizeof(USHORT);
1642 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1643 break;
1644 case RPC_FC_IGNORE:
1645 break;
1646 default:
1647 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1649 #undef BASE_TYPE_UNMARSHALL
1652 /***********************************************************************
1653 * NdrSimpleStructMarshall [RPCRT4.@]
1655 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1656 unsigned char *pMemory,
1657 PFORMAT_STRING pFormat)
1659 unsigned size = *(const WORD*)(pFormat+2);
1660 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1662 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1664 pStubMsg->BufferMark = pStubMsg->Buffer;
1665 safe_copy_to_buffer(pStubMsg, pMemory, size);
1667 if (pFormat[0] != RPC_FC_STRUCT)
1668 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1670 return NULL;
1673 /***********************************************************************
1674 * NdrSimpleStructUnmarshall [RPCRT4.@]
1676 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1677 unsigned char **ppMemory,
1678 PFORMAT_STRING pFormat,
1679 unsigned char fMustAlloc)
1681 unsigned size = *(const WORD*)(pFormat+2);
1682 unsigned char *saved_buffer;
1683 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1685 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1687 if (fMustAlloc)
1688 *ppMemory = NdrAllocate(pStubMsg, size);
1689 else
1691 if (!pStubMsg->IsClient && !*ppMemory)
1692 /* for servers, we just point straight into the RPC buffer */
1693 *ppMemory = pStubMsg->Buffer;
1696 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1697 safe_buffer_increment(pStubMsg, size);
1698 if (pFormat[0] == RPC_FC_PSTRUCT)
1699 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1701 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1702 if (*ppMemory != saved_buffer)
1703 memcpy(*ppMemory, saved_buffer, size);
1705 return NULL;
1708 /***********************************************************************
1709 * NdrSimpleStructBufferSize [RPCRT4.@]
1711 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1712 unsigned char *pMemory,
1713 PFORMAT_STRING pFormat)
1715 unsigned size = *(const WORD*)(pFormat+2);
1716 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1718 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1720 safe_buffer_length_increment(pStubMsg, size);
1721 if (pFormat[0] != RPC_FC_STRUCT)
1722 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1725 /***********************************************************************
1726 * NdrSimpleStructMemorySize [RPCRT4.@]
1728 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1729 PFORMAT_STRING pFormat)
1731 unsigned short size = *(const WORD *)(pFormat+2);
1733 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1735 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1736 pStubMsg->MemorySize += size;
1737 safe_buffer_increment(pStubMsg, size);
1739 if (pFormat[0] != RPC_FC_STRUCT)
1740 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1741 return pStubMsg->MemorySize;
1744 /***********************************************************************
1745 * NdrSimpleStructFree [RPCRT4.@]
1747 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1748 unsigned char *pMemory,
1749 PFORMAT_STRING pFormat)
1751 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1752 if (pFormat[0] != RPC_FC_STRUCT)
1753 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1756 /* Array helpers */
1758 static inline void array_compute_and_size_conformance(
1759 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1760 PFORMAT_STRING pFormat)
1762 switch (fc)
1764 case RPC_FC_CARRAY:
1765 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1766 SizeConformance(pStubMsg);
1767 break;
1768 case RPC_FC_CVARRAY:
1769 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1770 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1771 SizeConformance(pStubMsg);
1772 break;
1773 case RPC_FC_C_CSTRING:
1774 case RPC_FC_C_WSTRING:
1775 if (pFormat[0] == RPC_FC_C_CSTRING)
1777 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1778 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1780 else
1782 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1783 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1786 if (fc == RPC_FC_STRING_SIZED)
1787 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1788 else
1789 pStubMsg->MaxCount = pStubMsg->ActualCount;
1791 SizeConformance(pStubMsg);
1792 break;
1793 default:
1794 ERR("unknown array format 0x%x\n", fc);
1795 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1799 static inline void array_buffer_size(
1800 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1801 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1803 DWORD size;
1804 DWORD esize;
1805 unsigned char alignment;
1807 switch (fc)
1809 case RPC_FC_CARRAY:
1810 esize = *(const WORD*)(pFormat+2);
1811 alignment = pFormat[1] + 1;
1813 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1815 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1817 size = safe_multiply(esize, pStubMsg->MaxCount);
1818 /* conformance value plus array */
1819 safe_buffer_length_increment(pStubMsg, size);
1821 if (fHasPointers)
1822 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1823 break;
1824 case RPC_FC_CVARRAY:
1825 esize = *(const WORD*)(pFormat+2);
1826 alignment = pFormat[1] + 1;
1828 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1829 pFormat = SkipConformance(pStubMsg, pFormat);
1831 SizeVariance(pStubMsg);
1833 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1835 size = safe_multiply(esize, pStubMsg->ActualCount);
1836 safe_buffer_length_increment(pStubMsg, size);
1838 if (fHasPointers)
1839 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1840 break;
1841 case RPC_FC_C_CSTRING:
1842 case RPC_FC_C_WSTRING:
1843 if (fc == RPC_FC_C_CSTRING)
1844 esize = 1;
1845 else
1846 esize = 2;
1848 SizeVariance(pStubMsg);
1850 size = safe_multiply(esize, pStubMsg->ActualCount);
1851 safe_buffer_length_increment(pStubMsg, size);
1852 break;
1853 default:
1854 ERR("unknown array format 0x%x\n", fc);
1855 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1859 static inline void array_compute_and_write_conformance(
1860 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1861 PFORMAT_STRING pFormat)
1863 switch (fc)
1865 case RPC_FC_CARRAY:
1866 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1867 WriteConformance(pStubMsg);
1868 break;
1869 case RPC_FC_CVARRAY:
1870 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1871 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1872 WriteConformance(pStubMsg);
1873 break;
1874 case RPC_FC_C_CSTRING:
1875 case RPC_FC_C_WSTRING:
1876 if (fc == RPC_FC_C_CSTRING)
1878 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1879 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1881 else
1883 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1884 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1886 if (pFormat[1] == RPC_FC_STRING_SIZED)
1887 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1888 else
1889 pStubMsg->MaxCount = pStubMsg->ActualCount;
1890 pStubMsg->Offset = 0;
1891 WriteConformance(pStubMsg);
1892 break;
1893 default:
1894 ERR("unknown array format 0x%x\n", fc);
1895 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1899 static inline void array_write_variance_and_marshall(
1900 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1901 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1903 DWORD size;
1904 DWORD esize;
1905 unsigned char alignment;
1907 switch (fc)
1909 case RPC_FC_CARRAY:
1910 esize = *(const WORD*)(pFormat+2);
1911 alignment = pFormat[1] + 1;
1913 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1915 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1917 size = safe_multiply(esize, pStubMsg->MaxCount);
1918 if (fHasPointers)
1919 pStubMsg->BufferMark = pStubMsg->Buffer;
1920 safe_copy_to_buffer(pStubMsg, pMemory, size);
1922 if (fHasPointers)
1923 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1924 break;
1925 case RPC_FC_CVARRAY:
1926 esize = *(const WORD*)(pFormat+2);
1927 alignment = pFormat[1] + 1;
1929 /* conformance */
1930 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1931 /* variance */
1932 pFormat = SkipConformance(pStubMsg, pFormat);
1934 WriteVariance(pStubMsg);
1936 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1938 size = safe_multiply(esize, pStubMsg->ActualCount);
1940 if (fHasPointers)
1941 pStubMsg->BufferMark = pStubMsg->Buffer;
1942 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
1944 if (fHasPointers)
1945 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1946 break;
1947 case RPC_FC_C_CSTRING:
1948 case RPC_FC_C_WSTRING:
1949 if (fc == RPC_FC_C_CSTRING)
1950 esize = 1;
1951 else
1952 esize = 2;
1954 WriteVariance(pStubMsg);
1956 size = safe_multiply(esize, pStubMsg->ActualCount);
1957 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
1958 break;
1959 default:
1960 ERR("unknown array format 0x%x\n", fc);
1961 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1965 static inline ULONG array_read_conformance(
1966 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
1968 DWORD esize;
1970 switch (fc)
1972 case RPC_FC_CARRAY:
1973 esize = *(const WORD*)(pFormat+2);
1974 pFormat = ReadConformance(pStubMsg, pFormat+4);
1975 return safe_multiply(esize, pStubMsg->MaxCount);
1976 case RPC_FC_CVARRAY:
1977 esize = *(const WORD*)(pFormat+2);
1978 pFormat = ReadConformance(pStubMsg, pFormat+4);
1979 return safe_multiply(esize, pStubMsg->MaxCount);
1980 case RPC_FC_C_CSTRING:
1981 case RPC_FC_C_WSTRING:
1982 if (fc == RPC_FC_C_CSTRING)
1983 esize = 1;
1984 else
1985 esize = 2;
1987 if (pFormat[1] == RPC_FC_STRING_SIZED)
1988 ReadConformance(pStubMsg, pFormat + 2);
1989 else
1990 ReadConformance(pStubMsg, NULL);
1991 return safe_multiply(esize, pStubMsg->MaxCount);
1992 default:
1993 ERR("unknown array format 0x%x\n", fc);
1994 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1998 static inline ULONG array_read_variance_and_unmarshall(
1999 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2000 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2001 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2003 ULONG bufsize, memsize;
2004 WORD esize;
2005 unsigned char alignment;
2006 unsigned char *saved_buffer;
2007 ULONG offset;
2009 switch (fc)
2011 case RPC_FC_CARRAY:
2012 esize = *(const WORD*)(pFormat+2);
2013 alignment = pFormat[1] + 1;
2015 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2017 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2019 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2021 if (fUnmarshall)
2023 if (fMustAlloc)
2024 *ppMemory = NdrAllocate(pStubMsg, memsize);
2025 else
2027 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2028 /* for servers, we just point straight into the RPC buffer */
2029 *ppMemory = pStubMsg->Buffer;
2032 saved_buffer = pStubMsg->Buffer;
2033 safe_buffer_increment(pStubMsg, bufsize);
2035 pStubMsg->BufferMark = saved_buffer;
2036 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2038 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2039 if (*ppMemory != saved_buffer)
2040 memcpy(*ppMemory, saved_buffer, bufsize);
2042 return bufsize;
2043 case RPC_FC_CVARRAY:
2044 esize = *(const WORD*)(pFormat+2);
2045 alignment = pFormat[1] + 1;
2047 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2049 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2051 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2053 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2054 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2056 if (fUnmarshall)
2058 offset = pStubMsg->Offset;
2060 if (!fMustAlloc && !*ppMemory)
2061 fMustAlloc = TRUE;
2062 if (fMustAlloc)
2063 *ppMemory = NdrAllocate(pStubMsg, memsize);
2064 saved_buffer = pStubMsg->Buffer;
2065 safe_buffer_increment(pStubMsg, bufsize);
2067 pStubMsg->BufferMark = saved_buffer;
2068 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2069 fMustAlloc);
2071 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2073 return bufsize;
2074 case RPC_FC_C_CSTRING:
2075 case RPC_FC_C_WSTRING:
2076 if (fc == RPC_FC_C_CSTRING)
2077 esize = 1;
2078 else
2079 esize = 2;
2081 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2083 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2085 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2086 pStubMsg->ActualCount, pStubMsg->MaxCount);
2087 RpcRaiseException(RPC_S_INVALID_BOUND);
2089 if (pStubMsg->Offset)
2091 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2092 RpcRaiseException(RPC_S_INVALID_BOUND);
2095 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2096 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2098 validate_string_data(pStubMsg, bufsize, esize);
2100 if (fUnmarshall)
2102 if (fMustAlloc)
2103 *ppMemory = NdrAllocate(pStubMsg, memsize);
2104 else
2106 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2107 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2108 /* if the data in the RPC buffer is big enough, we just point
2109 * straight into it */
2110 *ppMemory = pStubMsg->Buffer;
2111 else if (!*ppMemory)
2112 *ppMemory = NdrAllocate(pStubMsg, memsize);
2115 if (*ppMemory == pStubMsg->Buffer)
2116 safe_buffer_increment(pStubMsg, bufsize);
2117 else
2118 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2120 if (*pFormat == RPC_FC_C_CSTRING)
2121 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2122 else
2123 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2125 return bufsize;
2126 default:
2127 ERR("unknown array format 0x%x\n", fc);
2128 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2132 static inline void array_memory_size(
2133 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2134 unsigned char fHasPointers)
2136 ULONG bufsize, memsize;
2137 DWORD esize;
2138 unsigned char alignment;
2140 switch (fc)
2142 case RPC_FC_CARRAY:
2143 esize = *(const WORD*)(pFormat+2);
2144 alignment = pFormat[1] + 1;
2146 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2148 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2149 pStubMsg->MemorySize += memsize;
2151 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2152 if (fHasPointers)
2153 pStubMsg->BufferMark = pStubMsg->Buffer;
2154 safe_buffer_increment(pStubMsg, bufsize);
2156 if (fHasPointers)
2157 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2158 break;
2159 case RPC_FC_CVARRAY:
2160 esize = *(const WORD*)(pFormat+2);
2161 alignment = pFormat[1] + 1;
2163 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2165 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2167 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2168 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2169 pStubMsg->MemorySize += memsize;
2171 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2172 if (fHasPointers)
2173 pStubMsg->BufferMark = pStubMsg->Buffer;
2174 safe_buffer_increment(pStubMsg, bufsize);
2176 if (fHasPointers)
2177 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2178 break;
2179 case RPC_FC_C_CSTRING:
2180 case RPC_FC_C_WSTRING:
2181 if (fc == RPC_FC_C_CSTRING)
2182 esize = 1;
2183 else
2184 esize = 2;
2186 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2188 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2190 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2191 pStubMsg->ActualCount, pStubMsg->MaxCount);
2192 RpcRaiseException(RPC_S_INVALID_BOUND);
2194 if (pStubMsg->Offset)
2196 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2197 RpcRaiseException(RPC_S_INVALID_BOUND);
2200 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2201 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2203 validate_string_data(pStubMsg, bufsize, esize);
2205 safe_buffer_increment(pStubMsg, bufsize);
2206 pStubMsg->MemorySize += memsize;
2207 break;
2208 default:
2209 ERR("unknown array format 0x%x\n", fc);
2210 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2214 static inline void array_free(
2215 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2216 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2218 switch (fc)
2220 case RPC_FC_CARRAY:
2221 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2222 if (fHasPointers)
2223 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2224 break;
2225 case RPC_FC_CVARRAY:
2226 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2227 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2228 if (fHasPointers)
2229 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2230 break;
2231 case RPC_FC_C_CSTRING:
2232 case RPC_FC_C_WSTRING:
2233 /* No embedded pointers so nothing to do */
2234 break;
2235 default:
2236 ERR("unknown array format 0x%x\n", fc);
2237 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2242 * NdrConformantString:
2244 * What MS calls a ConformantString is, in DCE terminology,
2245 * a Varying-Conformant String.
2247 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2248 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2249 * into unmarshalled string)
2250 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2252 * data: CHARTYPE[maxlen]
2254 * ], where CHARTYPE is the appropriate character type (specified externally)
2258 /***********************************************************************
2259 * NdrConformantStringMarshall [RPCRT4.@]
2261 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2262 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2264 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2266 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2267 ERR("Unhandled string type: %#x\n", pFormat[0]);
2268 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2271 /* allow compiler to optimise inline function by passing constant into
2272 * these functions */
2273 if (pFormat[0] == RPC_FC_C_CSTRING) {
2274 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2275 pFormat);
2276 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2277 pFormat, TRUE /* fHasPointers */);
2278 } else {
2279 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2280 pFormat);
2281 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2282 pFormat, TRUE /* fHasPointers */);
2285 return NULL;
2288 /***********************************************************************
2289 * NdrConformantStringBufferSize [RPCRT4.@]
2291 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2292 unsigned char* pMemory, PFORMAT_STRING pFormat)
2294 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2296 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2297 ERR("Unhandled string type: %#x\n", pFormat[0]);
2298 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2301 /* allow compiler to optimise inline function by passing constant into
2302 * these functions */
2303 if (pFormat[0] == RPC_FC_C_CSTRING) {
2304 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2305 pFormat);
2306 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2307 TRUE /* fHasPointers */);
2308 } else {
2309 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2310 pFormat);
2311 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2312 TRUE /* fHasPointers */);
2316 /************************************************************************
2317 * NdrConformantStringMemorySize [RPCRT4.@]
2319 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2320 PFORMAT_STRING pFormat )
2322 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2324 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2325 ERR("Unhandled string type: %#x\n", pFormat[0]);
2326 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2329 /* allow compiler to optimise inline function by passing constant into
2330 * these functions */
2331 if (pFormat[0] == RPC_FC_C_CSTRING) {
2332 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2333 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2334 TRUE /* fHasPointers */);
2335 } else {
2336 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2337 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2338 TRUE /* fHasPointers */);
2341 return pStubMsg->MemorySize;
2344 /************************************************************************
2345 * NdrConformantStringUnmarshall [RPCRT4.@]
2347 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2348 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2350 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2351 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2353 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2354 ERR("Unhandled string type: %#x\n", *pFormat);
2355 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2358 /* allow compiler to optimise inline function by passing constant into
2359 * these functions */
2360 if (pFormat[0] == RPC_FC_C_CSTRING) {
2361 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2362 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2363 pFormat, fMustAlloc,
2364 TRUE /* fUseBufferMemoryServer */,
2365 TRUE /* fUnmarshall */);
2366 } else {
2367 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2368 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2369 pFormat, fMustAlloc,
2370 TRUE /* fUseBufferMemoryServer */,
2371 TRUE /* fUnmarshall */);
2374 return NULL;
2377 /***********************************************************************
2378 * NdrNonConformantStringMarshall [RPCRT4.@]
2380 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2381 unsigned char *pMemory,
2382 PFORMAT_STRING pFormat)
2384 ULONG esize, size, maxsize;
2386 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2388 maxsize = *(USHORT *)&pFormat[2];
2390 if (*pFormat == RPC_FC_CSTRING)
2392 ULONG i;
2393 const char *str = (const char *)pMemory;
2394 for (i = 0; i < maxsize && *str; i++, str++)
2396 TRACE("string=%s\n", debugstr_an(str, i));
2397 pStubMsg->ActualCount = i + 1;
2398 esize = 1;
2400 else if (*pFormat == RPC_FC_WSTRING)
2402 ULONG i;
2403 const WCHAR *str = (const WCHAR *)pMemory;
2404 for (i = 0; i < maxsize && *str; i++, str++)
2406 TRACE("string=%s\n", debugstr_wn(str, i));
2407 pStubMsg->ActualCount = i + 1;
2408 esize = 2;
2410 else
2412 ERR("Unhandled string type: %#x\n", *pFormat);
2413 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2416 pStubMsg->Offset = 0;
2417 WriteVariance(pStubMsg);
2419 size = safe_multiply(esize, pStubMsg->ActualCount);
2420 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2422 return NULL;
2425 /***********************************************************************
2426 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2428 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2429 unsigned char **ppMemory,
2430 PFORMAT_STRING pFormat,
2431 unsigned char fMustAlloc)
2433 ULONG bufsize, memsize, esize, maxsize;
2435 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2436 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2438 maxsize = *(USHORT *)&pFormat[2];
2440 ReadVariance(pStubMsg, NULL, maxsize);
2441 if (pStubMsg->Offset)
2443 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2444 RpcRaiseException(RPC_S_INVALID_BOUND);
2447 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2448 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2449 else
2451 ERR("Unhandled string type: %#x\n", *pFormat);
2452 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2455 memsize = esize * maxsize;
2456 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2458 validate_string_data(pStubMsg, bufsize, esize);
2460 if (!fMustAlloc && !*ppMemory)
2461 fMustAlloc = TRUE;
2462 if (fMustAlloc)
2463 *ppMemory = NdrAllocate(pStubMsg, memsize);
2465 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2467 if (*pFormat == RPC_FC_CSTRING) {
2468 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2470 else if (*pFormat == RPC_FC_WSTRING) {
2471 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2474 return NULL;
2477 /***********************************************************************
2478 * NdrNonConformantStringBufferSize [RPCRT4.@]
2480 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2481 unsigned char *pMemory,
2482 PFORMAT_STRING pFormat)
2484 ULONG esize, maxsize;
2486 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2488 maxsize = *(USHORT *)&pFormat[2];
2490 SizeVariance(pStubMsg);
2492 if (*pFormat == RPC_FC_CSTRING)
2494 ULONG i;
2495 const char *str = (const char *)pMemory;
2496 for (i = 0; i < maxsize && *str; i++, str++)
2498 TRACE("string=%s\n", debugstr_an(str, i));
2499 pStubMsg->ActualCount = i + 1;
2500 esize = 1;
2502 else if (*pFormat == RPC_FC_WSTRING)
2504 ULONG i;
2505 const WCHAR *str = (const WCHAR *)pMemory;
2506 for (i = 0; i < maxsize && *str; i++, str++)
2508 TRACE("string=%s\n", debugstr_wn(str, i));
2509 pStubMsg->ActualCount = i + 1;
2510 esize = 2;
2512 else
2514 ERR("Unhandled string type: %#x\n", *pFormat);
2515 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2518 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2521 /***********************************************************************
2522 * NdrNonConformantStringMemorySize [RPCRT4.@]
2524 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2525 PFORMAT_STRING pFormat)
2527 ULONG bufsize, memsize, esize, maxsize;
2529 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2531 maxsize = *(USHORT *)&pFormat[2];
2533 ReadVariance(pStubMsg, NULL, maxsize);
2535 if (pStubMsg->Offset)
2537 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2538 RpcRaiseException(RPC_S_INVALID_BOUND);
2541 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2542 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2543 else
2545 ERR("Unhandled string type: %#x\n", *pFormat);
2546 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2549 memsize = esize * maxsize;
2550 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2552 validate_string_data(pStubMsg, bufsize, esize);
2554 safe_buffer_increment(pStubMsg, bufsize);
2555 pStubMsg->MemorySize += memsize;
2557 return pStubMsg->MemorySize;
2560 /* Complex types */
2562 #include "pshpack1.h"
2563 typedef struct
2565 unsigned char type;
2566 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2567 ULONG low_value;
2568 ULONG high_value;
2569 } NDR_RANGE;
2570 #include "poppack.h"
2572 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2573 PFORMAT_STRING pFormat)
2575 switch (*pFormat) {
2576 case RPC_FC_STRUCT:
2577 case RPC_FC_PSTRUCT:
2578 case RPC_FC_CSTRUCT:
2579 case RPC_FC_BOGUS_STRUCT:
2580 case RPC_FC_SMFARRAY:
2581 case RPC_FC_SMVARRAY:
2582 case RPC_FC_CSTRING:
2583 return *(const WORD*)&pFormat[2];
2584 case RPC_FC_USER_MARSHAL:
2585 return *(const WORD*)&pFormat[4];
2586 case RPC_FC_RANGE: {
2587 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2588 case RPC_FC_BYTE:
2589 case RPC_FC_CHAR:
2590 case RPC_FC_SMALL:
2591 case RPC_FC_USMALL:
2592 return sizeof(UCHAR);
2593 case RPC_FC_WCHAR:
2594 case RPC_FC_SHORT:
2595 case RPC_FC_USHORT:
2596 return sizeof(USHORT);
2597 case RPC_FC_LONG:
2598 case RPC_FC_ULONG:
2599 case RPC_FC_ENUM32:
2600 return sizeof(ULONG);
2601 case RPC_FC_FLOAT:
2602 return sizeof(float);
2603 case RPC_FC_DOUBLE:
2604 return sizeof(double);
2605 case RPC_FC_HYPER:
2606 return sizeof(ULONGLONG);
2607 case RPC_FC_ENUM16:
2608 return sizeof(UINT);
2609 default:
2610 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2611 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2614 case RPC_FC_NON_ENCAPSULATED_UNION:
2615 pFormat += 2;
2616 if (pStubMsg->fHasNewCorrDesc)
2617 pFormat += 6;
2618 else
2619 pFormat += 4;
2621 pFormat += *(const SHORT*)pFormat;
2622 return *(const SHORT*)pFormat;
2623 case RPC_FC_IP:
2624 return sizeof(void *);
2625 case RPC_FC_WSTRING:
2626 return *(const WORD*)&pFormat[2] * 2;
2627 default:
2628 FIXME("unhandled embedded type %02x\n", *pFormat);
2630 return 0;
2634 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2635 PFORMAT_STRING pFormat)
2637 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2639 if (!m)
2641 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2642 return 0;
2645 return m(pStubMsg, pFormat);
2649 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2650 unsigned char *pMemory,
2651 PFORMAT_STRING pFormat,
2652 PFORMAT_STRING pPointer)
2654 PFORMAT_STRING desc;
2655 NDR_MARSHALL m;
2656 unsigned long size;
2658 while (*pFormat != RPC_FC_END) {
2659 switch (*pFormat) {
2660 case RPC_FC_BYTE:
2661 case RPC_FC_CHAR:
2662 case RPC_FC_SMALL:
2663 case RPC_FC_USMALL:
2664 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2665 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2666 pMemory += 1;
2667 break;
2668 case RPC_FC_WCHAR:
2669 case RPC_FC_SHORT:
2670 case RPC_FC_USHORT:
2671 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2672 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2673 pMemory += 2;
2674 break;
2675 case RPC_FC_ENUM16:
2676 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2677 if (32767 < *(DWORD*)pMemory)
2678 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2679 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2680 pMemory += 4;
2681 break;
2682 case RPC_FC_LONG:
2683 case RPC_FC_ULONG:
2684 case RPC_FC_ENUM32:
2685 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2686 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2687 pMemory += 4;
2688 break;
2689 case RPC_FC_HYPER:
2690 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2691 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2692 pMemory += 8;
2693 break;
2694 case RPC_FC_POINTER:
2696 unsigned char *saved_buffer;
2697 int pointer_buffer_mark_set = 0;
2698 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2699 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2700 if (*pPointer != RPC_FC_RP)
2701 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2702 saved_buffer = pStubMsg->Buffer;
2703 if (pStubMsg->PointerBufferMark)
2705 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2706 pStubMsg->PointerBufferMark = NULL;
2707 pointer_buffer_mark_set = 1;
2709 else if (*pPointer != RPC_FC_RP)
2710 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2711 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2712 if (pointer_buffer_mark_set)
2714 STD_OVERFLOW_CHECK(pStubMsg);
2715 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2716 pStubMsg->Buffer = saved_buffer;
2717 if (*pPointer != RPC_FC_RP)
2718 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2720 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2721 pPointer += 4;
2722 pMemory += 4;
2723 break;
2725 case RPC_FC_ALIGNM4:
2726 ALIGN_POINTER(pMemory, 4);
2727 break;
2728 case RPC_FC_ALIGNM8:
2729 ALIGN_POINTER(pMemory, 8);
2730 break;
2731 case RPC_FC_STRUCTPAD1:
2732 case RPC_FC_STRUCTPAD2:
2733 case RPC_FC_STRUCTPAD3:
2734 case RPC_FC_STRUCTPAD4:
2735 case RPC_FC_STRUCTPAD5:
2736 case RPC_FC_STRUCTPAD6:
2737 case RPC_FC_STRUCTPAD7:
2738 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2739 break;
2740 case RPC_FC_EMBEDDED_COMPLEX:
2741 pMemory += pFormat[1];
2742 pFormat += 2;
2743 desc = pFormat + *(const SHORT*)pFormat;
2744 size = EmbeddedComplexSize(pStubMsg, desc);
2745 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2746 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2747 if (m)
2749 /* for some reason interface pointers aren't generated as
2750 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2751 * they still need the derefencing treatment that pointers are
2752 * given */
2753 if (*desc == RPC_FC_IP)
2754 m(pStubMsg, *(unsigned char **)pMemory, desc);
2755 else
2756 m(pStubMsg, pMemory, desc);
2758 else FIXME("no marshaller for embedded type %02x\n", *desc);
2759 pMemory += size;
2760 pFormat += 2;
2761 continue;
2762 case RPC_FC_PAD:
2763 break;
2764 default:
2765 FIXME("unhandled format 0x%02x\n", *pFormat);
2767 pFormat++;
2770 return pMemory;
2773 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2774 unsigned char *pMemory,
2775 PFORMAT_STRING pFormat,
2776 PFORMAT_STRING pPointer,
2777 unsigned char fMustAlloc)
2779 PFORMAT_STRING desc;
2780 NDR_UNMARSHALL m;
2781 unsigned long size;
2783 while (*pFormat != RPC_FC_END) {
2784 switch (*pFormat) {
2785 case RPC_FC_BYTE:
2786 case RPC_FC_CHAR:
2787 case RPC_FC_SMALL:
2788 case RPC_FC_USMALL:
2789 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2790 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2791 pMemory += 1;
2792 break;
2793 case RPC_FC_WCHAR:
2794 case RPC_FC_SHORT:
2795 case RPC_FC_USHORT:
2796 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2797 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2798 pMemory += 2;
2799 break;
2800 case RPC_FC_ENUM16:
2801 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2802 *(DWORD*)pMemory &= 0xffff;
2803 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2804 if (32767 < *(DWORD*)pMemory)
2805 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2806 pMemory += 4;
2807 break;
2808 case RPC_FC_LONG:
2809 case RPC_FC_ULONG:
2810 case RPC_FC_ENUM32:
2811 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2812 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2813 pMemory += 4;
2814 break;
2815 case RPC_FC_HYPER:
2816 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2817 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2818 pMemory += 8;
2819 break;
2820 case RPC_FC_POINTER:
2822 unsigned char *saved_buffer;
2823 int pointer_buffer_mark_set = 0;
2824 TRACE("pointer => %p\n", pMemory);
2825 if (*pPointer != RPC_FC_RP)
2826 ALIGN_POINTER(pStubMsg->Buffer, 4);
2827 saved_buffer = pStubMsg->Buffer;
2828 if (pStubMsg->PointerBufferMark)
2830 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2831 pStubMsg->PointerBufferMark = NULL;
2832 pointer_buffer_mark_set = 1;
2834 else if (*pPointer != RPC_FC_RP)
2835 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2837 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2838 if (pointer_buffer_mark_set)
2840 STD_OVERFLOW_CHECK(pStubMsg);
2841 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2842 pStubMsg->Buffer = saved_buffer;
2843 if (*pPointer != RPC_FC_RP)
2844 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2846 pPointer += 4;
2847 pMemory += 4;
2848 break;
2850 case RPC_FC_ALIGNM4:
2851 ALIGN_POINTER_CLEAR(pMemory, 4);
2852 break;
2853 case RPC_FC_ALIGNM8:
2854 ALIGN_POINTER_CLEAR(pMemory, 8);
2855 break;
2856 case RPC_FC_STRUCTPAD1:
2857 case RPC_FC_STRUCTPAD2:
2858 case RPC_FC_STRUCTPAD3:
2859 case RPC_FC_STRUCTPAD4:
2860 case RPC_FC_STRUCTPAD5:
2861 case RPC_FC_STRUCTPAD6:
2862 case RPC_FC_STRUCTPAD7:
2863 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2864 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2865 break;
2866 case RPC_FC_EMBEDDED_COMPLEX:
2867 pMemory += pFormat[1];
2868 pFormat += 2;
2869 desc = pFormat + *(const SHORT*)pFormat;
2870 size = EmbeddedComplexSize(pStubMsg, desc);
2871 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2872 if (fMustAlloc)
2873 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2874 * since the type is part of the memory block that is encompassed by
2875 * the whole complex type. Memory is forced to allocate when pointers
2876 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2877 * clearing the memory we pass in to the unmarshaller */
2878 memset(pMemory, 0, size);
2879 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2880 if (m)
2882 /* for some reason interface pointers aren't generated as
2883 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2884 * they still need the derefencing treatment that pointers are
2885 * given */
2886 if (*desc == RPC_FC_IP)
2887 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2888 else
2889 m(pStubMsg, &pMemory, desc, FALSE);
2891 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2892 pMemory += size;
2893 pFormat += 2;
2894 continue;
2895 case RPC_FC_PAD:
2896 break;
2897 default:
2898 FIXME("unhandled format %d\n", *pFormat);
2900 pFormat++;
2903 return pMemory;
2906 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2907 unsigned char *pMemory,
2908 PFORMAT_STRING pFormat,
2909 PFORMAT_STRING pPointer)
2911 PFORMAT_STRING desc;
2912 NDR_BUFFERSIZE m;
2913 unsigned long size;
2915 while (*pFormat != RPC_FC_END) {
2916 switch (*pFormat) {
2917 case RPC_FC_BYTE:
2918 case RPC_FC_CHAR:
2919 case RPC_FC_SMALL:
2920 case RPC_FC_USMALL:
2921 safe_buffer_length_increment(pStubMsg, 1);
2922 pMemory += 1;
2923 break;
2924 case RPC_FC_WCHAR:
2925 case RPC_FC_SHORT:
2926 case RPC_FC_USHORT:
2927 safe_buffer_length_increment(pStubMsg, 2);
2928 pMemory += 2;
2929 break;
2930 case RPC_FC_ENUM16:
2931 safe_buffer_length_increment(pStubMsg, 2);
2932 pMemory += 4;
2933 break;
2934 case RPC_FC_LONG:
2935 case RPC_FC_ULONG:
2936 case RPC_FC_ENUM32:
2937 safe_buffer_length_increment(pStubMsg, 4);
2938 pMemory += 4;
2939 break;
2940 case RPC_FC_HYPER:
2941 safe_buffer_length_increment(pStubMsg, 8);
2942 pMemory += 8;
2943 break;
2944 case RPC_FC_POINTER:
2945 if (!pStubMsg->IgnoreEmbeddedPointers)
2947 int saved_buffer_length = pStubMsg->BufferLength;
2948 pStubMsg->BufferLength = pStubMsg->PointerLength;
2949 pStubMsg->PointerLength = 0;
2950 if(!pStubMsg->BufferLength)
2951 ERR("BufferLength == 0??\n");
2952 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2953 pStubMsg->PointerLength = pStubMsg->BufferLength;
2954 pStubMsg->BufferLength = saved_buffer_length;
2956 if (*pPointer != RPC_FC_RP)
2958 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2959 safe_buffer_length_increment(pStubMsg, 4);
2961 pPointer += 4;
2962 pMemory += 4;
2963 break;
2964 case RPC_FC_ALIGNM4:
2965 ALIGN_POINTER(pMemory, 4);
2966 break;
2967 case RPC_FC_ALIGNM8:
2968 ALIGN_POINTER(pMemory, 8);
2969 break;
2970 case RPC_FC_STRUCTPAD1:
2971 case RPC_FC_STRUCTPAD2:
2972 case RPC_FC_STRUCTPAD3:
2973 case RPC_FC_STRUCTPAD4:
2974 case RPC_FC_STRUCTPAD5:
2975 case RPC_FC_STRUCTPAD6:
2976 case RPC_FC_STRUCTPAD7:
2977 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2978 break;
2979 case RPC_FC_EMBEDDED_COMPLEX:
2980 pMemory += pFormat[1];
2981 pFormat += 2;
2982 desc = pFormat + *(const SHORT*)pFormat;
2983 size = EmbeddedComplexSize(pStubMsg, desc);
2984 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2985 if (m)
2987 /* for some reason interface pointers aren't generated as
2988 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2989 * they still need the derefencing treatment that pointers are
2990 * given */
2991 if (*desc == RPC_FC_IP)
2992 m(pStubMsg, *(unsigned char **)pMemory, desc);
2993 else
2994 m(pStubMsg, pMemory, desc);
2996 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2997 pMemory += size;
2998 pFormat += 2;
2999 continue;
3000 case RPC_FC_PAD:
3001 break;
3002 default:
3003 FIXME("unhandled format 0x%02x\n", *pFormat);
3005 pFormat++;
3008 return pMemory;
3011 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3012 unsigned char *pMemory,
3013 PFORMAT_STRING pFormat,
3014 PFORMAT_STRING pPointer)
3016 PFORMAT_STRING desc;
3017 NDR_FREE m;
3018 unsigned long size;
3020 while (*pFormat != RPC_FC_END) {
3021 switch (*pFormat) {
3022 case RPC_FC_BYTE:
3023 case RPC_FC_CHAR:
3024 case RPC_FC_SMALL:
3025 case RPC_FC_USMALL:
3026 pMemory += 1;
3027 break;
3028 case RPC_FC_WCHAR:
3029 case RPC_FC_SHORT:
3030 case RPC_FC_USHORT:
3031 pMemory += 2;
3032 break;
3033 case RPC_FC_LONG:
3034 case RPC_FC_ULONG:
3035 case RPC_FC_ENUM16:
3036 case RPC_FC_ENUM32:
3037 pMemory += 4;
3038 break;
3039 case RPC_FC_HYPER:
3040 pMemory += 8;
3041 break;
3042 case RPC_FC_POINTER:
3043 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3044 pPointer += 4;
3045 pMemory += 4;
3046 break;
3047 case RPC_FC_ALIGNM4:
3048 ALIGN_POINTER(pMemory, 4);
3049 break;
3050 case RPC_FC_ALIGNM8:
3051 ALIGN_POINTER(pMemory, 8);
3052 break;
3053 case RPC_FC_STRUCTPAD1:
3054 case RPC_FC_STRUCTPAD2:
3055 case RPC_FC_STRUCTPAD3:
3056 case RPC_FC_STRUCTPAD4:
3057 case RPC_FC_STRUCTPAD5:
3058 case RPC_FC_STRUCTPAD6:
3059 case RPC_FC_STRUCTPAD7:
3060 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3061 break;
3062 case RPC_FC_EMBEDDED_COMPLEX:
3063 pMemory += pFormat[1];
3064 pFormat += 2;
3065 desc = pFormat + *(const SHORT*)pFormat;
3066 size = EmbeddedComplexSize(pStubMsg, desc);
3067 m = NdrFreer[*desc & NDR_TABLE_MASK];
3068 if (m)
3070 /* for some reason interface pointers aren't generated as
3071 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3072 * they still need the derefencing treatment that pointers are
3073 * given */
3074 if (*desc == RPC_FC_IP)
3075 m(pStubMsg, *(unsigned char **)pMemory, desc);
3076 else
3077 m(pStubMsg, pMemory, desc);
3079 pMemory += size;
3080 pFormat += 2;
3081 continue;
3082 case RPC_FC_PAD:
3083 break;
3084 default:
3085 FIXME("unhandled format 0x%02x\n", *pFormat);
3087 pFormat++;
3090 return pMemory;
3093 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3094 PFORMAT_STRING pFormat,
3095 PFORMAT_STRING pPointer)
3097 PFORMAT_STRING desc;
3098 unsigned long size = 0;
3100 while (*pFormat != RPC_FC_END) {
3101 switch (*pFormat) {
3102 case RPC_FC_BYTE:
3103 case RPC_FC_CHAR:
3104 case RPC_FC_SMALL:
3105 case RPC_FC_USMALL:
3106 size += 1;
3107 safe_buffer_increment(pStubMsg, 1);
3108 break;
3109 case RPC_FC_WCHAR:
3110 case RPC_FC_SHORT:
3111 case RPC_FC_USHORT:
3112 size += 2;
3113 safe_buffer_increment(pStubMsg, 2);
3114 break;
3115 case RPC_FC_ENUM16:
3116 size += 4;
3117 safe_buffer_increment(pStubMsg, 2);
3118 break;
3119 case RPC_FC_LONG:
3120 case RPC_FC_ULONG:
3121 case RPC_FC_ENUM32:
3122 size += 4;
3123 safe_buffer_increment(pStubMsg, 4);
3124 break;
3125 case RPC_FC_HYPER:
3126 size += 8;
3127 safe_buffer_increment(pStubMsg, 8);
3128 break;
3129 case RPC_FC_POINTER:
3131 unsigned char *saved_buffer;
3132 int pointer_buffer_mark_set = 0;
3133 if (*pPointer != RPC_FC_RP)
3134 ALIGN_POINTER(pStubMsg->Buffer, 4);
3135 saved_buffer = pStubMsg->Buffer;
3136 if (pStubMsg->PointerBufferMark)
3138 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3139 pStubMsg->PointerBufferMark = NULL;
3140 pointer_buffer_mark_set = 1;
3142 else if (*pPointer != RPC_FC_RP)
3143 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3145 if (!pStubMsg->IgnoreEmbeddedPointers)
3146 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3147 if (pointer_buffer_mark_set)
3149 STD_OVERFLOW_CHECK(pStubMsg);
3150 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3151 pStubMsg->Buffer = saved_buffer;
3152 if (*pPointer != RPC_FC_RP)
3153 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3155 pPointer += 4;
3156 size += 4;
3157 break;
3159 case RPC_FC_ALIGNM4:
3160 ALIGN_LENGTH(size, 4);
3161 break;
3162 case RPC_FC_ALIGNM8:
3163 ALIGN_LENGTH(size, 8);
3164 break;
3165 case RPC_FC_STRUCTPAD1:
3166 case RPC_FC_STRUCTPAD2:
3167 case RPC_FC_STRUCTPAD3:
3168 case RPC_FC_STRUCTPAD4:
3169 case RPC_FC_STRUCTPAD5:
3170 case RPC_FC_STRUCTPAD6:
3171 case RPC_FC_STRUCTPAD7:
3172 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3173 break;
3174 case RPC_FC_EMBEDDED_COMPLEX:
3175 size += pFormat[1];
3176 pFormat += 2;
3177 desc = pFormat + *(const SHORT*)pFormat;
3178 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3179 pFormat += 2;
3180 continue;
3181 case RPC_FC_PAD:
3182 break;
3183 default:
3184 FIXME("unhandled format 0x%02x\n", *pFormat);
3186 pFormat++;
3189 return size;
3192 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
3193 PFORMAT_STRING pFormat)
3195 PFORMAT_STRING desc;
3196 unsigned long size = 0;
3198 while (*pFormat != RPC_FC_END) {
3199 switch (*pFormat) {
3200 case RPC_FC_BYTE:
3201 case RPC_FC_CHAR:
3202 case RPC_FC_SMALL:
3203 case RPC_FC_USMALL:
3204 size += 1;
3205 break;
3206 case RPC_FC_WCHAR:
3207 case RPC_FC_SHORT:
3208 case RPC_FC_USHORT:
3209 size += 2;
3210 break;
3211 case RPC_FC_LONG:
3212 case RPC_FC_ULONG:
3213 case RPC_FC_ENUM16:
3214 case RPC_FC_ENUM32:
3215 size += 4;
3216 break;
3217 case RPC_FC_HYPER:
3218 size += 8;
3219 break;
3220 case RPC_FC_POINTER:
3221 size += sizeof(void *);
3222 break;
3223 case RPC_FC_ALIGNM4:
3224 ALIGN_LENGTH(size, 4);
3225 break;
3226 case RPC_FC_ALIGNM8:
3227 ALIGN_LENGTH(size, 8);
3228 break;
3229 case RPC_FC_STRUCTPAD1:
3230 case RPC_FC_STRUCTPAD2:
3231 case RPC_FC_STRUCTPAD3:
3232 case RPC_FC_STRUCTPAD4:
3233 case RPC_FC_STRUCTPAD5:
3234 case RPC_FC_STRUCTPAD6:
3235 case RPC_FC_STRUCTPAD7:
3236 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3237 break;
3238 case RPC_FC_EMBEDDED_COMPLEX:
3239 size += pFormat[1];
3240 pFormat += 2;
3241 desc = pFormat + *(const SHORT*)pFormat;
3242 size += EmbeddedComplexSize(pStubMsg, desc);
3243 pFormat += 2;
3244 continue;
3245 case RPC_FC_PAD:
3246 break;
3247 default:
3248 FIXME("unhandled format 0x%02x\n", *pFormat);
3250 pFormat++;
3253 return size;
3256 /***********************************************************************
3257 * NdrComplexStructMarshall [RPCRT4.@]
3259 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3260 unsigned char *pMemory,
3261 PFORMAT_STRING pFormat)
3263 PFORMAT_STRING conf_array = NULL;
3264 PFORMAT_STRING pointer_desc = NULL;
3265 unsigned char *OldMemory = pStubMsg->Memory;
3266 int pointer_buffer_mark_set = 0;
3267 ULONG count = 0;
3268 ULONG max_count = 0;
3269 ULONG offset = 0;
3271 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3273 if (!pStubMsg->PointerBufferMark)
3275 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3276 /* save buffer length */
3277 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3279 /* get the buffer pointer after complex array data, but before
3280 * pointer data */
3281 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3282 pStubMsg->IgnoreEmbeddedPointers = 1;
3283 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3284 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3286 /* save it for use by embedded pointer code later */
3287 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3288 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
3289 pointer_buffer_mark_set = 1;
3291 /* restore the original buffer length */
3292 pStubMsg->BufferLength = saved_buffer_length;
3295 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3297 pFormat += 4;
3298 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3299 pFormat += 2;
3300 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3301 pFormat += 2;
3303 pStubMsg->Memory = pMemory;
3305 if (conf_array)
3307 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3308 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3309 pMemory + struct_size, conf_array);
3310 /* these could be changed in ComplexMarshall so save them for later */
3311 max_count = pStubMsg->MaxCount;
3312 count = pStubMsg->ActualCount;
3313 offset = pStubMsg->Offset;
3316 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3318 if (conf_array)
3320 pStubMsg->MaxCount = max_count;
3321 pStubMsg->ActualCount = count;
3322 pStubMsg->Offset = offset;
3323 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3324 conf_array, TRUE /* fHasPointers */);
3327 pStubMsg->Memory = OldMemory;
3329 if (pointer_buffer_mark_set)
3331 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3332 pStubMsg->PointerBufferMark = NULL;
3335 STD_OVERFLOW_CHECK(pStubMsg);
3337 return NULL;
3340 /***********************************************************************
3341 * NdrComplexStructUnmarshall [RPCRT4.@]
3343 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3344 unsigned char **ppMemory,
3345 PFORMAT_STRING pFormat,
3346 unsigned char fMustAlloc)
3348 unsigned size = *(const WORD*)(pFormat+2);
3349 PFORMAT_STRING conf_array = NULL;
3350 PFORMAT_STRING pointer_desc = NULL;
3351 unsigned char *pMemory;
3352 int pointer_buffer_mark_set = 0;
3353 ULONG count = 0;
3354 ULONG max_count = 0;
3355 ULONG offset = 0;
3356 ULONG array_size = 0;
3358 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3360 if (!pStubMsg->PointerBufferMark)
3362 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3363 /* save buffer pointer */
3364 unsigned char *saved_buffer = pStubMsg->Buffer;
3366 /* get the buffer pointer after complex array data, but before
3367 * pointer data */
3368 pStubMsg->IgnoreEmbeddedPointers = 1;
3369 NdrComplexStructMemorySize(pStubMsg, pFormat);
3370 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3372 /* save it for use by embedded pointer code later */
3373 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3374 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
3375 pointer_buffer_mark_set = 1;
3377 /* restore the original buffer */
3378 pStubMsg->Buffer = saved_buffer;
3381 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3383 pFormat += 4;
3384 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3385 pFormat += 2;
3386 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3387 pFormat += 2;
3389 if (conf_array)
3391 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3392 size += array_size;
3394 /* these could be changed in ComplexMarshall so save them for later */
3395 max_count = pStubMsg->MaxCount;
3396 count = pStubMsg->ActualCount;
3397 offset = pStubMsg->Offset;
3400 if (!fMustAlloc && !*ppMemory)
3401 fMustAlloc = TRUE;
3402 if (fMustAlloc)
3403 *ppMemory = NdrAllocate(pStubMsg, size);
3405 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3407 if (conf_array)
3409 pStubMsg->MaxCount = max_count;
3410 pStubMsg->ActualCount = count;
3411 pStubMsg->Offset = offset;
3412 if (fMustAlloc)
3413 memset(pMemory, 0, array_size);
3414 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3415 conf_array, FALSE,
3416 FALSE /* fUseBufferMemoryServer */,
3417 TRUE /* fUnmarshall */);
3420 if (pointer_buffer_mark_set)
3422 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3423 pStubMsg->PointerBufferMark = NULL;
3426 return NULL;
3429 /***********************************************************************
3430 * NdrComplexStructBufferSize [RPCRT4.@]
3432 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3433 unsigned char *pMemory,
3434 PFORMAT_STRING pFormat)
3436 PFORMAT_STRING conf_array = NULL;
3437 PFORMAT_STRING pointer_desc = NULL;
3438 unsigned char *OldMemory = pStubMsg->Memory;
3439 int pointer_length_set = 0;
3440 ULONG count = 0;
3441 ULONG max_count = 0;
3442 ULONG offset = 0;
3444 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3446 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3448 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3450 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3451 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3453 /* get the buffer length after complex struct data, but before
3454 * pointer data */
3455 pStubMsg->IgnoreEmbeddedPointers = 1;
3456 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3457 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3459 /* save it for use by embedded pointer code later */
3460 pStubMsg->PointerLength = pStubMsg->BufferLength;
3461 pointer_length_set = 1;
3462 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
3464 /* restore the original buffer length */
3465 pStubMsg->BufferLength = saved_buffer_length;
3468 pFormat += 4;
3469 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3470 pFormat += 2;
3471 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3472 pFormat += 2;
3474 pStubMsg->Memory = pMemory;
3476 if (conf_array)
3478 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3479 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3480 conf_array);
3482 /* these could be changed in ComplexMarshall so save them for later */
3483 max_count = pStubMsg->MaxCount;
3484 count = pStubMsg->ActualCount;
3485 offset = pStubMsg->Offset;
3488 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3490 if (conf_array)
3492 pStubMsg->MaxCount = max_count;
3493 pStubMsg->ActualCount = count;
3494 pStubMsg->Offset = offset;
3495 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3496 TRUE /* fHasPointers */);
3499 pStubMsg->Memory = OldMemory;
3501 if(pointer_length_set)
3503 pStubMsg->BufferLength = pStubMsg->PointerLength;
3504 pStubMsg->PointerLength = 0;
3509 /***********************************************************************
3510 * NdrComplexStructMemorySize [RPCRT4.@]
3512 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3513 PFORMAT_STRING pFormat)
3515 unsigned size = *(const WORD*)(pFormat+2);
3516 PFORMAT_STRING conf_array = NULL;
3517 PFORMAT_STRING pointer_desc = NULL;
3518 ULONG count = 0;
3519 ULONG max_count = 0;
3520 ULONG offset = 0;
3522 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3524 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3526 pFormat += 4;
3527 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3528 pFormat += 2;
3529 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3530 pFormat += 2;
3532 if (conf_array)
3534 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3536 /* these could be changed in ComplexStructMemorySize so save them for
3537 * later */
3538 max_count = pStubMsg->MaxCount;
3539 count = pStubMsg->ActualCount;
3540 offset = pStubMsg->Offset;
3543 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3545 if (conf_array)
3547 pStubMsg->MaxCount = max_count;
3548 pStubMsg->ActualCount = count;
3549 pStubMsg->Offset = offset;
3550 array_memory_size(conf_array[0], pStubMsg, conf_array,
3551 TRUE /* fHasPointers */);
3554 return size;
3557 /***********************************************************************
3558 * NdrComplexStructFree [RPCRT4.@]
3560 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3561 unsigned char *pMemory,
3562 PFORMAT_STRING pFormat)
3564 PFORMAT_STRING conf_array = NULL;
3565 PFORMAT_STRING pointer_desc = NULL;
3566 unsigned char *OldMemory = pStubMsg->Memory;
3568 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3570 pFormat += 4;
3571 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3572 pFormat += 2;
3573 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3574 pFormat += 2;
3576 pStubMsg->Memory = pMemory;
3578 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3580 if (conf_array)
3581 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3582 TRUE /* fHasPointers */);
3584 pStubMsg->Memory = OldMemory;
3587 /***********************************************************************
3588 * NdrConformantArrayMarshall [RPCRT4.@]
3590 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3591 unsigned char *pMemory,
3592 PFORMAT_STRING pFormat)
3594 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3595 if (pFormat[0] != RPC_FC_CARRAY)
3597 ERR("invalid format = 0x%x\n", pFormat[0]);
3598 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3601 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3602 pFormat);
3603 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3604 TRUE /* fHasPointers */);
3606 return NULL;
3609 /***********************************************************************
3610 * NdrConformantArrayUnmarshall [RPCRT4.@]
3612 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3613 unsigned char **ppMemory,
3614 PFORMAT_STRING pFormat,
3615 unsigned char fMustAlloc)
3617 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3618 if (pFormat[0] != RPC_FC_CARRAY)
3620 ERR("invalid format = 0x%x\n", pFormat[0]);
3621 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3624 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3625 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3626 fMustAlloc,
3627 TRUE /* fUseBufferMemoryServer */,
3628 TRUE /* fUnmarshall */);
3630 return NULL;
3633 /***********************************************************************
3634 * NdrConformantArrayBufferSize [RPCRT4.@]
3636 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3637 unsigned char *pMemory,
3638 PFORMAT_STRING pFormat)
3640 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3641 if (pFormat[0] != RPC_FC_CARRAY)
3643 ERR("invalid format = 0x%x\n", pFormat[0]);
3644 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3647 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3648 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3649 TRUE /* fHasPointers */);
3652 /***********************************************************************
3653 * NdrConformantArrayMemorySize [RPCRT4.@]
3655 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3656 PFORMAT_STRING pFormat)
3658 TRACE("(%p,%p)\n", pStubMsg, 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_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3666 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3668 return pStubMsg->MemorySize;
3671 /***********************************************************************
3672 * NdrConformantArrayFree [RPCRT4.@]
3674 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3675 unsigned char *pMemory,
3676 PFORMAT_STRING pFormat)
3678 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3679 if (pFormat[0] != RPC_FC_CARRAY)
3681 ERR("invalid format = 0x%x\n", pFormat[0]);
3682 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3685 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3686 TRUE /* fHasPointers */);
3690 /***********************************************************************
3691 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3693 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3694 unsigned char* pMemory,
3695 PFORMAT_STRING pFormat )
3697 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3699 if (pFormat[0] != RPC_FC_CVARRAY)
3701 ERR("invalid format type %x\n", pFormat[0]);
3702 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3703 return NULL;
3706 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3707 pFormat);
3708 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3709 pFormat, TRUE /* fHasPointers */);
3711 return NULL;
3715 /***********************************************************************
3716 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3718 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3719 unsigned char** ppMemory,
3720 PFORMAT_STRING pFormat,
3721 unsigned char fMustAlloc )
3723 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3725 if (pFormat[0] != RPC_FC_CVARRAY)
3727 ERR("invalid format type %x\n", pFormat[0]);
3728 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3729 return NULL;
3732 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3733 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3734 pFormat, fMustAlloc,
3735 TRUE /* fUseBufferMemoryServer */,
3736 TRUE /* fUnmarshall */);
3738 return NULL;
3742 /***********************************************************************
3743 * NdrConformantVaryingArrayFree [RPCRT4.@]
3745 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3746 unsigned char* pMemory,
3747 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_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3759 TRUE /* fHasPointers */);
3763 /***********************************************************************
3764 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3766 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3767 unsigned char* pMemory, PFORMAT_STRING pFormat )
3769 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3771 if (pFormat[0] != RPC_FC_CVARRAY)
3773 ERR("invalid format type %x\n", pFormat[0]);
3774 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3775 return;
3778 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3779 pFormat);
3780 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3781 TRUE /* fHasPointers */);
3785 /***********************************************************************
3786 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3788 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3789 PFORMAT_STRING pFormat )
3791 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3793 if (pFormat[0] != RPC_FC_CVARRAY)
3795 ERR("invalid format type %x\n", pFormat[0]);
3796 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3797 return pStubMsg->MemorySize;
3800 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3801 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3802 TRUE /* fHasPointers */);
3804 return pStubMsg->MemorySize;
3808 /***********************************************************************
3809 * NdrComplexArrayMarshall [RPCRT4.@]
3811 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3812 unsigned char *pMemory,
3813 PFORMAT_STRING pFormat)
3815 ULONG i, count, def;
3816 BOOL variance_present;
3817 unsigned char alignment;
3818 int pointer_buffer_mark_set = 0;
3820 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3822 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3824 ERR("invalid format type %x\n", pFormat[0]);
3825 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3826 return NULL;
3829 alignment = pFormat[1] + 1;
3831 if (!pStubMsg->PointerBufferMark)
3833 /* save buffer fields that may be changed by buffer sizer functions
3834 * and that may be needed later on */
3835 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3836 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3837 unsigned long saved_max_count = pStubMsg->MaxCount;
3838 unsigned long saved_offset = pStubMsg->Offset;
3839 unsigned long saved_actual_count = pStubMsg->ActualCount;
3841 /* get the buffer pointer after complex array data, but before
3842 * pointer data */
3843 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3844 pStubMsg->IgnoreEmbeddedPointers = 1;
3845 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3846 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3848 /* save it for use by embedded pointer code later */
3849 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3850 TRACE("difference = 0x%x\n", pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer);
3851 pointer_buffer_mark_set = 1;
3853 /* restore fields */
3854 pStubMsg->ActualCount = saved_actual_count;
3855 pStubMsg->Offset = saved_offset;
3856 pStubMsg->MaxCount = saved_max_count;
3857 pStubMsg->BufferLength = saved_buffer_length;
3860 def = *(const WORD*)&pFormat[2];
3861 pFormat += 4;
3863 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3864 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3866 variance_present = IsConformanceOrVariancePresent(pFormat);
3867 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3868 TRACE("variance = %d\n", pStubMsg->ActualCount);
3870 WriteConformance(pStubMsg);
3871 if (variance_present)
3872 WriteVariance(pStubMsg);
3874 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3876 count = pStubMsg->ActualCount;
3877 for (i = 0; i < count; i++)
3878 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3880 STD_OVERFLOW_CHECK(pStubMsg);
3882 if (pointer_buffer_mark_set)
3884 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3885 pStubMsg->PointerBufferMark = NULL;
3888 return NULL;
3891 /***********************************************************************
3892 * NdrComplexArrayUnmarshall [RPCRT4.@]
3894 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3895 unsigned char **ppMemory,
3896 PFORMAT_STRING pFormat,
3897 unsigned char fMustAlloc)
3899 ULONG i, count, size;
3900 unsigned char alignment;
3901 unsigned char *pMemory;
3902 unsigned char *saved_buffer;
3903 int pointer_buffer_mark_set = 0;
3904 int saved_ignore_embedded;
3906 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3908 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3910 ERR("invalid format type %x\n", pFormat[0]);
3911 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3912 return NULL;
3915 alignment = pFormat[1] + 1;
3917 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3918 /* save buffer pointer */
3919 saved_buffer = pStubMsg->Buffer;
3920 /* get the buffer pointer after complex array data, but before
3921 * pointer data */
3922 pStubMsg->IgnoreEmbeddedPointers = 1;
3923 pStubMsg->MemorySize = 0;
3924 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3925 size = pStubMsg->MemorySize;
3926 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3928 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3929 if (!pStubMsg->PointerBufferMark)
3931 /* save it for use by embedded pointer code later */
3932 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3933 pointer_buffer_mark_set = 1;
3935 /* restore the original buffer */
3936 pStubMsg->Buffer = saved_buffer;
3938 pFormat += 4;
3940 pFormat = ReadConformance(pStubMsg, pFormat);
3941 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3943 if (!fMustAlloc && !*ppMemory)
3944 fMustAlloc = TRUE;
3945 if (fMustAlloc)
3946 *ppMemory = NdrAllocate(pStubMsg, size);
3948 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3950 pMemory = *ppMemory;
3951 count = pStubMsg->ActualCount;
3952 for (i = 0; i < count; i++)
3953 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3955 if (pointer_buffer_mark_set)
3957 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3958 pStubMsg->PointerBufferMark = NULL;
3961 return NULL;
3964 /***********************************************************************
3965 * NdrComplexArrayBufferSize [RPCRT4.@]
3967 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3968 unsigned char *pMemory,
3969 PFORMAT_STRING pFormat)
3971 ULONG i, count, def;
3972 unsigned char alignment;
3973 BOOL variance_present;
3974 int pointer_length_set = 0;
3976 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3978 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3980 ERR("invalid format type %x\n", pFormat[0]);
3981 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3982 return;
3985 alignment = pFormat[1] + 1;
3987 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3989 /* save buffer fields that may be changed by buffer sizer functions
3990 * and that may be needed later on */
3991 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3992 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3993 unsigned long saved_max_count = pStubMsg->MaxCount;
3994 unsigned long saved_offset = pStubMsg->Offset;
3995 unsigned long saved_actual_count = pStubMsg->ActualCount;
3997 /* get the buffer pointer after complex array data, but before
3998 * pointer data */
3999 pStubMsg->IgnoreEmbeddedPointers = 1;
4000 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4001 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4003 /* save it for use by embedded pointer code later */
4004 pStubMsg->PointerLength = pStubMsg->BufferLength;
4005 pointer_length_set = 1;
4007 /* restore fields */
4008 pStubMsg->ActualCount = saved_actual_count;
4009 pStubMsg->Offset = saved_offset;
4010 pStubMsg->MaxCount = saved_max_count;
4011 pStubMsg->BufferLength = saved_buffer_length;
4013 def = *(const WORD*)&pFormat[2];
4014 pFormat += 4;
4016 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4017 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4018 SizeConformance(pStubMsg);
4020 variance_present = IsConformanceOrVariancePresent(pFormat);
4021 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4022 TRACE("variance = %d\n", pStubMsg->ActualCount);
4024 if (variance_present)
4025 SizeVariance(pStubMsg);
4027 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4029 count = pStubMsg->ActualCount;
4030 for (i = 0; i < count; i++)
4031 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4033 if(pointer_length_set)
4035 pStubMsg->BufferLength = pStubMsg->PointerLength;
4036 pStubMsg->PointerLength = 0;
4040 /***********************************************************************
4041 * NdrComplexArrayMemorySize [RPCRT4.@]
4043 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4044 PFORMAT_STRING pFormat)
4046 ULONG i, count, esize, SavedMemorySize, MemorySize;
4047 unsigned char alignment;
4049 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4051 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4053 ERR("invalid format type %x\n", pFormat[0]);
4054 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4055 return 0;
4058 alignment = pFormat[1] + 1;
4060 pFormat += 4;
4062 pFormat = ReadConformance(pStubMsg, pFormat);
4063 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4065 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4067 SavedMemorySize = pStubMsg->MemorySize;
4069 esize = ComplexStructSize(pStubMsg, pFormat);
4071 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4073 count = pStubMsg->ActualCount;
4074 for (i = 0; i < count; i++)
4075 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4077 pStubMsg->MemorySize = SavedMemorySize;
4079 pStubMsg->MemorySize += MemorySize;
4080 return MemorySize;
4083 /***********************************************************************
4084 * NdrComplexArrayFree [RPCRT4.@]
4086 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4087 unsigned char *pMemory,
4088 PFORMAT_STRING pFormat)
4090 ULONG i, count, def;
4092 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4094 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4096 ERR("invalid format type %x\n", pFormat[0]);
4097 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4098 return;
4101 def = *(const WORD*)&pFormat[2];
4102 pFormat += 4;
4104 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4105 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4107 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4108 TRACE("variance = %d\n", pStubMsg->ActualCount);
4110 count = pStubMsg->ActualCount;
4111 for (i = 0; i < count; i++)
4112 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4115 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4116 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4117 USER_MARSHAL_CB *umcb)
4119 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4120 pStubMsg->RpcMsg->DataRepresentation);
4121 umcb->pStubMsg = pStubMsg;
4122 umcb->pReserve = NULL;
4123 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4124 umcb->CBType = cbtype;
4125 umcb->pFormat = pFormat;
4126 umcb->pTypeFormat = NULL /* FIXME */;
4129 #define USER_MARSHAL_PTR_PREFIX \
4130 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4131 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4133 /***********************************************************************
4134 * NdrUserMarshalMarshall [RPCRT4.@]
4136 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4137 unsigned char *pMemory,
4138 PFORMAT_STRING pFormat)
4140 unsigned flags = pFormat[1];
4141 unsigned index = *(const WORD*)&pFormat[2];
4142 unsigned char *saved_buffer = NULL;
4143 USER_MARSHAL_CB umcb;
4145 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4146 TRACE("index=%d\n", index);
4148 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4150 if (flags & USER_MARSHAL_POINTER)
4152 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4153 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4154 pStubMsg->Buffer += 4;
4155 if (pStubMsg->PointerBufferMark)
4157 saved_buffer = pStubMsg->Buffer;
4158 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4159 pStubMsg->PointerBufferMark = NULL;
4161 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4163 else
4164 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4166 pStubMsg->Buffer =
4167 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4168 &umcb.Flags, pStubMsg->Buffer, pMemory);
4170 if (saved_buffer)
4172 STD_OVERFLOW_CHECK(pStubMsg);
4173 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4174 pStubMsg->Buffer = saved_buffer;
4177 STD_OVERFLOW_CHECK(pStubMsg);
4179 return NULL;
4182 /***********************************************************************
4183 * NdrUserMarshalUnmarshall [RPCRT4.@]
4185 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4186 unsigned char **ppMemory,
4187 PFORMAT_STRING pFormat,
4188 unsigned char fMustAlloc)
4190 unsigned flags = pFormat[1];
4191 unsigned index = *(const WORD*)&pFormat[2];
4192 DWORD memsize = *(const WORD*)&pFormat[4];
4193 unsigned char *saved_buffer = NULL;
4194 USER_MARSHAL_CB umcb;
4196 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4197 TRACE("index=%d\n", index);
4199 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4201 if (flags & USER_MARSHAL_POINTER)
4203 ALIGN_POINTER(pStubMsg->Buffer, 4);
4204 /* skip pointer prefix */
4205 pStubMsg->Buffer += 4;
4206 if (pStubMsg->PointerBufferMark)
4208 saved_buffer = pStubMsg->Buffer;
4209 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4210 pStubMsg->PointerBufferMark = NULL;
4212 ALIGN_POINTER(pStubMsg->Buffer, 8);
4214 else
4215 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4217 if (!fMustAlloc && !*ppMemory)
4218 fMustAlloc = TRUE;
4219 if (fMustAlloc)
4221 *ppMemory = NdrAllocate(pStubMsg, memsize);
4222 memset(*ppMemory, 0, memsize);
4225 pStubMsg->Buffer =
4226 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4227 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4229 if (saved_buffer)
4231 STD_OVERFLOW_CHECK(pStubMsg);
4232 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4233 pStubMsg->Buffer = saved_buffer;
4236 return NULL;
4239 /***********************************************************************
4240 * NdrUserMarshalBufferSize [RPCRT4.@]
4242 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4243 unsigned char *pMemory,
4244 PFORMAT_STRING pFormat)
4246 unsigned flags = pFormat[1];
4247 unsigned index = *(const WORD*)&pFormat[2];
4248 DWORD bufsize = *(const WORD*)&pFormat[6];
4249 USER_MARSHAL_CB umcb;
4250 unsigned long saved_buffer_length = 0;
4252 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4253 TRACE("index=%d\n", index);
4255 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4257 if (flags & USER_MARSHAL_POINTER)
4259 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4260 /* skip pointer prefix */
4261 safe_buffer_length_increment(pStubMsg, 4);
4262 if (pStubMsg->IgnoreEmbeddedPointers)
4263 return;
4264 if (pStubMsg->PointerLength)
4266 saved_buffer_length = pStubMsg->BufferLength;
4267 pStubMsg->BufferLength = pStubMsg->PointerLength;
4268 pStubMsg->PointerLength = 0;
4270 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4272 else
4273 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4275 if (bufsize) {
4276 TRACE("size=%d\n", bufsize);
4277 safe_buffer_length_increment(pStubMsg, bufsize);
4279 else
4280 pStubMsg->BufferLength =
4281 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4282 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4284 if (saved_buffer_length)
4286 pStubMsg->PointerLength = pStubMsg->BufferLength;
4287 pStubMsg->BufferLength = saved_buffer_length;
4292 /***********************************************************************
4293 * NdrUserMarshalMemorySize [RPCRT4.@]
4295 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4296 PFORMAT_STRING pFormat)
4298 unsigned flags = pFormat[1];
4299 unsigned index = *(const WORD*)&pFormat[2];
4300 DWORD memsize = *(const WORD*)&pFormat[4];
4301 DWORD bufsize = *(const WORD*)&pFormat[6];
4303 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4304 TRACE("index=%d\n", index);
4306 pStubMsg->MemorySize += memsize;
4308 if (flags & USER_MARSHAL_POINTER)
4310 ALIGN_POINTER(pStubMsg->Buffer, 4);
4311 /* skip pointer prefix */
4312 pStubMsg->Buffer += 4;
4313 if (pStubMsg->IgnoreEmbeddedPointers)
4314 return pStubMsg->MemorySize;
4315 ALIGN_POINTER(pStubMsg->Buffer, 8);
4317 else
4318 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4320 if (!bufsize)
4321 FIXME("not implemented for varying buffer size\n");
4323 pStubMsg->Buffer += bufsize;
4325 return pStubMsg->MemorySize;
4328 /***********************************************************************
4329 * NdrUserMarshalFree [RPCRT4.@]
4331 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4332 unsigned char *pMemory,
4333 PFORMAT_STRING pFormat)
4335 /* unsigned flags = pFormat[1]; */
4336 unsigned index = *(const WORD*)&pFormat[2];
4337 USER_MARSHAL_CB umcb;
4339 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4340 TRACE("index=%d\n", index);
4342 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4344 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4345 &umcb.Flags, pMemory);
4348 /***********************************************************************
4349 * NdrGetUserMarshalInfo [RPCRT4.@]
4351 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4353 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4355 TRACE("(%p,%u,%p)\n", flags, level, umi);
4357 if (level != 1)
4358 return RPC_S_INVALID_ARG;
4360 memset(&umi->Level1, 0, sizeof(umi->Level1));
4361 umi->InformationLevel = level;
4363 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4364 return RPC_S_INVALID_ARG;
4366 umi->Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4367 umi->Level1.pfnFree = umcb->pStubMsg->pfnFree;
4368 umi->Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4370 switch (umcb->CBType)
4372 case USER_MARSHAL_CB_MARSHALL:
4373 case USER_MARSHAL_CB_UNMARSHALL:
4375 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4376 unsigned char *buffer_start = msg->Buffer;
4377 unsigned char *buffer_end =
4378 (unsigned char *)msg->Buffer + msg->BufferLength;
4380 if (umcb->pStubMsg->Buffer < buffer_start ||
4381 umcb->pStubMsg->Buffer > buffer_end)
4382 return ERROR_INVALID_USER_BUFFER;
4384 umi->Level1.Buffer = umcb->pStubMsg->Buffer;
4385 umi->Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4386 break;
4388 case USER_MARSHAL_CB_BUFFER_SIZE:
4389 case USER_MARSHAL_CB_FREE:
4390 break;
4391 default:
4392 WARN("unrecognised CBType %d\n", umcb->CBType);
4395 return RPC_S_OK;
4398 /***********************************************************************
4399 * NdrClearOutParameters [RPCRT4.@]
4401 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4402 PFORMAT_STRING pFormat,
4403 void *ArgAddr)
4405 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4408 /***********************************************************************
4409 * NdrConvert [RPCRT4.@]
4411 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4413 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4414 /* FIXME: since this stub doesn't do any converting, the proper behavior
4415 is to raise an exception */
4418 /***********************************************************************
4419 * NdrConvert2 [RPCRT4.@]
4421 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4423 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4424 pStubMsg, pFormat, NumberParams);
4425 /* FIXME: since this stub doesn't do any converting, the proper behavior
4426 is to raise an exception */
4429 #include "pshpack1.h"
4430 typedef struct _NDR_CSTRUCT_FORMAT
4432 unsigned char type;
4433 unsigned char alignment;
4434 unsigned short memory_size;
4435 short offset_to_array_description;
4436 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4437 #include "poppack.h"
4439 /***********************************************************************
4440 * NdrConformantStructMarshall [RPCRT4.@]
4442 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4443 unsigned char *pMemory,
4444 PFORMAT_STRING pFormat)
4446 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4447 PFORMAT_STRING pCArrayFormat;
4448 ULONG esize, bufsize;
4450 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4452 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4453 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4455 ERR("invalid format type %x\n", pCStructFormat->type);
4456 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4457 return NULL;
4460 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4461 pCStructFormat->offset_to_array_description;
4462 if (*pCArrayFormat != RPC_FC_CARRAY)
4464 ERR("invalid array format type %x\n", pCStructFormat->type);
4465 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4466 return NULL;
4468 esize = *(const WORD*)(pCArrayFormat+2);
4470 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4471 pCArrayFormat + 4, 0);
4473 WriteConformance(pStubMsg);
4475 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4477 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4479 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4480 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4482 ERR("integer overflow of memory_size %u with bufsize %u\n",
4483 pCStructFormat->memory_size, bufsize);
4484 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4486 /* copy constant sized part of struct */
4487 pStubMsg->BufferMark = pStubMsg->Buffer;
4488 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4490 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4491 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4493 return NULL;
4496 /***********************************************************************
4497 * NdrConformantStructUnmarshall [RPCRT4.@]
4499 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4500 unsigned char **ppMemory,
4501 PFORMAT_STRING pFormat,
4502 unsigned char fMustAlloc)
4504 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4505 PFORMAT_STRING pCArrayFormat;
4506 ULONG esize, bufsize;
4507 unsigned char *saved_buffer;
4509 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4511 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4512 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4514 ERR("invalid format type %x\n", pCStructFormat->type);
4515 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4516 return NULL;
4518 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4519 pCStructFormat->offset_to_array_description;
4520 if (*pCArrayFormat != RPC_FC_CARRAY)
4522 ERR("invalid array format type %x\n", pCStructFormat->type);
4523 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4524 return NULL;
4526 esize = *(const WORD*)(pCArrayFormat+2);
4528 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4530 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4532 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4534 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4535 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4537 ERR("integer overflow of memory_size %u with bufsize %u\n",
4538 pCStructFormat->memory_size, bufsize);
4539 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4542 if (fMustAlloc)
4544 SIZE_T size = pCStructFormat->memory_size + bufsize;
4545 *ppMemory = NdrAllocate(pStubMsg, size);
4547 else
4549 if (!pStubMsg->IsClient && !*ppMemory)
4550 /* for servers, we just point straight into the RPC buffer */
4551 *ppMemory = pStubMsg->Buffer;
4554 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4555 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4556 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4557 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4559 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4560 if (*ppMemory != saved_buffer)
4561 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4563 return NULL;
4566 /***********************************************************************
4567 * NdrConformantStructBufferSize [RPCRT4.@]
4569 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4570 unsigned char *pMemory,
4571 PFORMAT_STRING pFormat)
4573 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4574 PFORMAT_STRING pCArrayFormat;
4575 ULONG esize;
4577 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4579 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4580 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4582 ERR("invalid format type %x\n", pCStructFormat->type);
4583 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4584 return;
4586 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4587 pCStructFormat->offset_to_array_description;
4588 if (*pCArrayFormat != RPC_FC_CARRAY)
4590 ERR("invalid array format type %x\n", pCStructFormat->type);
4591 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4592 return;
4594 esize = *(const WORD*)(pCArrayFormat+2);
4596 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4597 SizeConformance(pStubMsg);
4599 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4601 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4603 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4604 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4606 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4607 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4610 /***********************************************************************
4611 * NdrConformantStructMemorySize [RPCRT4.@]
4613 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4614 PFORMAT_STRING pFormat)
4616 FIXME("stub\n");
4617 return 0;
4620 /***********************************************************************
4621 * NdrConformantStructFree [RPCRT4.@]
4623 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4624 unsigned char *pMemory,
4625 PFORMAT_STRING pFormat)
4627 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4628 PFORMAT_STRING pCArrayFormat;
4630 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4632 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4633 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4635 ERR("invalid format type %x\n", pCStructFormat->type);
4636 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4637 return;
4640 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4641 pCStructFormat->offset_to_array_description;
4642 if (*pCArrayFormat != RPC_FC_CARRAY)
4644 ERR("invalid array format type %x\n", pCStructFormat->type);
4645 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4646 return;
4649 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4650 pCArrayFormat + 4, 0);
4652 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4654 /* copy constant sized part of struct */
4655 pStubMsg->BufferMark = pStubMsg->Buffer;
4657 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4658 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4661 /***********************************************************************
4662 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4664 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4665 unsigned char *pMemory,
4666 PFORMAT_STRING pFormat)
4668 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4669 PFORMAT_STRING pCVArrayFormat;
4671 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4673 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4674 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4676 ERR("invalid format type %x\n", pCVStructFormat->type);
4677 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4678 return NULL;
4681 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4682 pCVStructFormat->offset_to_array_description;
4684 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4685 pMemory + pCVStructFormat->memory_size,
4686 pCVArrayFormat);
4688 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4690 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4692 /* write constant sized part */
4693 pStubMsg->BufferMark = pStubMsg->Buffer;
4694 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4696 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4697 pMemory + pCVStructFormat->memory_size,
4698 pCVArrayFormat, FALSE /* fHasPointers */);
4700 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4702 return NULL;
4705 /***********************************************************************
4706 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4708 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4709 unsigned char **ppMemory,
4710 PFORMAT_STRING pFormat,
4711 unsigned char fMustAlloc)
4713 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4714 PFORMAT_STRING pCVArrayFormat;
4715 ULONG memsize, bufsize;
4716 unsigned char *saved_buffer, *saved_array_buffer;
4717 ULONG offset;
4718 unsigned char *array_memory;
4720 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4722 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4723 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4725 ERR("invalid format type %x\n", pCVStructFormat->type);
4726 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4727 return NULL;
4730 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4731 pCVStructFormat->offset_to_array_description;
4733 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4734 pCVArrayFormat);
4736 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4738 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4740 /* work out how much memory to allocate if we need to do so */
4741 if (!fMustAlloc && !*ppMemory)
4742 fMustAlloc = TRUE;
4743 if (fMustAlloc)
4745 SIZE_T size = pCVStructFormat->memory_size + memsize;
4746 *ppMemory = NdrAllocate(pStubMsg, size);
4749 /* mark the start of the constant data */
4750 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4751 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4753 array_memory = *ppMemory + pCVStructFormat->memory_size;
4754 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4755 &array_memory, pCVArrayFormat,
4756 FALSE /* fMustAlloc */,
4757 FALSE /* fUseServerBufferMemory */,
4758 FALSE /* fUnmarshall */);
4760 /* save offset in case unmarshalling pointers changes it */
4761 offset = pStubMsg->Offset;
4763 /* mark the start of the array data */
4764 saved_array_buffer = pStubMsg->Buffer;
4765 safe_buffer_increment(pStubMsg, bufsize);
4767 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4769 /* copy the constant data */
4770 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4771 /* copy the array data */
4772 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4773 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4774 saved_array_buffer, bufsize);
4776 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4777 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4778 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4779 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4781 return NULL;
4784 /***********************************************************************
4785 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4787 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4788 unsigned char *pMemory,
4789 PFORMAT_STRING pFormat)
4791 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4792 PFORMAT_STRING pCVArrayFormat;
4794 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4796 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4797 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4799 ERR("invalid format type %x\n", pCVStructFormat->type);
4800 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4801 return;
4804 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4805 pCVStructFormat->offset_to_array_description;
4806 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4807 pMemory + pCVStructFormat->memory_size,
4808 pCVArrayFormat);
4810 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4812 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4814 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4816 array_buffer_size(*pCVArrayFormat, pStubMsg,
4817 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4818 FALSE /* fHasPointers */);
4820 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4823 /***********************************************************************
4824 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4826 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4827 PFORMAT_STRING pFormat)
4829 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4830 PFORMAT_STRING pCVArrayFormat;
4832 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4834 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4835 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4837 ERR("invalid format type %x\n", pCVStructFormat->type);
4838 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4839 return 0;
4842 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4843 pCVStructFormat->offset_to_array_description;
4844 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4846 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4848 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4850 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4851 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4852 FALSE /* fHasPointers */);
4854 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4856 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4858 return pStubMsg->MemorySize;
4861 /***********************************************************************
4862 * NdrConformantVaryingStructFree [RPCRT4.@]
4864 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4865 unsigned char *pMemory,
4866 PFORMAT_STRING pFormat)
4868 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4869 PFORMAT_STRING pCVArrayFormat;
4871 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4873 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4874 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4876 ERR("invalid format type %x\n", pCVStructFormat->type);
4877 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4878 return;
4881 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4882 pCVStructFormat->offset_to_array_description;
4883 array_free(*pCVArrayFormat, pStubMsg,
4884 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4885 FALSE /* fHasPointers */);
4887 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4889 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4892 #include "pshpack1.h"
4893 typedef struct
4895 unsigned char type;
4896 unsigned char alignment;
4897 unsigned short total_size;
4898 } NDR_SMFARRAY_FORMAT;
4900 typedef struct
4902 unsigned char type;
4903 unsigned char alignment;
4904 unsigned long total_size;
4905 } NDR_LGFARRAY_FORMAT;
4906 #include "poppack.h"
4908 /***********************************************************************
4909 * NdrFixedArrayMarshall [RPCRT4.@]
4911 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4912 unsigned char *pMemory,
4913 PFORMAT_STRING pFormat)
4915 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4916 unsigned long total_size;
4918 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4920 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4921 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4923 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4924 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4925 return NULL;
4928 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4930 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4932 total_size = pSmFArrayFormat->total_size;
4933 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4935 else
4937 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4938 total_size = pLgFArrayFormat->total_size;
4939 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4942 pStubMsg->BufferMark = pStubMsg->Buffer;
4943 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4945 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4947 return NULL;
4950 /***********************************************************************
4951 * NdrFixedArrayUnmarshall [RPCRT4.@]
4953 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4954 unsigned char **ppMemory,
4955 PFORMAT_STRING pFormat,
4956 unsigned char fMustAlloc)
4958 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4959 unsigned long total_size;
4960 unsigned char *saved_buffer;
4962 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4964 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4965 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4967 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4968 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4969 return NULL;
4972 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4974 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4976 total_size = pSmFArrayFormat->total_size;
4977 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4979 else
4981 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4982 total_size = pLgFArrayFormat->total_size;
4983 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4986 if (fMustAlloc)
4987 *ppMemory = NdrAllocate(pStubMsg, total_size);
4988 else
4990 if (!pStubMsg->IsClient && !*ppMemory)
4991 /* for servers, we just point straight into the RPC buffer */
4992 *ppMemory = pStubMsg->Buffer;
4995 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4996 safe_buffer_increment(pStubMsg, total_size);
4997 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4999 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5000 if (*ppMemory != saved_buffer)
5001 memcpy(*ppMemory, saved_buffer, total_size);
5003 return NULL;
5006 /***********************************************************************
5007 * NdrFixedArrayBufferSize [RPCRT4.@]
5009 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5010 unsigned char *pMemory,
5011 PFORMAT_STRING pFormat)
5013 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5014 unsigned long total_size;
5016 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5018 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5019 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5021 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5022 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5023 return;
5026 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5028 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5030 total_size = pSmFArrayFormat->total_size;
5031 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5033 else
5035 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5036 total_size = pLgFArrayFormat->total_size;
5037 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5039 safe_buffer_length_increment(pStubMsg, total_size);
5041 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5044 /***********************************************************************
5045 * NdrFixedArrayMemorySize [RPCRT4.@]
5047 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5048 PFORMAT_STRING pFormat)
5050 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5051 ULONG total_size;
5053 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5055 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5056 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5058 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5059 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5060 return 0;
5063 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5065 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5067 total_size = pSmFArrayFormat->total_size;
5068 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5070 else
5072 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5073 total_size = pLgFArrayFormat->total_size;
5074 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5076 pStubMsg->BufferMark = pStubMsg->Buffer;
5077 safe_buffer_increment(pStubMsg, total_size);
5078 pStubMsg->MemorySize += total_size;
5080 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5082 return total_size;
5085 /***********************************************************************
5086 * NdrFixedArrayFree [RPCRT4.@]
5088 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5089 unsigned char *pMemory,
5090 PFORMAT_STRING pFormat)
5092 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5094 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5096 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5097 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5099 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5100 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5101 return;
5104 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5105 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5106 else
5108 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5109 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5112 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5115 /***********************************************************************
5116 * NdrVaryingArrayMarshall [RPCRT4.@]
5118 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5119 unsigned char *pMemory,
5120 PFORMAT_STRING pFormat)
5122 unsigned char alignment;
5123 DWORD elements, esize;
5124 ULONG bufsize;
5126 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5128 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5129 (pFormat[0] != RPC_FC_LGVARRAY))
5131 ERR("invalid format type %x\n", pFormat[0]);
5132 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5133 return NULL;
5136 alignment = pFormat[1] + 1;
5138 if (pFormat[0] == RPC_FC_SMVARRAY)
5140 pFormat += 2;
5141 pFormat += sizeof(WORD);
5142 elements = *(const WORD*)pFormat;
5143 pFormat += sizeof(WORD);
5145 else
5147 pFormat += 2;
5148 pFormat += sizeof(DWORD);
5149 elements = *(const DWORD*)pFormat;
5150 pFormat += sizeof(DWORD);
5153 esize = *(const WORD*)pFormat;
5154 pFormat += sizeof(WORD);
5156 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5157 if ((pStubMsg->ActualCount > elements) ||
5158 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5160 RpcRaiseException(RPC_S_INVALID_BOUND);
5161 return NULL;
5164 WriteVariance(pStubMsg);
5166 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5168 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5169 pStubMsg->BufferMark = pStubMsg->Buffer;
5170 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5172 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5174 return NULL;
5177 /***********************************************************************
5178 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5180 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5181 unsigned char **ppMemory,
5182 PFORMAT_STRING pFormat,
5183 unsigned char fMustAlloc)
5185 unsigned char alignment;
5186 DWORD size, elements, esize;
5187 ULONG bufsize;
5188 unsigned char *saved_buffer;
5189 ULONG offset;
5191 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5193 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5194 (pFormat[0] != RPC_FC_LGVARRAY))
5196 ERR("invalid format type %x\n", pFormat[0]);
5197 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5198 return NULL;
5201 alignment = pFormat[1] + 1;
5203 if (pFormat[0] == RPC_FC_SMVARRAY)
5205 pFormat += 2;
5206 size = *(const WORD*)pFormat;
5207 pFormat += sizeof(WORD);
5208 elements = *(const WORD*)pFormat;
5209 pFormat += sizeof(WORD);
5211 else
5213 pFormat += 2;
5214 size = *(const DWORD*)pFormat;
5215 pFormat += sizeof(DWORD);
5216 elements = *(const DWORD*)pFormat;
5217 pFormat += sizeof(DWORD);
5220 esize = *(const WORD*)pFormat;
5221 pFormat += sizeof(WORD);
5223 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5225 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5227 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5228 offset = pStubMsg->Offset;
5230 if (!fMustAlloc && !*ppMemory)
5231 fMustAlloc = TRUE;
5232 if (fMustAlloc)
5233 *ppMemory = NdrAllocate(pStubMsg, size);
5234 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5235 safe_buffer_increment(pStubMsg, bufsize);
5237 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5239 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5241 return NULL;
5244 /***********************************************************************
5245 * NdrVaryingArrayBufferSize [RPCRT4.@]
5247 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5248 unsigned char *pMemory,
5249 PFORMAT_STRING pFormat)
5251 unsigned char alignment;
5252 DWORD elements, esize;
5254 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5256 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5257 (pFormat[0] != RPC_FC_LGVARRAY))
5259 ERR("invalid format type %x\n", pFormat[0]);
5260 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5261 return;
5264 alignment = pFormat[1] + 1;
5266 if (pFormat[0] == RPC_FC_SMVARRAY)
5268 pFormat += 2;
5269 pFormat += sizeof(WORD);
5270 elements = *(const WORD*)pFormat;
5271 pFormat += sizeof(WORD);
5273 else
5275 pFormat += 2;
5276 pFormat += sizeof(DWORD);
5277 elements = *(const DWORD*)pFormat;
5278 pFormat += sizeof(DWORD);
5281 esize = *(const WORD*)pFormat;
5282 pFormat += sizeof(WORD);
5284 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5285 if ((pStubMsg->ActualCount > elements) ||
5286 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5288 RpcRaiseException(RPC_S_INVALID_BOUND);
5289 return;
5292 SizeVariance(pStubMsg);
5294 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5296 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5298 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5301 /***********************************************************************
5302 * NdrVaryingArrayMemorySize [RPCRT4.@]
5304 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5305 PFORMAT_STRING pFormat)
5307 unsigned char alignment;
5308 DWORD size, elements, esize;
5310 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5312 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5313 (pFormat[0] != RPC_FC_LGVARRAY))
5315 ERR("invalid format type %x\n", pFormat[0]);
5316 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5317 return 0;
5320 alignment = pFormat[1] + 1;
5322 if (pFormat[0] == RPC_FC_SMVARRAY)
5324 pFormat += 2;
5325 size = *(const WORD*)pFormat;
5326 pFormat += sizeof(WORD);
5327 elements = *(const WORD*)pFormat;
5328 pFormat += sizeof(WORD);
5330 else
5332 pFormat += 2;
5333 size = *(const DWORD*)pFormat;
5334 pFormat += sizeof(DWORD);
5335 elements = *(const DWORD*)pFormat;
5336 pFormat += sizeof(DWORD);
5339 esize = *(const WORD*)pFormat;
5340 pFormat += sizeof(WORD);
5342 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5344 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5346 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5347 pStubMsg->MemorySize += size;
5349 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5351 return pStubMsg->MemorySize;
5354 /***********************************************************************
5355 * NdrVaryingArrayFree [RPCRT4.@]
5357 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5358 unsigned char *pMemory,
5359 PFORMAT_STRING pFormat)
5361 DWORD elements;
5363 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5365 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5366 (pFormat[0] != RPC_FC_LGVARRAY))
5368 ERR("invalid format type %x\n", pFormat[0]);
5369 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5370 return;
5373 if (pFormat[0] == RPC_FC_SMVARRAY)
5375 pFormat += 2;
5376 pFormat += sizeof(WORD);
5377 elements = *(const WORD*)pFormat;
5378 pFormat += sizeof(WORD);
5380 else
5382 pFormat += 2;
5383 pFormat += sizeof(DWORD);
5384 elements = *(const DWORD*)pFormat;
5385 pFormat += sizeof(DWORD);
5388 pFormat += sizeof(WORD);
5390 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5391 if ((pStubMsg->ActualCount > elements) ||
5392 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5394 RpcRaiseException(RPC_S_INVALID_BOUND);
5395 return;
5398 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5401 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5403 switch (fc)
5405 case RPC_FC_BYTE:
5406 case RPC_FC_CHAR:
5407 case RPC_FC_SMALL:
5408 case RPC_FC_USMALL:
5409 return *pMemory;
5410 case RPC_FC_WCHAR:
5411 case RPC_FC_SHORT:
5412 case RPC_FC_USHORT:
5413 case RPC_FC_ENUM16:
5414 return *(const USHORT *)pMemory;
5415 case RPC_FC_LONG:
5416 case RPC_FC_ULONG:
5417 case RPC_FC_ENUM32:
5418 return *(const ULONG *)pMemory;
5419 default:
5420 FIXME("Unhandled base type: 0x%02x\n", fc);
5421 return 0;
5425 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5426 unsigned long discriminant,
5427 PFORMAT_STRING pFormat)
5429 unsigned short num_arms, arm, type;
5431 num_arms = *(const SHORT*)pFormat & 0x0fff;
5432 pFormat += 2;
5433 for(arm = 0; arm < num_arms; arm++)
5435 if(discriminant == *(const ULONG*)pFormat)
5437 pFormat += 4;
5438 break;
5440 pFormat += 6;
5443 type = *(const unsigned short*)pFormat;
5444 TRACE("type %04x\n", type);
5445 if(arm == num_arms) /* default arm extras */
5447 if(type == 0xffff)
5449 ERR("no arm for 0x%lx and no default case\n", discriminant);
5450 RpcRaiseException(RPC_S_INVALID_TAG);
5451 return NULL;
5453 if(type == 0)
5455 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5456 return NULL;
5459 return pFormat;
5462 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5464 unsigned short type;
5466 pFormat += 2;
5468 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5469 if(!pFormat)
5470 return NULL;
5472 type = *(const unsigned short*)pFormat;
5473 if((type & 0xff00) == 0x8000)
5475 unsigned char basetype = LOBYTE(type);
5476 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5478 else
5480 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5481 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5482 if (m)
5484 unsigned char *saved_buffer = NULL;
5485 int pointer_buffer_mark_set = 0;
5486 switch(*desc)
5488 case RPC_FC_RP:
5489 case RPC_FC_UP:
5490 case RPC_FC_OP:
5491 case RPC_FC_FP:
5492 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5493 saved_buffer = pStubMsg->Buffer;
5494 if (pStubMsg->PointerBufferMark)
5496 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5497 pStubMsg->PointerBufferMark = NULL;
5498 pointer_buffer_mark_set = 1;
5500 else
5501 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5503 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5504 if (pointer_buffer_mark_set)
5506 STD_OVERFLOW_CHECK(pStubMsg);
5507 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5508 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5510 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5511 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5512 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5514 pStubMsg->Buffer = saved_buffer + 4;
5516 break;
5517 default:
5518 m(pStubMsg, pMemory, desc);
5521 else FIXME("no marshaller for embedded type %02x\n", *desc);
5523 return NULL;
5526 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5527 unsigned char **ppMemory,
5528 ULONG discriminant,
5529 PFORMAT_STRING pFormat,
5530 unsigned char fMustAlloc)
5532 unsigned short type;
5534 pFormat += 2;
5536 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5537 if(!pFormat)
5538 return NULL;
5540 type = *(const unsigned short*)pFormat;
5541 if((type & 0xff00) == 0x8000)
5543 unsigned char basetype = LOBYTE(type);
5544 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5546 else
5548 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5549 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5550 if (m)
5552 unsigned char *saved_buffer = NULL;
5553 int pointer_buffer_mark_set = 0;
5554 switch(*desc)
5556 case RPC_FC_RP:
5557 case RPC_FC_UP:
5558 case RPC_FC_OP:
5559 case RPC_FC_FP:
5560 **(void***)ppMemory = NULL;
5561 ALIGN_POINTER(pStubMsg->Buffer, 4);
5562 saved_buffer = pStubMsg->Buffer;
5563 if (pStubMsg->PointerBufferMark)
5565 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5566 pStubMsg->PointerBufferMark = NULL;
5567 pointer_buffer_mark_set = 1;
5569 else
5570 pStubMsg->Buffer += 4; /* for pointer ID */
5572 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5574 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5575 saved_buffer, pStubMsg->BufferEnd);
5576 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5579 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5580 if (pointer_buffer_mark_set)
5582 STD_OVERFLOW_CHECK(pStubMsg);
5583 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5584 pStubMsg->Buffer = saved_buffer + 4;
5586 break;
5587 default:
5588 m(pStubMsg, ppMemory, desc, fMustAlloc);
5591 else FIXME("no marshaller for embedded type %02x\n", *desc);
5593 return NULL;
5596 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5597 unsigned char *pMemory,
5598 ULONG discriminant,
5599 PFORMAT_STRING pFormat)
5601 unsigned short type;
5603 pFormat += 2;
5605 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5606 if(!pFormat)
5607 return;
5609 type = *(const unsigned short*)pFormat;
5610 if((type & 0xff00) == 0x8000)
5612 unsigned char basetype = LOBYTE(type);
5613 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5615 else
5617 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5618 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5619 if (m)
5621 switch(*desc)
5623 case RPC_FC_RP:
5624 case RPC_FC_UP:
5625 case RPC_FC_OP:
5626 case RPC_FC_FP:
5627 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5628 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5629 if (!pStubMsg->IgnoreEmbeddedPointers)
5631 int saved_buffer_length = pStubMsg->BufferLength;
5632 pStubMsg->BufferLength = pStubMsg->PointerLength;
5633 pStubMsg->PointerLength = 0;
5634 if(!pStubMsg->BufferLength)
5635 ERR("BufferLength == 0??\n");
5636 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5637 pStubMsg->PointerLength = pStubMsg->BufferLength;
5638 pStubMsg->BufferLength = saved_buffer_length;
5640 break;
5641 default:
5642 m(pStubMsg, pMemory, desc);
5645 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5649 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5650 ULONG discriminant,
5651 PFORMAT_STRING pFormat)
5653 unsigned short type, size;
5655 size = *(const unsigned short*)pFormat;
5656 pStubMsg->Memory += size;
5657 pFormat += 2;
5659 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5660 if(!pFormat)
5661 return 0;
5663 type = *(const unsigned short*)pFormat;
5664 if((type & 0xff00) == 0x8000)
5666 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5668 else
5670 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5671 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5672 unsigned char *saved_buffer;
5673 if (m)
5675 switch(*desc)
5677 case RPC_FC_RP:
5678 case RPC_FC_UP:
5679 case RPC_FC_OP:
5680 case RPC_FC_FP:
5681 ALIGN_POINTER(pStubMsg->Buffer, 4);
5682 saved_buffer = pStubMsg->Buffer;
5683 safe_buffer_increment(pStubMsg, 4);
5684 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5685 pStubMsg->MemorySize += 4;
5686 if (!pStubMsg->IgnoreEmbeddedPointers)
5687 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5688 break;
5689 default:
5690 return m(pStubMsg, desc);
5693 else FIXME("no marshaller for embedded type %02x\n", *desc);
5696 TRACE("size %d\n", size);
5697 return size;
5700 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5701 unsigned char *pMemory,
5702 ULONG discriminant,
5703 PFORMAT_STRING pFormat)
5705 unsigned short type;
5707 pFormat += 2;
5709 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5710 if(!pFormat)
5711 return;
5713 type = *(const unsigned short*)pFormat;
5714 if((type & 0xff00) != 0x8000)
5716 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5717 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5718 if (m)
5720 switch(*desc)
5722 case RPC_FC_RP:
5723 case RPC_FC_UP:
5724 case RPC_FC_OP:
5725 case RPC_FC_FP:
5726 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5727 break;
5728 default:
5729 m(pStubMsg, pMemory, desc);
5735 /***********************************************************************
5736 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5738 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5739 unsigned char *pMemory,
5740 PFORMAT_STRING pFormat)
5742 unsigned char switch_type;
5743 unsigned char increment;
5744 ULONG switch_value;
5746 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5747 pFormat++;
5749 switch_type = *pFormat & 0xf;
5750 increment = (*pFormat & 0xf0) >> 4;
5751 pFormat++;
5753 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5755 switch_value = get_discriminant(switch_type, pMemory);
5756 TRACE("got switch value 0x%x\n", switch_value);
5758 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5759 pMemory += increment;
5761 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5764 /***********************************************************************
5765 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5767 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5768 unsigned char **ppMemory,
5769 PFORMAT_STRING pFormat,
5770 unsigned char fMustAlloc)
5772 unsigned char switch_type;
5773 unsigned char increment;
5774 ULONG switch_value;
5775 unsigned short size;
5776 unsigned char *pMemoryArm;
5778 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5779 pFormat++;
5781 switch_type = *pFormat & 0xf;
5782 increment = (*pFormat & 0xf0) >> 4;
5783 pFormat++;
5785 ALIGN_POINTER(pStubMsg->Buffer, increment);
5786 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5787 TRACE("got switch value 0x%x\n", switch_value);
5789 size = *(const unsigned short*)pFormat + increment;
5790 if (!fMustAlloc && !*ppMemory)
5791 fMustAlloc = TRUE;
5792 if (fMustAlloc)
5793 *ppMemory = NdrAllocate(pStubMsg, size);
5795 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5796 pMemoryArm = *ppMemory + increment;
5798 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5801 /***********************************************************************
5802 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5804 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5805 unsigned char *pMemory,
5806 PFORMAT_STRING pFormat)
5808 unsigned char switch_type;
5809 unsigned char increment;
5810 ULONG switch_value;
5812 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5813 pFormat++;
5815 switch_type = *pFormat & 0xf;
5816 increment = (*pFormat & 0xf0) >> 4;
5817 pFormat++;
5819 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5820 switch_value = get_discriminant(switch_type, pMemory);
5821 TRACE("got switch value 0x%x\n", switch_value);
5823 /* Add discriminant size */
5824 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5825 pMemory += increment;
5827 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5830 /***********************************************************************
5831 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5833 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5834 PFORMAT_STRING pFormat)
5836 unsigned char switch_type;
5837 unsigned char increment;
5838 ULONG switch_value;
5840 switch_type = *pFormat & 0xf;
5841 increment = (*pFormat & 0xf0) >> 4;
5842 pFormat++;
5844 ALIGN_POINTER(pStubMsg->Buffer, increment);
5845 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5846 TRACE("got switch value 0x%x\n", switch_value);
5848 pStubMsg->Memory += increment;
5850 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5853 /***********************************************************************
5854 * NdrEncapsulatedUnionFree [RPCRT4.@]
5856 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5857 unsigned char *pMemory,
5858 PFORMAT_STRING pFormat)
5860 unsigned char switch_type;
5861 unsigned char increment;
5862 ULONG switch_value;
5864 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5865 pFormat++;
5867 switch_type = *pFormat & 0xf;
5868 increment = (*pFormat & 0xf0) >> 4;
5869 pFormat++;
5871 switch_value = get_discriminant(switch_type, pMemory);
5872 TRACE("got switch value 0x%x\n", switch_value);
5874 pMemory += increment;
5876 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5879 /***********************************************************************
5880 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5882 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5883 unsigned char *pMemory,
5884 PFORMAT_STRING pFormat)
5886 unsigned char switch_type;
5888 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5889 pFormat++;
5891 switch_type = *pFormat;
5892 pFormat++;
5894 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5895 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5896 /* Marshall discriminant */
5897 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5899 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5902 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5903 PFORMAT_STRING *ppFormat)
5905 long discriminant = 0;
5907 switch(**ppFormat)
5909 case RPC_FC_BYTE:
5910 case RPC_FC_CHAR:
5911 case RPC_FC_SMALL:
5912 case RPC_FC_USMALL:
5914 UCHAR d;
5915 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5916 discriminant = d;
5917 break;
5919 case RPC_FC_WCHAR:
5920 case RPC_FC_SHORT:
5921 case RPC_FC_USHORT:
5923 USHORT d;
5924 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5925 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5926 discriminant = d;
5927 break;
5929 case RPC_FC_LONG:
5930 case RPC_FC_ULONG:
5932 ULONG d;
5933 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5934 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5935 discriminant = d;
5936 break;
5938 default:
5939 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5941 (*ppFormat)++;
5943 if (pStubMsg->fHasNewCorrDesc)
5944 *ppFormat += 6;
5945 else
5946 *ppFormat += 4;
5947 return discriminant;
5950 /**********************************************************************
5951 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5953 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5954 unsigned char **ppMemory,
5955 PFORMAT_STRING pFormat,
5956 unsigned char fMustAlloc)
5958 long discriminant;
5959 unsigned short size;
5961 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5962 pFormat++;
5964 /* Unmarshall discriminant */
5965 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5966 TRACE("unmarshalled discriminant %lx\n", discriminant);
5968 pFormat += *(const SHORT*)pFormat;
5970 size = *(const unsigned short*)pFormat;
5972 if (!fMustAlloc && !*ppMemory)
5973 fMustAlloc = TRUE;
5974 if (fMustAlloc)
5975 *ppMemory = NdrAllocate(pStubMsg, size);
5977 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5980 /***********************************************************************
5981 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5983 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5984 unsigned char *pMemory,
5985 PFORMAT_STRING pFormat)
5987 unsigned char switch_type;
5989 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5990 pFormat++;
5992 switch_type = *pFormat;
5993 pFormat++;
5995 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5996 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5997 /* Add discriminant size */
5998 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6000 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6003 /***********************************************************************
6004 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6006 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6007 PFORMAT_STRING pFormat)
6009 ULONG discriminant;
6011 pFormat++;
6012 /* Unmarshall discriminant */
6013 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6014 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6016 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6019 /***********************************************************************
6020 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6022 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6023 unsigned char *pMemory,
6024 PFORMAT_STRING pFormat)
6026 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6027 pFormat++;
6028 pFormat++;
6030 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6031 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6033 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6036 /***********************************************************************
6037 * NdrByteCountPointerMarshall [RPCRT4.@]
6039 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6040 unsigned char *pMemory,
6041 PFORMAT_STRING pFormat)
6043 FIXME("stub\n");
6044 return NULL;
6047 /***********************************************************************
6048 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6050 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6051 unsigned char **ppMemory,
6052 PFORMAT_STRING pFormat,
6053 unsigned char fMustAlloc)
6055 FIXME("stub\n");
6056 return NULL;
6059 /***********************************************************************
6060 * NdrByteCountPointerBufferSize [RPCRT4.@]
6062 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6063 unsigned char *pMemory,
6064 PFORMAT_STRING pFormat)
6066 FIXME("stub\n");
6069 /***********************************************************************
6070 * NdrByteCountPointerMemorySize [internal]
6072 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6073 PFORMAT_STRING pFormat)
6075 FIXME("stub\n");
6076 return 0;
6079 /***********************************************************************
6080 * NdrByteCountPointerFree [RPCRT4.@]
6082 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6083 unsigned char *pMemory,
6084 PFORMAT_STRING pFormat)
6086 FIXME("stub\n");
6089 /***********************************************************************
6090 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6092 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6093 unsigned char *pMemory,
6094 PFORMAT_STRING pFormat)
6096 FIXME("stub\n");
6097 return NULL;
6100 /***********************************************************************
6101 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6103 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6104 unsigned char **ppMemory,
6105 PFORMAT_STRING pFormat,
6106 unsigned char fMustAlloc)
6108 FIXME("stub\n");
6109 return NULL;
6112 /***********************************************************************
6113 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6115 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6116 unsigned char *pMemory,
6117 PFORMAT_STRING pFormat)
6119 FIXME("stub\n");
6122 /***********************************************************************
6123 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6125 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6126 PFORMAT_STRING pFormat)
6128 FIXME("stub\n");
6129 return 0;
6132 /***********************************************************************
6133 * NdrXmitOrRepAsFree [RPCRT4.@]
6135 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6136 unsigned char *pMemory,
6137 PFORMAT_STRING pFormat)
6139 FIXME("stub\n");
6142 /***********************************************************************
6143 * NdrRangeMarshall [internal]
6145 static unsigned char *WINAPI NdrRangeMarshall(
6146 PMIDL_STUB_MESSAGE pStubMsg,
6147 unsigned char *pMemory,
6148 PFORMAT_STRING pFormat)
6150 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6151 unsigned char base_type;
6153 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6155 if (pRange->type != RPC_FC_RANGE)
6157 ERR("invalid format type %x\n", pRange->type);
6158 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6159 return NULL;
6162 base_type = pRange->flags_type & 0xf;
6164 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6167 /***********************************************************************
6168 * NdrRangeUnmarshall [RPCRT4.@]
6170 unsigned char *WINAPI NdrRangeUnmarshall(
6171 PMIDL_STUB_MESSAGE pStubMsg,
6172 unsigned char **ppMemory,
6173 PFORMAT_STRING pFormat,
6174 unsigned char fMustAlloc)
6176 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6177 unsigned char base_type;
6179 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6181 if (pRange->type != RPC_FC_RANGE)
6183 ERR("invalid format type %x\n", pRange->type);
6184 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6185 return NULL;
6187 base_type = pRange->flags_type & 0xf;
6189 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6190 base_type, pRange->low_value, pRange->high_value);
6192 #define RANGE_UNMARSHALL(type, format_spec) \
6193 do \
6195 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6196 if (!fMustAlloc && !*ppMemory) \
6197 fMustAlloc = TRUE; \
6198 if (fMustAlloc) \
6199 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6200 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
6202 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6203 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6204 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6206 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
6207 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
6209 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6210 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
6211 (type)pRange->high_value); \
6212 RpcRaiseException(RPC_S_INVALID_BOUND); \
6213 return NULL; \
6215 TRACE("*ppMemory: %p\n", *ppMemory); \
6216 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6217 pStubMsg->Buffer += sizeof(type); \
6218 } while (0)
6220 switch(base_type)
6222 case RPC_FC_CHAR:
6223 case RPC_FC_SMALL:
6224 RANGE_UNMARSHALL(UCHAR, "%d");
6225 TRACE("value: 0x%02x\n", **ppMemory);
6226 break;
6227 case RPC_FC_BYTE:
6228 case RPC_FC_USMALL:
6229 RANGE_UNMARSHALL(CHAR, "%u");
6230 TRACE("value: 0x%02x\n", **ppMemory);
6231 break;
6232 case RPC_FC_WCHAR: /* FIXME: valid? */
6233 case RPC_FC_USHORT:
6234 RANGE_UNMARSHALL(USHORT, "%u");
6235 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6236 break;
6237 case RPC_FC_SHORT:
6238 RANGE_UNMARSHALL(SHORT, "%d");
6239 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6240 break;
6241 case RPC_FC_LONG:
6242 RANGE_UNMARSHALL(LONG, "%d");
6243 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6244 break;
6245 case RPC_FC_ULONG:
6246 RANGE_UNMARSHALL(ULONG, "%u");
6247 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6248 break;
6249 case RPC_FC_ENUM16:
6250 case RPC_FC_ENUM32:
6251 FIXME("Unhandled enum type\n");
6252 break;
6253 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
6254 case RPC_FC_FLOAT:
6255 case RPC_FC_DOUBLE:
6256 case RPC_FC_HYPER:
6257 default:
6258 ERR("invalid range base type: 0x%02x\n", base_type);
6259 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6262 return NULL;
6265 /***********************************************************************
6266 * NdrRangeBufferSize [internal]
6268 static void WINAPI NdrRangeBufferSize(
6269 PMIDL_STUB_MESSAGE pStubMsg,
6270 unsigned char *pMemory,
6271 PFORMAT_STRING pFormat)
6273 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6274 unsigned char base_type;
6276 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6278 if (pRange->type != RPC_FC_RANGE)
6280 ERR("invalid format type %x\n", pRange->type);
6281 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6283 base_type = pRange->flags_type & 0xf;
6285 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6288 /***********************************************************************
6289 * NdrRangeMemorySize [internal]
6291 static ULONG WINAPI NdrRangeMemorySize(
6292 PMIDL_STUB_MESSAGE pStubMsg,
6293 PFORMAT_STRING pFormat)
6295 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6296 unsigned char base_type;
6298 if (pRange->type != RPC_FC_RANGE)
6300 ERR("invalid format type %x\n", pRange->type);
6301 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6302 return 0;
6304 base_type = pRange->flags_type & 0xf;
6306 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6309 /***********************************************************************
6310 * NdrRangeFree [internal]
6312 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6313 unsigned char *pMemory,
6314 PFORMAT_STRING pFormat)
6316 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6318 /* nothing to do */
6321 /***********************************************************************
6322 * NdrBaseTypeMarshall [internal]
6324 static unsigned char *WINAPI NdrBaseTypeMarshall(
6325 PMIDL_STUB_MESSAGE pStubMsg,
6326 unsigned char *pMemory,
6327 PFORMAT_STRING pFormat)
6329 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6331 switch(*pFormat)
6333 case RPC_FC_BYTE:
6334 case RPC_FC_CHAR:
6335 case RPC_FC_SMALL:
6336 case RPC_FC_USMALL:
6337 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6338 TRACE("value: 0x%02x\n", *pMemory);
6339 break;
6340 case RPC_FC_WCHAR:
6341 case RPC_FC_SHORT:
6342 case RPC_FC_USHORT:
6343 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6344 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6345 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6346 break;
6347 case RPC_FC_LONG:
6348 case RPC_FC_ULONG:
6349 case RPC_FC_ERROR_STATUS_T:
6350 case RPC_FC_ENUM32:
6351 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6352 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6353 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6354 break;
6355 case RPC_FC_FLOAT:
6356 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6357 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6358 break;
6359 case RPC_FC_DOUBLE:
6360 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6361 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6362 break;
6363 case RPC_FC_HYPER:
6364 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6365 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6366 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6367 break;
6368 case RPC_FC_ENUM16:
6369 /* only 16-bits on the wire, so do a sanity check */
6370 if (*(UINT *)pMemory > SHRT_MAX)
6371 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6372 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6373 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6374 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6375 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6376 pStubMsg->Buffer += sizeof(USHORT);
6377 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6378 break;
6379 case RPC_FC_IGNORE:
6380 break;
6381 default:
6382 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6385 /* FIXME: what is the correct return value? */
6386 return NULL;
6389 /***********************************************************************
6390 * NdrBaseTypeUnmarshall [internal]
6392 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6393 PMIDL_STUB_MESSAGE pStubMsg,
6394 unsigned char **ppMemory,
6395 PFORMAT_STRING pFormat,
6396 unsigned char fMustAlloc)
6398 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6400 #define BASE_TYPE_UNMARSHALL(type) \
6401 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6402 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6404 *ppMemory = pStubMsg->Buffer; \
6405 TRACE("*ppMemory: %p\n", *ppMemory); \
6406 safe_buffer_increment(pStubMsg, sizeof(type)); \
6408 else \
6410 if (fMustAlloc) \
6411 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6412 TRACE("*ppMemory: %p\n", *ppMemory); \
6413 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6416 switch(*pFormat)
6418 case RPC_FC_BYTE:
6419 case RPC_FC_CHAR:
6420 case RPC_FC_SMALL:
6421 case RPC_FC_USMALL:
6422 BASE_TYPE_UNMARSHALL(UCHAR);
6423 TRACE("value: 0x%02x\n", **ppMemory);
6424 break;
6425 case RPC_FC_WCHAR:
6426 case RPC_FC_SHORT:
6427 case RPC_FC_USHORT:
6428 BASE_TYPE_UNMARSHALL(USHORT);
6429 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6430 break;
6431 case RPC_FC_LONG:
6432 case RPC_FC_ULONG:
6433 case RPC_FC_ERROR_STATUS_T:
6434 case RPC_FC_ENUM32:
6435 BASE_TYPE_UNMARSHALL(ULONG);
6436 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6437 break;
6438 case RPC_FC_FLOAT:
6439 BASE_TYPE_UNMARSHALL(float);
6440 TRACE("value: %f\n", **(float **)ppMemory);
6441 break;
6442 case RPC_FC_DOUBLE:
6443 BASE_TYPE_UNMARSHALL(double);
6444 TRACE("value: %f\n", **(double **)ppMemory);
6445 break;
6446 case RPC_FC_HYPER:
6447 BASE_TYPE_UNMARSHALL(ULONGLONG);
6448 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6449 break;
6450 case RPC_FC_ENUM16:
6451 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6452 if (!fMustAlloc && !*ppMemory)
6453 fMustAlloc = TRUE;
6454 if (fMustAlloc)
6455 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6456 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6457 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6458 TRACE("*ppMemory: %p\n", *ppMemory);
6459 /* 16-bits on the wire, but int in memory */
6460 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6461 pStubMsg->Buffer += sizeof(USHORT);
6462 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6463 break;
6464 case RPC_FC_IGNORE:
6465 break;
6466 default:
6467 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6469 #undef BASE_TYPE_UNMARSHALL
6471 /* FIXME: what is the correct return value? */
6473 return NULL;
6476 /***********************************************************************
6477 * NdrBaseTypeBufferSize [internal]
6479 static void WINAPI NdrBaseTypeBufferSize(
6480 PMIDL_STUB_MESSAGE pStubMsg,
6481 unsigned char *pMemory,
6482 PFORMAT_STRING pFormat)
6484 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6486 switch(*pFormat)
6488 case RPC_FC_BYTE:
6489 case RPC_FC_CHAR:
6490 case RPC_FC_SMALL:
6491 case RPC_FC_USMALL:
6492 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6493 break;
6494 case RPC_FC_WCHAR:
6495 case RPC_FC_SHORT:
6496 case RPC_FC_USHORT:
6497 case RPC_FC_ENUM16:
6498 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6499 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6500 break;
6501 case RPC_FC_LONG:
6502 case RPC_FC_ULONG:
6503 case RPC_FC_ENUM32:
6504 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6505 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6506 break;
6507 case RPC_FC_FLOAT:
6508 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6509 safe_buffer_length_increment(pStubMsg, sizeof(float));
6510 break;
6511 case RPC_FC_DOUBLE:
6512 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6513 safe_buffer_length_increment(pStubMsg, sizeof(double));
6514 break;
6515 case RPC_FC_HYPER:
6516 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6517 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6518 break;
6519 case RPC_FC_ERROR_STATUS_T:
6520 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6521 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6522 break;
6523 case RPC_FC_IGNORE:
6524 break;
6525 default:
6526 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6530 /***********************************************************************
6531 * NdrBaseTypeMemorySize [internal]
6533 static ULONG WINAPI NdrBaseTypeMemorySize(
6534 PMIDL_STUB_MESSAGE pStubMsg,
6535 PFORMAT_STRING pFormat)
6537 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6539 switch(*pFormat)
6541 case RPC_FC_BYTE:
6542 case RPC_FC_CHAR:
6543 case RPC_FC_SMALL:
6544 case RPC_FC_USMALL:
6545 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6546 pStubMsg->MemorySize += sizeof(UCHAR);
6547 return sizeof(UCHAR);
6548 case RPC_FC_WCHAR:
6549 case RPC_FC_SHORT:
6550 case RPC_FC_USHORT:
6551 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6552 pStubMsg->MemorySize += sizeof(USHORT);
6553 return sizeof(USHORT);
6554 case RPC_FC_LONG:
6555 case RPC_FC_ULONG:
6556 case RPC_FC_ENUM32:
6557 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6558 pStubMsg->MemorySize += sizeof(ULONG);
6559 return sizeof(ULONG);
6560 case RPC_FC_FLOAT:
6561 safe_buffer_increment(pStubMsg, sizeof(float));
6562 pStubMsg->MemorySize += sizeof(float);
6563 return sizeof(float);
6564 case RPC_FC_DOUBLE:
6565 safe_buffer_increment(pStubMsg, sizeof(double));
6566 pStubMsg->MemorySize += sizeof(double);
6567 return sizeof(double);
6568 case RPC_FC_HYPER:
6569 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6570 pStubMsg->MemorySize += sizeof(ULONGLONG);
6571 return sizeof(ULONGLONG);
6572 case RPC_FC_ERROR_STATUS_T:
6573 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6574 pStubMsg->MemorySize += sizeof(error_status_t);
6575 return sizeof(error_status_t);
6576 case RPC_FC_ENUM16:
6577 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6578 pStubMsg->MemorySize += sizeof(UINT);
6579 return sizeof(UINT);
6580 case RPC_FC_IGNORE:
6581 pStubMsg->MemorySize += sizeof(void *);
6582 return sizeof(void *);
6583 default:
6584 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6585 return 0;
6589 /***********************************************************************
6590 * NdrBaseTypeFree [internal]
6592 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6593 unsigned char *pMemory,
6594 PFORMAT_STRING pFormat)
6596 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6598 /* nothing to do */
6601 /***********************************************************************
6602 * NdrContextHandleBufferSize [internal]
6604 static void WINAPI NdrContextHandleBufferSize(
6605 PMIDL_STUB_MESSAGE pStubMsg,
6606 unsigned char *pMemory,
6607 PFORMAT_STRING pFormat)
6609 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6611 if (*pFormat != RPC_FC_BIND_CONTEXT)
6613 ERR("invalid format type %x\n", *pFormat);
6614 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6616 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6617 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6620 /***********************************************************************
6621 * NdrContextHandleMarshall [internal]
6623 static unsigned char *WINAPI NdrContextHandleMarshall(
6624 PMIDL_STUB_MESSAGE pStubMsg,
6625 unsigned char *pMemory,
6626 PFORMAT_STRING pFormat)
6628 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6630 if (*pFormat != RPC_FC_BIND_CONTEXT)
6632 ERR("invalid format type %x\n", *pFormat);
6633 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6635 TRACE("flags: 0x%02x\n", pFormat[1]);
6637 if (pFormat[1] & 0x80)
6638 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6639 else
6640 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6642 return NULL;
6645 /***********************************************************************
6646 * NdrContextHandleUnmarshall [internal]
6648 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6649 PMIDL_STUB_MESSAGE pStubMsg,
6650 unsigned char **ppMemory,
6651 PFORMAT_STRING pFormat,
6652 unsigned char fMustAlloc)
6654 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6655 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6657 if (*pFormat != RPC_FC_BIND_CONTEXT)
6659 ERR("invalid format type %x\n", *pFormat);
6660 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6662 TRACE("flags: 0x%02x\n", pFormat[1]);
6664 /* [out]-only or [ret] param */
6665 if ((pFormat[1] & 0x60) == 0x20)
6666 **(NDR_CCONTEXT **)ppMemory = NULL;
6667 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6669 return NULL;
6672 /***********************************************************************
6673 * NdrClientContextMarshall [RPCRT4.@]
6675 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6676 NDR_CCONTEXT ContextHandle,
6677 int fCheck)
6679 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6681 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6683 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6685 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6686 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6687 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6690 /* FIXME: what does fCheck do? */
6691 NDRCContextMarshall(ContextHandle,
6692 pStubMsg->Buffer);
6694 pStubMsg->Buffer += cbNDRContext;
6697 /***********************************************************************
6698 * NdrClientContextUnmarshall [RPCRT4.@]
6700 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6701 NDR_CCONTEXT * pContextHandle,
6702 RPC_BINDING_HANDLE BindHandle)
6704 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6706 ALIGN_POINTER(pStubMsg->Buffer, 4);
6708 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6709 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6711 NDRCContextUnmarshall(pContextHandle,
6712 BindHandle,
6713 pStubMsg->Buffer,
6714 pStubMsg->RpcMsg->DataRepresentation);
6716 pStubMsg->Buffer += cbNDRContext;
6719 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6720 NDR_SCONTEXT ContextHandle,
6721 NDR_RUNDOWN RundownRoutine )
6723 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6725 ALIGN_POINTER(pStubMsg->Buffer, 4);
6727 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6729 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6730 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6731 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6734 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6735 pStubMsg->Buffer, RundownRoutine, NULL,
6736 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6737 pStubMsg->Buffer += cbNDRContext;
6740 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6742 NDR_SCONTEXT ContextHandle;
6744 TRACE("(%p)\n", pStubMsg);
6746 ALIGN_POINTER(pStubMsg->Buffer, 4);
6748 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6750 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6751 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6752 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6755 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6756 pStubMsg->Buffer,
6757 pStubMsg->RpcMsg->DataRepresentation,
6758 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6759 pStubMsg->Buffer += cbNDRContext;
6761 return ContextHandle;
6764 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6765 unsigned char* pMemory,
6766 PFORMAT_STRING pFormat)
6768 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6771 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6772 PFORMAT_STRING pFormat)
6774 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6775 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6777 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6779 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6780 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6781 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6782 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6783 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6785 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6786 if_id = &sif->InterfaceId;
6789 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6790 pStubMsg->RpcMsg->DataRepresentation, if_id,
6791 flags);
6794 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6795 NDR_SCONTEXT ContextHandle,
6796 NDR_RUNDOWN RundownRoutine,
6797 PFORMAT_STRING pFormat)
6799 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6800 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6802 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6804 ALIGN_POINTER(pStubMsg->Buffer, 4);
6806 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6808 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6809 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6810 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6813 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6814 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6815 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6816 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6817 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6819 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6820 if_id = &sif->InterfaceId;
6823 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6824 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6825 pStubMsg->Buffer += cbNDRContext;
6828 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6829 PFORMAT_STRING pFormat)
6831 NDR_SCONTEXT ContextHandle;
6832 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6833 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6835 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6837 ALIGN_POINTER(pStubMsg->Buffer, 4);
6839 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6841 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6842 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6843 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6846 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6847 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6848 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6849 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6850 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6852 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6853 if_id = &sif->InterfaceId;
6856 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6857 pStubMsg->Buffer,
6858 pStubMsg->RpcMsg->DataRepresentation,
6859 if_id, flags);
6860 pStubMsg->Buffer += cbNDRContext;
6862 return ContextHandle;
6865 /***********************************************************************
6866 * NdrCorrelationInitialize [RPCRT4.@]
6868 * Initializes correlation validity checking.
6870 * PARAMS
6871 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6872 * pMemory [I] Pointer to memory to use as a cache.
6873 * CacheSize [I] Size of the memory pointed to by pMemory.
6874 * Flags [I] Reserved. Set to zero.
6876 * RETURNS
6877 * Nothing.
6879 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6881 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6882 pStubMsg->fHasNewCorrDesc = TRUE;
6885 /***********************************************************************
6886 * NdrCorrelationPass [RPCRT4.@]
6888 * Performs correlation validity checking.
6890 * PARAMS
6891 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6893 * RETURNS
6894 * Nothing.
6896 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6898 FIXME("(%p): stub\n", pStubMsg);
6901 /***********************************************************************
6902 * NdrCorrelationFree [RPCRT4.@]
6904 * Frees any resources used while unmarshalling parameters that need
6905 * correlation validity checking.
6907 * PARAMS
6908 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6910 * RETURNS
6911 * Nothing.
6913 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6915 FIXME("(%p): stub\n", pStubMsg);