Merge freeldr from amd64 branch:
[reactos.git] / reactos / dll / win32 / rpcrt4 / ndr_marshall.c
1 /*
2 * NDR data marshalling
3 *
4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
6 *
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.
11 *
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.
16 *
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
20 *
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
28 */
29
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <limits.h>
34
35 #include "windef.h"
36 #include "winbase.h"
37 #include "winerror.h"
38
39 #include "ndr_misc.h"
40 #include "rpcndr.h"
41
42 #include "wine/unicode.h"
43 #include "wine/rpcfc.h"
44
45 #include "wine/debug.h"
46
47 WINE_DEFAULT_DEBUG_CHANNEL(ole);
48
49 #if defined(__i386__)
50 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
51 (*((UINT32 *)(pchar)) = (uint32))
52
53 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
54 (*((UINT32 *)(pchar)))
55 #else
56 /* these would work for i386 too, but less efficient */
57 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
58 (*(pchar) = LOBYTE(LOWORD(uint32)), \
59 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
60 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
61 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
62
63 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
64 (MAKELONG( \
65 MAKEWORD(*(pchar), *((pchar)+1)), \
66 MAKEWORD(*((pchar)+2), *((pchar)+3))))
67 #endif
68
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)))
74
75 #define BIG_ENDIAN_UINT32_READ(pchar) \
76 (MAKELONG( \
77 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
78 MAKEWORD(*((pchar)+1), *(pchar))))
79
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
91
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)
103
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)
109
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
114
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);
120
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);
124
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);
129
130 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
131
132 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
133 0,
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
173 };
174 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
175 0,
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
215 };
216 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
217 0,
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
257 };
258 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
259 0,
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 */
292 0,
293 /* 0xb1 */
294 0, 0, 0,
295 NdrUserMarshalMemorySize,
296 0, 0,
297 /* 0xb7 */
298 NdrRangeMemorySize
299 };
300 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
301 0,
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,
328 0,
329 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
330 /* 0x2f */
331 NdrInterfacePointerFree,
332 /* 0x30 */
333 0,
334 /* 0xb1 */
335 0, 0, 0,
336 NdrUserMarshalFree,
337 0, 0,
338 /* 0xb7 */
339 NdrRangeFree
340 };
341
342 typedef struct _NDR_MEMORY_LIST
343 {
344 ULONG magic;
345 ULONG size;
346 ULONG reserved;
347 struct _NDR_MEMORY_LIST *next;
348 } NDR_MEMORY_LIST;
349
350 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
351
352 /***********************************************************************
353 * NdrAllocate [RPCRT4.@]
354 *
355 * Allocates a block of memory using pStubMsg->pfnAllocate.
356 *
357 * PARAMS
358 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
359 * len [I] Size of memory block to allocate.
360 *
361 * RETURNS
362 * The memory block of size len that was allocated.
363 *
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.
368 */
369 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
370 {
371 SIZE_T aligned_len;
372 SIZE_T adjusted_len;
373 void *p;
374 NDR_MEMORY_LIST *mem_list;
375
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)
380 {
381 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
382 RpcRaiseException(RPC_X_BAD_STUB_DATA);
383 }
384
385 p = pStubMsg->pfnAllocate(adjusted_len);
386 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
387
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;
394
395 TRACE("-- %p\n", p);
396 return p;
397 }
398
399 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
400 {
401 TRACE("(%p, %p)\n", pStubMsg, Pointer);
402
403 pStubMsg->pfnFree(Pointer);
404 }
405
406 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
407 {
408 return (*(const ULONG *)pFormat != -1);
409 }
410
411 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
412 {
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;
423 }
424
425 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
426 {
427 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
428 {
429 pStubMsg->Offset = 0;
430 pStubMsg->ActualCount = pStubMsg->MaxCount;
431 goto done;
432 }
433
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);
443
444 if ((pStubMsg->ActualCount > MaxValue) ||
445 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
446 {
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;
451 }
452
453 done:
454 if (pStubMsg->fHasNewCorrDesc)
455 return pFormat+6;
456 else
457 return pFormat+4;
458 }
459
460 /* writes the conformance value to the buffer */
461 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
462 {
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;
468 }
469
470 /* writes the variance values to the buffer */
471 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
472 {
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;
480 }
481
482 /* requests buffer space for the conformance value */
483 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
484 {
485 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
486 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
487 RpcRaiseException(RPC_X_BAD_STUB_DATA);
488 pStubMsg->BufferLength += 4;
489 }
490
491 /* requests buffer space for the variance values */
492 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
493 {
494 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
495 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
496 RpcRaiseException(RPC_X_BAD_STUB_DATA);
497 pStubMsg->BufferLength += 8;
498 }
499
500 PFORMAT_STRING ComputeConformanceOrVariance(
501 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
502 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
503 {
504 BYTE dtype = pFormat[0] & 0xf;
505 short ofs = *(const short *)&pFormat[2];
506 LPVOID ptr = NULL;
507 DWORD data = 0;
508
509 if (!IsConformanceOrVariancePresent(pFormat)) {
510 /* null descriptor */
511 *pCount = def;
512 goto finish_conf;
513 }
514
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;
528 }
529 else {
530 /* -Os mode, *pCount is already set */
531 goto finish_conf;
532 }
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;
543 }
544 else {
545 /* ? */
546 goto done_conf_grab;
547 }
548 break;
549 default:
550 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
551 }
552
553 switch (pFormat[1]) {
554 case RPC_FC_DEREFERENCE:
555 ptr = *(LPVOID*)((char *)ptr + ofs);
556 break;
557 case RPC_FC_CALLBACK:
558 {
559 unsigned char *old_stack_top = pStubMsg->StackTop;
560 pStubMsg->StackTop = ptr;
561
562 /* ofs is index into StubDesc->apfnExprEval */
563 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
564 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
565
566 pStubMsg->StackTop = old_stack_top;
567
568 /* the callback function always stores the computed value in MaxCount */
569 *pCount = pStubMsg->MaxCount;
570 goto finish_conf;
571 }
572 default:
573 ptr = (char *)ptr + ofs;
574 break;
575 }
576
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;
599 }
600 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
601
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;
623 }
624
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;
631 }
632
633 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
634 PFORMAT_STRING pFormat)
635 {
636 if (IsConformanceOrVariancePresent(pFormat))
637 {
638 if (pStubMsg->fHasNewCorrDesc)
639 pFormat += 6;
640 else
641 pFormat += 4;
642 }
643 return pFormat;
644 }
645
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)
649 {
650 ULONGLONG ret = (ULONGLONG)a * b;
651 if (ret > 0xffffffff)
652 {
653 RpcRaiseException(RPC_S_INVALID_BOUND);
654 return 0;
655 }
656 return ret;
657 }
658
659 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
660 {
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;
665 }
666
667 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
668 {
669 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
670 {
671 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
672 pStubMsg->BufferLength, size);
673 RpcRaiseException(RPC_X_BAD_STUB_DATA);
674 }
675 pStubMsg->BufferLength += size;
676 }
677
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)
681 {
682 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
683 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
684 {
685 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
686 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
687 RpcRaiseException(RPC_X_BAD_STUB_DATA);
688 }
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;
693 }
694
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)
697 {
698 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
699 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
700 {
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);
705 }
706 memcpy(pStubMsg->Buffer, p, size);
707 pStubMsg->Buffer += size;
708 }
709
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)
713 {
714 ULONG i;
715
716 /* verify the buffer is safe to access */
717 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
718 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
719 {
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);
723 }
724
725 /* strings must always have null terminating bytes */
726 if (bufsize < esize)
727 {
728 ERR("invalid string length of %d\n", bufsize / esize);
729 RpcRaiseException(RPC_S_INVALID_BOUND);
730 }
731
732 for (i = bufsize - esize; i < bufsize; i++)
733 if (pStubMsg->Buffer[i] != 0)
734 {
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);
738 }
739 }
740
741 static inline void dump_pointer_attr(unsigned char attr)
742 {
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");
754 }
755
756 /***********************************************************************
757 * PointerMarshall [internal]
758 */
759 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
760 unsigned char *Buffer,
761 unsigned char *Pointer,
762 PFORMAT_STRING pFormat)
763 {
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;
769
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;
775
776 switch (type) {
777 case RPC_FC_RP: /* ref pointer (always non-null) */
778 if (!Pointer)
779 {
780 ERR("NULL ref pointer is not allowed\n");
781 RpcRaiseException(RPC_X_NULL_REF_POINTER);
782 }
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;
805 }
806
807 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
808
809 if (pointer_needs_marshaling) {
810 if (attr & RPC_FC_P_DEREF) {
811 Pointer = *(unsigned char**)Pointer;
812 TRACE("deref => %p\n", Pointer);
813 }
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);
817 }
818
819 STD_OVERFLOW_CHECK(pStubMsg);
820 }
821
822 /***********************************************************************
823 * PointerUnmarshall [internal]
824 */
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)
831 {
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;
837
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;
843
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;
856 }
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)
862 {
863 FIXME("free object pointer %p\n", pSrcPointer);
864 fMustAlloc = TRUE;
865 }
866 if (pointer_id)
867 pointer_needs_unmarshaling = 1;
868 else
869 {
870 *pPointer = NULL;
871 pointer_needs_unmarshaling = 0;
872 }
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;
884 }
885
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;
903 }
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;
915 }
916 }
917
918 if (attr & RPC_FC_P_ALLOCALLNODES)
919 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
920
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;
930 }
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);
934
935 if (type == RPC_FC_FP)
936 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
937 base_ptr_val);
938 }
939
940 TRACE("pointer=%p\n", *pPointer);
941 }
942
943 /***********************************************************************
944 * PointerBufferSize [internal]
945 */
946 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
947 unsigned char *Pointer,
948 PFORMAT_STRING pFormat)
949 {
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;
955
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;
961
962 switch (type) {
963 case RPC_FC_RP: /* ref pointer (always non-null) */
964 if (!Pointer)
965 {
966 ERR("NULL ref pointer is not allowed\n");
967 RpcRaiseException(RPC_X_NULL_REF_POINTER);
968 }
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;
986 }
987
988 if (attr & RPC_FC_P_DEREF) {
989 Pointer = *(unsigned char**)Pointer;
990 TRACE("deref => %p\n", Pointer);
991 }
992
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);
996 }
997
998 /***********************************************************************
999 * PointerMemorySize [internal]
1000 */
1001 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1002 unsigned char *Buffer,
1003 PFORMAT_STRING pFormat)
1004 {
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;
1010
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;
1016
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:
1031 {
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;
1038 }
1039 default:
1040 FIXME("unhandled ptr type=%02x\n", type);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1042 return 0;
1043 }
1044
1045 if (attr & RPC_FC_P_DEREF) {
1046 TRACE("deref\n");
1047 }
1048
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);
1053 }
1054
1055 return pStubMsg->MemorySize;
1056 }
1057
1058 /***********************************************************************
1059 * PointerFree [internal]
1060 */
1061 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1062 unsigned char *Pointer,
1063 PFORMAT_STRING pFormat)
1064 {
1065 unsigned type = pFormat[0], attr = pFormat[1];
1066 PFORMAT_STRING desc;
1067 NDR_FREE m;
1068 unsigned char *current_pointer = Pointer;
1069
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;
1076
1077 if (!Pointer) return;
1078
1079 if (type == RPC_FC_FP) {
1080 int pointer_needs_freeing = NdrFullPointerFree(
1081 pStubMsg->FullPtrXlatTables, Pointer);
1082 if (!pointer_needs_freeing)
1083 return;
1084 }
1085
1086 if (attr & RPC_FC_P_DEREF) {
1087 current_pointer = *(unsigned char**)Pointer;
1088 TRACE("deref => %p\n", current_pointer);
1089 }
1090
1091 m = NdrFreer[*desc & NDR_TABLE_MASK];
1092 if (m) m(pStubMsg, current_pointer, desc);
1093
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;
1102
1103 if (attr & RPC_FC_P_ONSTACK) {
1104 TRACE("not freeing stack ptr %p\n", Pointer);
1105 return;
1106 }
1107 TRACE("freeing %p\n", Pointer);
1108 NdrFree(pStubMsg, Pointer);
1109 return;
1110 notfree:
1111 TRACE("not freeing %p\n", Pointer);
1112 }
1113
1114 /***********************************************************************
1115 * EmbeddedPointerMarshall
1116 */
1117 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1118 unsigned char *pMemory,
1119 PFORMAT_STRING pFormat)
1120 {
1121 unsigned char *Mark = pStubMsg->BufferMark;
1122 unsigned rep, count, stride;
1123 unsigned i;
1124 unsigned char *saved_buffer = NULL;
1125
1126 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1127
1128 if (*pFormat != RPC_FC_PP) return NULL;
1129 pFormat += 2;
1130
1131 if (pStubMsg->PointerBufferMark)
1132 {
1133 saved_buffer = pStubMsg->Buffer;
1134 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1135 pStubMsg->PointerBufferMark = NULL;
1136 }
1137
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;
1160 }
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;
1166
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;
1171
1172 pStubMsg->Memory = pMemory;
1173 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1174 pStubMsg->Memory = saved_memory;
1175 }
1176 }
1177 pFormat += 8 * count;
1178 }
1179
1180 if (saved_buffer)
1181 {
1182 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1183 pStubMsg->Buffer = saved_buffer;
1184 }
1185
1186 STD_OVERFLOW_CHECK(pStubMsg);
1187
1188 return NULL;
1189 }
1190
1191 /***********************************************************************
1192 * EmbeddedPointerUnmarshall
1193 */
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)
1199 {
1200 unsigned char *Mark = pStubMsg->BufferMark;
1201 unsigned rep, count, stride;
1202 unsigned i;
1203 unsigned char *saved_buffer = NULL;
1204
1205 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1206
1207 if (*pFormat != RPC_FC_PP) return NULL;
1208 pFormat += 2;
1209
1210 if (pStubMsg->PointerBufferMark)
1211 {
1212 saved_buffer = pStubMsg->Buffer;
1213 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1214 pStubMsg->PointerBufferMark = NULL;
1215 }
1216
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;
1240 }
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;
1247
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);
1253 }
1254 }
1255 pFormat += 8 * count;
1256 }
1257
1258 if (saved_buffer)
1259 {
1260 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1261 pStubMsg->Buffer = saved_buffer;
1262 }
1263
1264 return NULL;
1265 }
1266
1267 /***********************************************************************
1268 * EmbeddedPointerBufferSize
1269 */
1270 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1271 unsigned char *pMemory,
1272 PFORMAT_STRING pFormat)
1273 {
1274 unsigned rep, count, stride;
1275 unsigned i;
1276 ULONG saved_buffer_length = 0;
1277
1278 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1279
1280 if (pStubMsg->IgnoreEmbeddedPointers) return;
1281
1282 if (*pFormat != RPC_FC_PP) return;
1283 pFormat += 2;
1284
1285 if (pStubMsg->PointerLength)
1286 {
1287 saved_buffer_length = pStubMsg->BufferLength;
1288 pStubMsg->BufferLength = pStubMsg->PointerLength;
1289 pStubMsg->PointerLength = 0;
1290 }
1291
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;
1314 }
1315 for (i = 0; i < rep; i++) {
1316 PFORMAT_STRING info = pFormat;
1317 unsigned char *membase = pMemory + (i * stride);
1318 unsigned u;
1319
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;
1323
1324 pStubMsg->Memory = pMemory;
1325 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1326 pStubMsg->Memory = saved_memory;
1327 }
1328 }
1329 pFormat += 8 * count;
1330 }
1331
1332 if (saved_buffer_length)
1333 {
1334 pStubMsg->PointerLength = pStubMsg->BufferLength;
1335 pStubMsg->BufferLength = saved_buffer_length;
1336 }
1337 }
1338
1339 /***********************************************************************
1340 * EmbeddedPointerMemorySize [internal]
1341 */
1342 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1343 PFORMAT_STRING pFormat)
1344 {
1345 unsigned char *Mark = pStubMsg->BufferMark;
1346 unsigned rep, count, stride;
1347 unsigned i;
1348 unsigned char *saved_buffer = NULL;
1349
1350 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1351
1352 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1353
1354 if (pStubMsg->PointerBufferMark)
1355 {
1356 saved_buffer = pStubMsg->Buffer;
1357 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1358 pStubMsg->PointerBufferMark = NULL;
1359 }
1360
1361 if (*pFormat != RPC_FC_PP) return 0;
1362 pFormat += 2;
1363
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;
1386 }
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);
1394 }
1395 }
1396 pFormat += 8 * count;
1397 }
1398
1399 if (saved_buffer)
1400 {
1401 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1402 pStubMsg->Buffer = saved_buffer;
1403 }
1404
1405 return 0;
1406 }
1407
1408 /***********************************************************************
1409 * EmbeddedPointerFree [internal]
1410 */
1411 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1412 unsigned char *pMemory,
1413 PFORMAT_STRING pFormat)
1414 {
1415 unsigned rep, count, stride;
1416 unsigned i;
1417
1418 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1419 if (*pFormat != RPC_FC_PP) return;
1420 pFormat += 2;
1421
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;
1444 }
1445 for (i = 0; i < rep; i++) {
1446 PFORMAT_STRING info = pFormat;
1447 unsigned char *membase = pMemory + (i * stride);
1448 unsigned u;
1449
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;
1453
1454 pStubMsg->Memory = pMemory;
1455 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1456 pStubMsg->Memory = saved_memory;
1457 }
1458 }
1459 pFormat += 8 * count;
1460 }
1461 }
1462
1463 /***********************************************************************
1464 * NdrPointerMarshall [RPCRT4.@]
1465 */
1466 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1467 unsigned char *pMemory,
1468 PFORMAT_STRING pFormat)
1469 {
1470 unsigned char *Buffer;
1471
1472 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1473
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)
1478 {
1479 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1480 Buffer = pStubMsg->Buffer;
1481 safe_buffer_increment(pStubMsg, 4);
1482 }
1483 else
1484 Buffer = pStubMsg->Buffer;
1485
1486 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1487
1488 return NULL;
1489 }
1490
1491 /***********************************************************************
1492 * NdrPointerUnmarshall [RPCRT4.@]
1493 */
1494 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1495 unsigned char **ppMemory,
1496 PFORMAT_STRING pFormat,
1497 unsigned char fMustAlloc)
1498 {
1499 unsigned char *Buffer;
1500
1501 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1502
1503 /* Increment the buffer here instead of in PointerUnmarshall,
1504 * as that is used by embedded pointers which already handle the incrementing
1505 * the buffer, and shouldn't read any additional pointer data from the
1506 * buffer */
1507 if (*pFormat != RPC_FC_RP)
1508 {
1509 ALIGN_POINTER(pStubMsg->Buffer, 4);
1510 Buffer = pStubMsg->Buffer;
1511 safe_buffer_increment(pStubMsg, 4);
1512 }
1513 else
1514 Buffer = pStubMsg->Buffer;
1515
1516 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1517
1518 return NULL;
1519 }
1520
1521 /***********************************************************************
1522 * NdrPointerBufferSize [RPCRT4.@]
1523 */
1524 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1525 unsigned char *pMemory,
1526 PFORMAT_STRING pFormat)
1527 {
1528 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1529
1530 /* Increment the buffer length here instead of in PointerBufferSize,
1531 * as that is used by embedded pointers which already handle the buffer
1532 * length, and shouldn't write anything more to the wire */
1533 if (*pFormat != RPC_FC_RP)
1534 {
1535 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1536 safe_buffer_length_increment(pStubMsg, 4);
1537 }
1538
1539 PointerBufferSize(pStubMsg, pMemory, pFormat);
1540 }
1541
1542 /***********************************************************************
1543 * NdrPointerMemorySize [RPCRT4.@]
1544 */
1545 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1546 PFORMAT_STRING pFormat)
1547 {
1548 /* unsigned size = *(LPWORD)(pFormat+2); */
1549 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1550 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1551 return 0;
1552 }
1553
1554 /***********************************************************************
1555 * NdrPointerFree [RPCRT4.@]
1556 */
1557 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1558 unsigned char *pMemory,
1559 PFORMAT_STRING pFormat)
1560 {
1561 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1562 PointerFree(pStubMsg, pMemory, pFormat);
1563 }
1564
1565 /***********************************************************************
1566 * NdrSimpleTypeMarshall [RPCRT4.@]
1567 */
1568 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1569 unsigned char FormatChar )
1570 {
1571 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1572 }
1573
1574 /***********************************************************************
1575 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1576 *
1577 * Unmarshall a base type.
1578 *
1579 * NOTES
1580 * Doesn't check that the buffer is long enough before copying, so the caller
1581 * should do this.
1582 */
1583 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1584 unsigned char FormatChar )
1585 {
1586 #define BASE_TYPE_UNMARSHALL(type) \
1587 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1588 TRACE("pMemory: %p\n", pMemory); \
1589 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1590 pStubMsg->Buffer += sizeof(type);
1591
1592 switch(FormatChar)
1593 {
1594 case RPC_FC_BYTE:
1595 case RPC_FC_CHAR:
1596 case RPC_FC_SMALL:
1597 case RPC_FC_USMALL:
1598 BASE_TYPE_UNMARSHALL(UCHAR);
1599 TRACE("value: 0x%02x\n", *pMemory);
1600 break;
1601 case RPC_FC_WCHAR:
1602 case RPC_FC_SHORT:
1603 case RPC_FC_USHORT:
1604 BASE_TYPE_UNMARSHALL(USHORT);
1605 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1606 break;
1607 case RPC_FC_LONG:
1608 case RPC_FC_ULONG:
1609 case RPC_FC_ERROR_STATUS_T:
1610 case RPC_FC_ENUM32:
1611 BASE_TYPE_UNMARSHALL(ULONG);
1612 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1613 break;
1614 case RPC_FC_FLOAT:
1615 BASE_TYPE_UNMARSHALL(float);
1616 TRACE("value: %f\n", *(float *)pMemory);
1617 break;
1618 case RPC_FC_DOUBLE:
1619 BASE_TYPE_UNMARSHALL(double);
1620 TRACE("value: %f\n", *(double *)pMemory);
1621 break;
1622 case RPC_FC_HYPER:
1623 BASE_TYPE_UNMARSHALL(ULONGLONG);
1624 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1625 break;
1626 case RPC_FC_ENUM16:
1627 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1628 TRACE("pMemory: %p\n", pMemory);
1629 /* 16-bits on the wire, but int in memory */
1630 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1631 pStubMsg->Buffer += sizeof(USHORT);
1632 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1633 break;
1634 case RPC_FC_IGNORE:
1635 break;
1636 default:
1637 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1638 }
1639 #undef BASE_TYPE_UNMARSHALL
1640 }
1641
1642 /***********************************************************************
1643 * NdrSimpleStructMarshall [RPCRT4.@]
1644 */
1645 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1646 unsigned char *pMemory,
1647 PFORMAT_STRING pFormat)
1648 {
1649 unsigned size = *(const WORD*)(pFormat+2);
1650 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1651
1652 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1653
1654 pStubMsg->BufferMark = pStubMsg->Buffer;
1655 safe_copy_to_buffer(pStubMsg, pMemory, size);
1656
1657 if (pFormat[0] != RPC_FC_STRUCT)
1658 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1659
1660 return NULL;
1661 }
1662
1663 /***********************************************************************
1664 * NdrSimpleStructUnmarshall [RPCRT4.@]
1665 */
1666 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1667 unsigned char **ppMemory,
1668 PFORMAT_STRING pFormat,
1669 unsigned char fMustAlloc)
1670 {
1671 unsigned size = *(const WORD*)(pFormat+2);
1672 unsigned char *saved_buffer;
1673 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1674
1675 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1676
1677 if (fMustAlloc)
1678 *ppMemory = NdrAllocate(pStubMsg, size);
1679 else
1680 {
1681 if (!pStubMsg->IsClient && !*ppMemory)
1682 /* for servers, we just point straight into the RPC buffer */
1683 *ppMemory = pStubMsg->Buffer;
1684 }
1685
1686 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1687 safe_buffer_increment(pStubMsg, size);
1688 if (pFormat[0] == RPC_FC_PSTRUCT)
1689 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1690
1691 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1692 if (*ppMemory != saved_buffer)
1693 memcpy(*ppMemory, saved_buffer, size);
1694
1695 return NULL;
1696 }
1697
1698 /***********************************************************************
1699 * NdrSimpleStructBufferSize [RPCRT4.@]
1700 */
1701 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1702 unsigned char *pMemory,
1703 PFORMAT_STRING pFormat)
1704 {
1705 unsigned size = *(const WORD*)(pFormat+2);
1706 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1707
1708 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1709
1710 safe_buffer_length_increment(pStubMsg, size);
1711 if (pFormat[0] != RPC_FC_STRUCT)
1712 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1713 }
1714
1715 /***********************************************************************
1716 * NdrSimpleStructMemorySize [RPCRT4.@]
1717 */
1718 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1719 PFORMAT_STRING pFormat)
1720 {
1721 unsigned short size = *(const WORD *)(pFormat+2);
1722
1723 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1724
1725 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1726 pStubMsg->MemorySize += size;
1727 safe_buffer_increment(pStubMsg, size);
1728
1729 if (pFormat[0] != RPC_FC_STRUCT)
1730 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1731 return pStubMsg->MemorySize;
1732 }
1733
1734 /***********************************************************************
1735 * NdrSimpleStructFree [RPCRT4.@]
1736 */
1737 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1738 unsigned char *pMemory,
1739 PFORMAT_STRING pFormat)
1740 {
1741 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1742 if (pFormat[0] != RPC_FC_STRUCT)
1743 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1744 }
1745
1746 /* Array helpers */
1747
1748 static inline void array_compute_and_size_conformance(
1749 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1750 PFORMAT_STRING pFormat)
1751 {
1752 switch (fc)
1753 {
1754 case RPC_FC_CARRAY:
1755 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1756 SizeConformance(pStubMsg);
1757 break;
1758 case RPC_FC_CVARRAY:
1759 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1760 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1761 SizeConformance(pStubMsg);
1762 break;
1763 case RPC_FC_C_CSTRING:
1764 case RPC_FC_C_WSTRING:
1765 if (pFormat[0] == RPC_FC_C_CSTRING)
1766 {
1767 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1768 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1769 }
1770 else
1771 {
1772 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1773 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1774 }
1775
1776 if (fc == RPC_FC_STRING_SIZED)
1777 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1778 else
1779 pStubMsg->MaxCount = pStubMsg->ActualCount;
1780
1781 SizeConformance(pStubMsg);
1782 break;
1783 default:
1784 ERR("unknown array format 0x%x\n", fc);
1785 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1786 }
1787 }
1788
1789 static inline void array_buffer_size(
1790 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1791 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1792 {
1793 DWORD size;
1794 DWORD esize;
1795 unsigned char alignment;
1796
1797 switch (fc)
1798 {
1799 case RPC_FC_CARRAY:
1800 esize = *(const WORD*)(pFormat+2);
1801 alignment = pFormat[1] + 1;
1802
1803 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1804
1805 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1806
1807 size = safe_multiply(esize, pStubMsg->MaxCount);
1808 /* conformance value plus array */
1809 safe_buffer_length_increment(pStubMsg, size);
1810
1811 if (fHasPointers)
1812 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1813 break;
1814 case RPC_FC_CVARRAY:
1815 esize = *(const WORD*)(pFormat+2);
1816 alignment = pFormat[1] + 1;
1817
1818 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1819 pFormat = SkipConformance(pStubMsg, pFormat);
1820
1821 SizeVariance(pStubMsg);
1822
1823 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1824
1825 size = safe_multiply(esize, pStubMsg->ActualCount);
1826 safe_buffer_length_increment(pStubMsg, size);
1827
1828 if (fHasPointers)
1829 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1830 break;
1831 case RPC_FC_C_CSTRING:
1832 case RPC_FC_C_WSTRING:
1833 if (fc == RPC_FC_C_CSTRING)
1834 esize = 1;
1835 else
1836 esize = 2;
1837
1838 SizeVariance(pStubMsg);
1839
1840 size = safe_multiply(esize, pStubMsg->ActualCount);
1841 safe_buffer_length_increment(pStubMsg, size);
1842 break;
1843 default:
1844 ERR("unknown array format 0x%x\n", fc);
1845 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1846 }
1847 }
1848
1849 static inline void array_compute_and_write_conformance(
1850 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1851 PFORMAT_STRING pFormat)
1852 {
1853 switch (fc)
1854 {
1855 case RPC_FC_CARRAY:
1856 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1857 WriteConformance(pStubMsg);
1858 break;
1859 case RPC_FC_CVARRAY:
1860 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1861 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1862 WriteConformance(pStubMsg);
1863 break;
1864 case RPC_FC_C_CSTRING:
1865 case RPC_FC_C_WSTRING:
1866 if (fc == RPC_FC_C_CSTRING)
1867 {
1868 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1869 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1870 }
1871 else
1872 {
1873 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1874 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1875 }
1876 if (pFormat[1] == RPC_FC_STRING_SIZED)
1877 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1878 else
1879 pStubMsg->MaxCount = pStubMsg->ActualCount;
1880 pStubMsg->Offset = 0;
1881 WriteConformance(pStubMsg);
1882 break;
1883 default:
1884 ERR("unknown array format 0x%x\n", fc);
1885 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1886 }
1887 }
1888
1889 static inline void array_write_variance_and_marshall(
1890 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1891 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1892 {
1893 DWORD size;
1894 DWORD esize;
1895 unsigned char alignment;
1896
1897 switch (fc)
1898 {
1899 case RPC_FC_CARRAY:
1900 esize = *(const WORD*)(pFormat+2);
1901 alignment = pFormat[1] + 1;
1902
1903 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1904
1905 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1906
1907 size = safe_multiply(esize, pStubMsg->MaxCount);
1908 if (fHasPointers)
1909 pStubMsg->BufferMark = pStubMsg->Buffer;
1910 safe_copy_to_buffer(pStubMsg, pMemory, size);
1911
1912 if (fHasPointers)
1913 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1914 break;
1915 case RPC_FC_CVARRAY:
1916 esize = *(const WORD*)(pFormat+2);
1917 alignment = pFormat[1] + 1;
1918
1919 /* conformance */
1920 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1921 /* variance */
1922 pFormat = SkipConformance(pStubMsg, pFormat);
1923
1924 WriteVariance(pStubMsg);
1925
1926 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1927
1928 size = safe_multiply(esize, pStubMsg->ActualCount);
1929
1930 if (fHasPointers)
1931 pStubMsg->BufferMark = pStubMsg->Buffer;
1932 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
1933
1934 if (fHasPointers)
1935 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1936 break;
1937 case RPC_FC_C_CSTRING:
1938 case RPC_FC_C_WSTRING:
1939 if (fc == RPC_FC_C_CSTRING)
1940 esize = 1;
1941 else
1942 esize = 2;
1943
1944 WriteVariance(pStubMsg);
1945
1946 size = safe_multiply(esize, pStubMsg->ActualCount);
1947 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
1948 break;
1949 default:
1950 ERR("unknown array format 0x%x\n", fc);
1951 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1952 }
1953 }
1954
1955 static inline ULONG array_read_conformance(
1956 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
1957 {
1958 DWORD esize;
1959
1960 switch (fc)
1961 {
1962 case RPC_FC_CARRAY:
1963 esize = *(const WORD*)(pFormat+2);
1964 pFormat = ReadConformance(pStubMsg, pFormat+4);
1965 return safe_multiply(esize, pStubMsg->MaxCount);
1966 case RPC_FC_CVARRAY:
1967 esize = *(const WORD*)(pFormat+2);
1968 pFormat = ReadConformance(pStubMsg, pFormat+4);
1969 return safe_multiply(esize, pStubMsg->MaxCount);
1970 case RPC_FC_C_CSTRING:
1971 case RPC_FC_C_WSTRING:
1972 if (fc == RPC_FC_C_CSTRING)
1973 esize = 1;
1974 else
1975 esize = 2;
1976
1977 if (pFormat[1] == RPC_FC_STRING_SIZED)
1978 ReadConformance(pStubMsg, pFormat + 2);
1979 else
1980 ReadConformance(pStubMsg, NULL);
1981 return safe_multiply(esize, pStubMsg->MaxCount);
1982 default:
1983 ERR("unknown array format 0x%x\n", fc);
1984 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1985 }
1986 }
1987
1988 static inline ULONG array_read_variance_and_unmarshall(
1989 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
1990 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
1991 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
1992 {
1993 ULONG bufsize, memsize;
1994 WORD esize;
1995 unsigned char alignment;
1996 unsigned char *saved_buffer;
1997 ULONG offset;
1998
1999 switch (fc)
2000 {
2001 case RPC_FC_CARRAY:
2002 esize = *(const WORD*)(pFormat+2);
2003 alignment = pFormat[1] + 1;
2004
2005 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2006
2007 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2008
2009 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2010
2011 if (fUnmarshall)
2012 {
2013 if (fMustAlloc)
2014 *ppMemory = NdrAllocate(pStubMsg, memsize);
2015 else
2016 {
2017 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2018 /* for servers, we just point straight into the RPC buffer */
2019 *ppMemory = pStubMsg->Buffer;
2020 }
2021
2022 saved_buffer = pStubMsg->Buffer;
2023 safe_buffer_increment(pStubMsg, bufsize);
2024
2025 pStubMsg->BufferMark = saved_buffer;
2026 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2027
2028 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2029 if (*ppMemory != saved_buffer)
2030 memcpy(*ppMemory, saved_buffer, bufsize);
2031 }
2032 return bufsize;
2033 case RPC_FC_CVARRAY:
2034 esize = *(const WORD*)(pFormat+2);
2035 alignment = pFormat[1] + 1;
2036
2037 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2038
2039 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2040
2041 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2042
2043 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2044 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2045
2046 if (fUnmarshall)
2047 {
2048 offset = pStubMsg->Offset;
2049
2050 if (!fMustAlloc && !*ppMemory)
2051 fMustAlloc = TRUE;
2052 if (fMustAlloc)
2053 *ppMemory = NdrAllocate(pStubMsg, memsize);
2054 saved_buffer = pStubMsg->Buffer;
2055 safe_buffer_increment(pStubMsg, bufsize);
2056
2057 pStubMsg->BufferMark = saved_buffer;
2058 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2059 fMustAlloc);
2060
2061 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2062 }
2063 return bufsize;
2064 case RPC_FC_C_CSTRING:
2065 case RPC_FC_C_WSTRING:
2066 if (fc == RPC_FC_C_CSTRING)
2067 esize = 1;
2068 else
2069 esize = 2;
2070
2071 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2072
2073 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2074 {
2075 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2076 pStubMsg->ActualCount, pStubMsg->MaxCount);
2077 RpcRaiseException(RPC_S_INVALID_BOUND);
2078 }
2079 if (pStubMsg->Offset)
2080 {
2081 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2082 RpcRaiseException(RPC_S_INVALID_BOUND);
2083 }
2084
2085 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2086 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2087
2088 validate_string_data(pStubMsg, bufsize, esize);
2089
2090 if (fUnmarshall)
2091 {
2092 if (fMustAlloc)
2093 *ppMemory = NdrAllocate(pStubMsg, memsize);
2094 else
2095 {
2096 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2097 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2098 /* if the data in the RPC buffer is big enough, we just point
2099 * straight into it */
2100 *ppMemory = pStubMsg->Buffer;
2101 else if (!*ppMemory)
2102 *ppMemory = NdrAllocate(pStubMsg, memsize);
2103 }
2104
2105 if (*ppMemory == pStubMsg->Buffer)
2106 safe_buffer_increment(pStubMsg, bufsize);
2107 else
2108 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2109
2110 if (*pFormat == RPC_FC_C_CSTRING)
2111 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2112 else
2113 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2114 }
2115 return bufsize;
2116 default:
2117 ERR("unknown array format 0x%x\n", fc);
2118 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2119 }
2120 }
2121
2122 static inline void array_memory_size(
2123 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2124 unsigned char fHasPointers)
2125 {
2126 ULONG bufsize, memsize;
2127 DWORD esize;
2128 unsigned char alignment;
2129
2130 switch (fc)
2131 {
2132 case RPC_FC_CARRAY:
2133 esize = *(const WORD*)(pFormat+2);
2134 alignment = pFormat[1] + 1;
2135
2136 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2137
2138 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2139 pStubMsg->MemorySize += memsize;
2140
2141 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2142 if (fHasPointers)
2143 pStubMsg->BufferMark = pStubMsg->Buffer;
2144 safe_buffer_increment(pStubMsg, bufsize);
2145
2146 if (fHasPointers)
2147 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2148 break;
2149 case RPC_FC_CVARRAY:
2150 esize = *(const WORD*)(pFormat+2);
2151 alignment = pFormat[1] + 1;
2152
2153 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2154
2155 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2156
2157 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2158 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2159 pStubMsg->MemorySize += memsize;
2160
2161 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2162 if (fHasPointers)
2163 pStubMsg->BufferMark = pStubMsg->Buffer;
2164 safe_buffer_increment(pStubMsg, bufsize);
2165
2166 if (fHasPointers)
2167 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2168 break;
2169 case RPC_FC_C_CSTRING:
2170 case RPC_FC_C_WSTRING:
2171 if (fc == RPC_FC_C_CSTRING)
2172 esize = 1;
2173 else
2174 esize = 2;
2175
2176 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2177
2178 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2179 {
2180 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2181 pStubMsg->ActualCount, pStubMsg->MaxCount);
2182 RpcRaiseException(RPC_S_INVALID_BOUND);
2183 }
2184 if (pStubMsg->Offset)
2185 {
2186 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2187 RpcRaiseException(RPC_S_INVALID_BOUND);
2188 }
2189
2190 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2191 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2192
2193 validate_string_data(pStubMsg, bufsize, esize);
2194
2195 safe_buffer_increment(pStubMsg, bufsize);
2196 pStubMsg->MemorySize += memsize;
2197 break;
2198 default:
2199 ERR("unknown array format 0x%x\n", fc);
2200 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2201 }
2202 }
2203
2204 static inline void array_free(
2205 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2206 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2207 {
2208 switch (fc)
2209 {
2210 case RPC_FC_CARRAY:
2211 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2212 if (fHasPointers)
2213 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2214 break;
2215 case RPC_FC_CVARRAY:
2216 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2217 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2218 if (fHasPointers)
2219 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2220 break;
2221 case RPC_FC_C_CSTRING:
2222 case RPC_FC_C_WSTRING:
2223 /* No embedded pointers so nothing to do */
2224 break;
2225 default:
2226 ERR("unknown array format 0x%x\n", fc);
2227 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2228 }
2229 }
2230
2231 /*
2232 * NdrConformantString:
2233 *
2234 * What MS calls a ConformantString is, in DCE terminology,
2235 * a Varying-Conformant String.
2236 * [
2237 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2238 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2239 * into unmarshalled string)
2240 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2241 * [
2242 * data: CHARTYPE[maxlen]
2243 * ]
2244 * ], where CHARTYPE is the appropriate character type (specified externally)
2245 *
2246 */
2247
2248 /***********************************************************************
2249 * NdrConformantStringMarshall [RPCRT4.@]
2250 */
2251 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2252 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2253 {
2254 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2255
2256 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2257 ERR("Unhandled string type: %#x\n", pFormat[0]);
2258 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2259 }
2260
2261 /* allow compiler to optimise inline function by passing constant into
2262 * these functions */
2263 if (pFormat[0] == RPC_FC_C_CSTRING) {
2264 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2265 pFormat);
2266 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2267 pFormat, TRUE /* fHasPointers */);
2268 } else {
2269 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2270 pFormat);
2271 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2272 pFormat, TRUE /* fHasPointers */);
2273 }
2274
2275 return NULL;
2276 }
2277
2278 /***********************************************************************
2279 * NdrConformantStringBufferSize [RPCRT4.@]
2280 */
2281 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2282 unsigned char* pMemory, PFORMAT_STRING pFormat)
2283 {
2284 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2285
2286 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2287 ERR("Unhandled string type: %#x\n", pFormat[0]);
2288 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2289 }
2290
2291 /* allow compiler to optimise inline function by passing constant into
2292 * these functions */
2293 if (pFormat[0] == RPC_FC_C_CSTRING) {
2294 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2295 pFormat);
2296 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2297 TRUE /* fHasPointers */);
2298 } else {
2299 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2300 pFormat);
2301 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2302 TRUE /* fHasPointers */);
2303 }
2304 }
2305
2306 /************************************************************************
2307 * NdrConformantStringMemorySize [RPCRT4.@]
2308 */
2309 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2310 PFORMAT_STRING pFormat )
2311 {
2312 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2313
2314 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2315 ERR("Unhandled string type: %#x\n", pFormat[0]);
2316 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2317 }
2318
2319 /* allow compiler to optimise inline function by passing constant into
2320 * these functions */
2321 if (pFormat[0] == RPC_FC_C_CSTRING) {
2322 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2323 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2324 TRUE /* fHasPointers */);
2325 } else {
2326 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2327 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2328 TRUE /* fHasPointers */);
2329 }
2330
2331 return pStubMsg->MemorySize;
2332 }
2333
2334 /************************************************************************
2335 * NdrConformantStringUnmarshall [RPCRT4.@]
2336 */
2337 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2338 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2339 {
2340 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2341 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2342
2343 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2344 ERR("Unhandled string type: %#x\n", *pFormat);
2345 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2346 }
2347
2348 /* allow compiler to optimise inline function by passing constant into
2349 * these functions */
2350 if (pFormat[0] == RPC_FC_C_CSTRING) {
2351 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2352 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2353 pFormat, fMustAlloc,
2354 TRUE /* fUseBufferMemoryServer */,
2355 TRUE /* fUnmarshall */);
2356 } else {
2357 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2358 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2359 pFormat, fMustAlloc,
2360 TRUE /* fUseBufferMemoryServer */,
2361 TRUE /* fUnmarshall */);
2362 }
2363
2364 return NULL;
2365 }
2366
2367 /***********************************************************************
2368 * NdrNonConformantStringMarshall [RPCRT4.@]
2369 */
2370 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2371 unsigned char *pMemory,
2372 PFORMAT_STRING pFormat)
2373 {
2374 ULONG esize, size, maxsize;
2375
2376 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2377
2378 maxsize = *(USHORT *)&pFormat[2];
2379
2380 if (*pFormat == RPC_FC_CSTRING)
2381 {
2382 ULONG i;
2383 const char *str = (const char *)pMemory;
2384 for (i = 0; i < maxsize && *str; i++, str++)
2385 ;
2386 TRACE("string=%s\n", debugstr_an(str, i));
2387 pStubMsg->ActualCount = i + 1;
2388 esize = 1;
2389 }
2390 else if (*pFormat == RPC_FC_WSTRING)
2391 {
2392 ULONG i;
2393 const WCHAR *str = (const WCHAR *)pMemory;
2394 for (i = 0; i < maxsize && *str; i++, str++)
2395 ;
2396 TRACE("string=%s\n", debugstr_wn(str, i));
2397 pStubMsg->ActualCount = i + 1;
2398 esize = 2;
2399 }
2400 else
2401 {
2402 ERR("Unhandled string type: %#x\n", *pFormat);
2403 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2404 }
2405
2406 pStubMsg->Offset = 0;
2407 WriteVariance(pStubMsg);
2408
2409 size = safe_multiply(esize, pStubMsg->ActualCount);
2410 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2411
2412 return NULL;
2413 }
2414
2415 /***********************************************************************
2416 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2417 */
2418 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2419 unsigned char **ppMemory,
2420 PFORMAT_STRING pFormat,
2421 unsigned char fMustAlloc)
2422 {
2423 ULONG bufsize, memsize, esize, maxsize;
2424
2425 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2426 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2427
2428 maxsize = *(USHORT *)&pFormat[2];
2429
2430 ReadVariance(pStubMsg, NULL, maxsize);
2431 if (pStubMsg->Offset)
2432 {
2433 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2434 RpcRaiseException(RPC_S_INVALID_BOUND);
2435 }
2436
2437 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2438 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2439 else
2440 {
2441 ERR("Unhandled string type: %#x\n", *pFormat);
2442 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2443 }
2444
2445 memsize = esize * maxsize;
2446 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2447
2448 validate_string_data(pStubMsg, bufsize, esize);
2449
2450 if (!fMustAlloc && !*ppMemory)
2451 fMustAlloc = TRUE;
2452 if (fMustAlloc)
2453 *ppMemory = NdrAllocate(pStubMsg, memsize);
2454
2455 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2456
2457 if (*pFormat == RPC_FC_CSTRING) {
2458 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2459 }
2460 else if (*pFormat == RPC_FC_WSTRING) {
2461 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2462 }
2463
2464 return NULL;
2465 }
2466
2467 /***********************************************************************
2468 * NdrNonConformantStringBufferSize [RPCRT4.@]
2469 */
2470 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2471 unsigned char *pMemory,
2472 PFORMAT_STRING pFormat)
2473 {
2474 ULONG esize, maxsize;
2475
2476 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2477
2478 maxsize = *(USHORT *)&pFormat[2];
2479
2480 SizeVariance(pStubMsg);
2481
2482 if (*pFormat == RPC_FC_CSTRING)
2483 {
2484 ULONG i;
2485 const char *str = (const char *)pMemory;
2486 for (i = 0; i < maxsize && *str; i++, str++)
2487 ;
2488 TRACE("string=%s\n", debugstr_an(str, i));
2489 pStubMsg->ActualCount = i + 1;
2490 esize = 1;
2491 }
2492 else if (*pFormat == RPC_FC_WSTRING)
2493 {
2494 ULONG i;
2495 const WCHAR *str = (const WCHAR *)pMemory;
2496 for (i = 0; i < maxsize && *str; i++, str++)
2497 ;
2498 TRACE("string=%s\n", debugstr_wn(str, i));
2499 pStubMsg->ActualCount = i + 1;
2500 esize = 2;
2501 }
2502 else
2503 {
2504 ERR("Unhandled string type: %#x\n", *pFormat);
2505 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2506 }
2507
2508 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2509 }
2510
2511 /***********************************************************************
2512 * NdrNonConformantStringMemorySize [RPCRT4.@]
2513 */
2514 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2515 PFORMAT_STRING pFormat)
2516 {
2517 ULONG bufsize, memsize, esize, maxsize;
2518
2519 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2520
2521 maxsize = *(USHORT *)&pFormat[2];
2522
2523 ReadVariance(pStubMsg, NULL, maxsize);
2524
2525 if (pStubMsg->Offset)
2526 {
2527 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2528 RpcRaiseException(RPC_S_INVALID_BOUND);
2529 }
2530
2531 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2532 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2533 else
2534 {
2535 ERR("Unhandled string type: %#x\n", *pFormat);
2536 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2537 }
2538
2539 memsize = esize * maxsize;
2540 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2541
2542 validate_string_data(pStubMsg, bufsize, esize);
2543
2544 safe_buffer_increment(pStubMsg, bufsize);
2545 pStubMsg->MemorySize += memsize;
2546
2547 return pStubMsg->MemorySize;
2548 }
2549
2550 /* Complex types */
2551
2552 #include "pshpack1.h"
2553 typedef struct
2554 {
2555 unsigned char type;
2556 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2557 ULONG low_value;
2558 ULONG high_value;
2559 } NDR_RANGE;
2560 #include "poppack.h"
2561
2562 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2563 PFORMAT_STRING pFormat)
2564 {
2565 switch (*pFormat) {
2566 case RPC_FC_STRUCT:
2567 case RPC_FC_PSTRUCT:
2568 case RPC_FC_CSTRUCT:
2569 case RPC_FC_BOGUS_STRUCT:
2570 case RPC_FC_SMFARRAY:
2571 case RPC_FC_SMVARRAY:
2572 case RPC_FC_CSTRING:
2573 return *(const WORD*)&pFormat[2];
2574 case RPC_FC_USER_MARSHAL:
2575 return *(const WORD*)&pFormat[4];
2576 case RPC_FC_RANGE: {
2577 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2578 case RPC_FC_BYTE:
2579 case RPC_FC_CHAR:
2580 case RPC_FC_SMALL:
2581 case RPC_FC_USMALL:
2582 return sizeof(UCHAR);
2583 case RPC_FC_WCHAR:
2584 case RPC_FC_SHORT:
2585 case RPC_FC_USHORT:
2586 return sizeof(USHORT);
2587 case RPC_FC_LONG:
2588 case RPC_FC_ULONG:
2589 case RPC_FC_ENUM32:
2590 return sizeof(ULONG);
2591 case RPC_FC_FLOAT:
2592 return sizeof(float);
2593 case RPC_FC_DOUBLE:
2594 return sizeof(double);
2595 case RPC_FC_HYPER:
2596 return sizeof(ULONGLONG);
2597 case RPC_FC_ENUM16:
2598 return sizeof(UINT);
2599 default:
2600 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2601 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2602 }
2603 }
2604 case RPC_FC_NON_ENCAPSULATED_UNION:
2605 pFormat += 2;
2606 if (pStubMsg->fHasNewCorrDesc)
2607 pFormat += 6;
2608 else
2609 pFormat += 4;
2610
2611 pFormat += *(const SHORT*)pFormat;
2612 return *(const SHORT*)pFormat;
2613 case RPC_FC_IP:
2614 return sizeof(void *);
2615 case RPC_FC_WSTRING:
2616 return *(const WORD*)&pFormat[2] * 2;
2617 default:
2618 FIXME("unhandled embedded type %02x\n", *pFormat);
2619 }
2620 return 0;
2621 }
2622
2623
2624 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2625 PFORMAT_STRING pFormat)
2626 {
2627 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2628
2629 if (!m)
2630 {
2631 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2632 return 0;
2633 }
2634
2635 return m(pStubMsg, pFormat);
2636 }
2637
2638
2639 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2640 unsigned char *pMemory,
2641 PFORMAT_STRING pFormat,
2642 PFORMAT_STRING pPointer)
2643 {
2644 PFORMAT_STRING desc;
2645 NDR_MARSHALL m;
2646 unsigned long size;
2647
2648 while (*pFormat != RPC_FC_END) {
2649 switch (*pFormat) {
2650 case RPC_FC_BYTE:
2651 case RPC_FC_CHAR:
2652 case RPC_FC_SMALL:
2653 case RPC_FC_USMALL:
2654 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2655 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2656 pMemory += 1;
2657 break;
2658 case RPC_FC_WCHAR:
2659 case RPC_FC_SHORT:
2660 case RPC_FC_USHORT:
2661 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2662 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2663 pMemory += 2;
2664 break;
2665 case RPC_FC_ENUM16:
2666 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2667 if (32767 < *(DWORD*)pMemory)
2668 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2669 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2670 pMemory += 4;
2671 break;
2672 case RPC_FC_LONG:
2673 case RPC_FC_ULONG:
2674 case RPC_FC_ENUM32:
2675 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2676 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2677 pMemory += 4;
2678 break;
2679 case RPC_FC_HYPER:
2680 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2681 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2682 pMemory += 8;
2683 break;
2684 case RPC_FC_POINTER:
2685 {
2686 unsigned char *saved_buffer;
2687 int pointer_buffer_mark_set = 0;
2688 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2689 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2690 if (*pPointer != RPC_FC_RP)
2691 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2692 saved_buffer = pStubMsg->Buffer;
2693 if (pStubMsg->PointerBufferMark)
2694 {
2695 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2696 pStubMsg->PointerBufferMark = NULL;
2697 pointer_buffer_mark_set = 1;
2698 }
2699 else if (*pPointer != RPC_FC_RP)
2700 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2701 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2702 if (pointer_buffer_mark_set)
2703 {
2704 STD_OVERFLOW_CHECK(pStubMsg);
2705 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2706 pStubMsg->Buffer = saved_buffer;
2707 if (*pPointer != RPC_FC_RP)
2708 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2709 }
2710 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2711 pPointer += 4;
2712 pMemory += 4;
2713 break;
2714 }
2715 case RPC_FC_ALIGNM4:
2716 ALIGN_POINTER(pMemory, 4);
2717 break;
2718 case RPC_FC_ALIGNM8:
2719 ALIGN_POINTER(pMemory, 8);
2720 break;
2721 case RPC_FC_STRUCTPAD1:
2722 case RPC_FC_STRUCTPAD2:
2723 case RPC_FC_STRUCTPAD3:
2724 case RPC_FC_STRUCTPAD4:
2725 case RPC_FC_STRUCTPAD5:
2726 case RPC_FC_STRUCTPAD6:
2727 case RPC_FC_STRUCTPAD7:
2728 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2729 break;
2730 case RPC_FC_EMBEDDED_COMPLEX:
2731 pMemory += pFormat[1];
2732 pFormat += 2;
2733 desc = pFormat + *(const SHORT*)pFormat;
2734 size = EmbeddedComplexSize(pStubMsg, desc);
2735 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2736 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2737 if (m)
2738 {
2739 /* for some reason interface pointers aren't generated as
2740 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2741 * they still need the derefencing treatment that pointers are
2742 * given */
2743 if (*desc == RPC_FC_IP)
2744 m(pStubMsg, *(unsigned char **)pMemory, desc);
2745 else
2746 m(pStubMsg, pMemory, desc);
2747 }
2748 else FIXME("no marshaller for embedded type %02x\n", *desc);
2749 pMemory += size;
2750 pFormat += 2;
2751 continue;
2752 case RPC_FC_PAD:
2753 break;
2754 default:
2755 FIXME("unhandled format 0x%02x\n", *pFormat);
2756 }
2757 pFormat++;
2758 }
2759
2760 return pMemory;
2761 }
2762
2763 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2764 unsigned char *pMemory,
2765 PFORMAT_STRING pFormat,
2766 PFORMAT_STRING pPointer,
2767 unsigned char fMustAlloc)
2768 {
2769 PFORMAT_STRING desc;
2770 NDR_UNMARSHALL m;
2771 unsigned long size;
2772
2773 while (*pFormat != RPC_FC_END) {
2774 switch (*pFormat) {
2775 case RPC_FC_BYTE:
2776 case RPC_FC_CHAR:
2777 case RPC_FC_SMALL:
2778 case RPC_FC_USMALL:
2779 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2780 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2781 pMemory += 1;
2782 break;
2783 case RPC_FC_WCHAR:
2784 case RPC_FC_SHORT:
2785 case RPC_FC_USHORT:
2786 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2787 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2788 pMemory += 2;
2789 break;
2790 case RPC_FC_ENUM16:
2791 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2792 *(DWORD*)pMemory &= 0xffff;
2793 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2794 if (32767 < *(DWORD*)pMemory)
2795 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2796 pMemory += 4;
2797 break;
2798 case RPC_FC_LONG:
2799 case RPC_FC_ULONG:
2800 case RPC_FC_ENUM32:
2801 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2802 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2803 pMemory += 4;
2804 break;
2805 case RPC_FC_HYPER:
2806 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2807 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2808 pMemory += 8;
2809 break;
2810 case RPC_FC_POINTER:
2811 {
2812 unsigned char *saved_buffer;
2813 int pointer_buffer_mark_set = 0;
2814 TRACE("pointer => %p\n", pMemory);
2815 if (*pPointer != RPC_FC_RP)
2816 ALIGN_POINTER(pStubMsg->Buffer, 4);
2817 saved_buffer = pStubMsg->Buffer;
2818 if (pStubMsg->PointerBufferMark)
2819 {
2820 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2821 pStubMsg->PointerBufferMark = NULL;
2822 pointer_buffer_mark_set = 1;
2823 }
2824 else if (*pPointer != RPC_FC_RP)
2825 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2826
2827 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2828 if (pointer_buffer_mark_set)
2829 {
2830 STD_OVERFLOW_CHECK(pStubMsg);
2831 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2832 pStubMsg->Buffer = saved_buffer;
2833 if (*pPointer != RPC_FC_RP)
2834 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2835 }
2836 pPointer += 4;
2837 pMemory += 4;
2838 break;
2839 }
2840 case RPC_FC_ALIGNM4:
2841 ALIGN_POINTER_CLEAR(pMemory, 4);
2842 break;
2843 case RPC_FC_ALIGNM8:
2844 ALIGN_POINTER_CLEAR(pMemory, 8);
2845 break;
2846 case RPC_FC_STRUCTPAD1:
2847 case RPC_FC_STRUCTPAD2:
2848 case RPC_FC_STRUCTPAD3:
2849 case RPC_FC_STRUCTPAD4:
2850 case RPC_FC_STRUCTPAD5:
2851 case RPC_FC_STRUCTPAD6:
2852 case RPC_FC_STRUCTPAD7:
2853 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2854 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2855 break;
2856 case RPC_FC_EMBEDDED_COMPLEX:
2857 pMemory += pFormat[1];
2858 pFormat += 2;
2859 desc = pFormat + *(const SHORT*)pFormat;
2860 size = EmbeddedComplexSize(pStubMsg, desc);
2861 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2862 if (fMustAlloc)
2863 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2864 * since the type is part of the memory block that is encompassed by
2865 * the whole complex type. Memory is forced to allocate when pointers
2866 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2867 * clearing the memory we pass in to the unmarshaller */
2868 memset(pMemory, 0, size);
2869 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2870 if (m)
2871 {
2872 /* for some reason interface pointers aren't generated as
2873 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2874 * they still need the derefencing treatment that pointers are
2875 * given */
2876 if (*desc == RPC_FC_IP)
2877 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2878 else
2879 m(pStubMsg, &pMemory, desc, FALSE);
2880 }
2881 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2882 pMemory += size;
2883 pFormat += 2;
2884 continue;
2885 case RPC_FC_PAD:
2886 break;
2887 default:
2888 FIXME("unhandled format %d\n", *pFormat);
2889 }
2890 pFormat++;
2891 }
2892
2893 return pMemory;
2894 }
2895
2896 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2897 unsigned char *pMemory,
2898 PFORMAT_STRING pFormat,
2899 PFORMAT_STRING pPointer)
2900 {
2901 PFORMAT_STRING desc;
2902 NDR_BUFFERSIZE m;
2903 unsigned long size;
2904
2905 while (*pFormat != RPC_FC_END) {
2906 switch (*pFormat) {
2907 case RPC_FC_BYTE:
2908 case RPC_FC_CHAR:
2909 case RPC_FC_SMALL:
2910 case RPC_FC_USMALL:
2911 safe_buffer_length_increment(pStubMsg, 1);
2912 pMemory += 1;
2913 break;
2914 case RPC_FC_WCHAR:
2915 case RPC_FC_SHORT:
2916 case RPC_FC_USHORT:
2917 safe_buffer_length_increment(pStubMsg, 2);
2918 pMemory += 2;
2919 break;
2920 case RPC_FC_ENUM16:
2921 safe_buffer_length_increment(pStubMsg, 2);
2922 pMemory += 4;
2923 break;
2924 case RPC_FC_LONG:
2925 case RPC_FC_ULONG:
2926 case RPC_FC_ENUM32:
2927 safe_buffer_length_increment(pStubMsg, 4);
2928 pMemory += 4;
2929 break;
2930 case RPC_FC_HYPER:
2931 safe_buffer_length_increment(pStubMsg, 8);
2932 pMemory += 8;
2933 break;
2934 case RPC_FC_POINTER:
2935 if (!pStubMsg->IgnoreEmbeddedPointers)
2936 {
2937 int saved_buffer_length = pStubMsg->BufferLength;
2938 pStubMsg->BufferLength = pStubMsg->PointerLength;
2939 pStubMsg->PointerLength = 0;
2940 if(!pStubMsg->BufferLength)
2941 ERR("BufferLength == 0??\n");
2942 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2943 pStubMsg->PointerLength = pStubMsg->BufferLength;
2944 pStubMsg->BufferLength = saved_buffer_length;
2945 }
2946 if (*pPointer != RPC_FC_RP)
2947 {
2948 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2949 safe_buffer_length_increment(pStubMsg, 4);
2950 }
2951 pPointer += 4;
2952 pMemory += 4;
2953 break;
2954 case RPC_FC_ALIGNM4:
2955 ALIGN_POINTER(pMemory, 4);
2956 break;
2957 case RPC_FC_ALIGNM8:
2958 ALIGN_POINTER(pMemory, 8);
2959 break;
2960 case RPC_FC_STRUCTPAD1:
2961 case RPC_FC_STRUCTPAD2:
2962 case RPC_FC_STRUCTPAD3:
2963 case RPC_FC_STRUCTPAD4:
2964 case RPC_FC_STRUCTPAD5:
2965 case RPC_FC_STRUCTPAD6:
2966 case RPC_FC_STRUCTPAD7:
2967 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2968 break;
2969 case RPC_FC_EMBEDDED_COMPLEX:
2970 pMemory += pFormat[1];
2971 pFormat += 2;
2972 desc = pFormat + *(const SHORT*)pFormat;
2973 size = EmbeddedComplexSize(pStubMsg, desc);
2974 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2975 if (m)
2976 {
2977 /* for some reason interface pointers aren't generated as
2978 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2979 * they still need the derefencing treatment that pointers are
2980 * given */
2981 if (*desc == RPC_FC_IP)
2982 m(pStubMsg, *(unsigned char **)pMemory, desc);
2983 else
2984 m(pStubMsg, pMemory, desc);
2985 }
2986 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2987 pMemory += size;
2988 pFormat += 2;
2989 continue;
2990 case RPC_FC_PAD:
2991 break;
2992 default:
2993 FIXME("unhandled format 0x%02x\n", *pFormat);
2994 }
2995 pFormat++;
2996 }
2997
2998 return pMemory;
2999 }
3000
3001 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3002 unsigned char *pMemory,
3003 PFORMAT_STRING pFormat,
3004 PFORMAT_STRING pPointer)
3005 {
3006 PFORMAT_STRING desc;
3007 NDR_FREE m;
3008 unsigned long size;
3009
3010 while (*pFormat != RPC_FC_END) {
3011 switch (*pFormat) {
3012 case RPC_FC_BYTE:
3013 case RPC_FC_CHAR:
3014 case RPC_FC_SMALL:
3015 case RPC_FC_USMALL:
3016 pMemory += 1;
3017 break;
3018 case RPC_FC_WCHAR:
3019 case RPC_FC_SHORT:
3020 case RPC_FC_USHORT:
3021 pMemory += 2;
3022 break;
3023 case RPC_FC_LONG:
3024 case RPC_FC_ULONG:
3025 case RPC_FC_ENUM16:
3026 case RPC_FC_ENUM32:
3027 pMemory += 4;
3028 break;
3029 case RPC_FC_HYPER:
3030 pMemory += 8;
3031 break;
3032 case RPC_FC_POINTER:
3033 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3034 pPointer += 4;
3035 pMemory += 4;
3036 break;
3037 case RPC_FC_ALIGNM4:
3038 ALIGN_POINTER(pMemory, 4);
3039 break;
3040 case RPC_FC_ALIGNM8:
3041 ALIGN_POINTER(pMemory, 8);
3042 break;
3043 case RPC_FC_STRUCTPAD1:
3044 case RPC_FC_STRUCTPAD2:
3045 case RPC_FC_STRUCTPAD3:
3046 case RPC_FC_STRUCTPAD4:
3047 case RPC_FC_STRUCTPAD5:
3048 case RPC_FC_STRUCTPAD6:
3049 case RPC_FC_STRUCTPAD7:
3050 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3051 break;
3052 case RPC_FC_EMBEDDED_COMPLEX:
3053 pMemory += pFormat[1];
3054 pFormat += 2;
3055 desc = pFormat + *(const SHORT*)pFormat;
3056 size = EmbeddedComplexSize(pStubMsg, desc);
3057 m = NdrFreer[*desc & NDR_TABLE_MASK];
3058 if (m)
3059 {
3060 /* for some reason interface pointers aren't generated as
3061 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3062 * they still need the derefencing treatment that pointers are
3063 * given */
3064 if (*desc == RPC_FC_IP)
3065 m(pStubMsg, *(unsigned char **)pMemory, desc);
3066 else
3067 m(pStubMsg, pMemory, desc);
3068 }
3069 pMemory += size;
3070 pFormat += 2;
3071 continue;
3072 case RPC_FC_PAD:
3073 break;
3074 default:
3075 FIXME("unhandled format 0x%02x\n", *pFormat);
3076 }
3077 pFormat++;
3078 }
3079
3080 return pMemory;
3081 }
3082
3083 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3084 PFORMAT_STRING pFormat,
3085 PFORMAT_STRING pPointer)
3086 {
3087 PFORMAT_STRING desc;
3088 unsigned long size = 0;
3089
3090 while (*pFormat != RPC_FC_END) {
3091 switch (*pFormat) {
3092 case RPC_FC_BYTE:
3093 case RPC_FC_CHAR:
3094 case RPC_FC_SMALL:
3095 case RPC_FC_USMALL:
3096 size += 1;
3097 safe_buffer_increment(pStubMsg, 1);
3098 break;
3099 case RPC_FC_WCHAR:
3100 case RPC_FC_SHORT:
3101 case RPC_FC_USHORT:
3102 size += 2;
3103 safe_buffer_increment(pStubMsg, 2);
3104 break;
3105 case RPC_FC_ENUM16:
3106 size += 4;
3107 safe_buffer_increment(pStubMsg, 2);
3108 break;
3109 case RPC_FC_LONG:
3110 case RPC_FC_ULONG:
3111 case RPC_FC_ENUM32:
3112 size += 4;
3113 safe_buffer_increment(pStubMsg, 4);
3114 break;
3115 case RPC_FC_HYPER:
3116 size += 8;
3117 safe_buffer_increment(pStubMsg, 8);
3118 break;
3119 case RPC_FC_POINTER:
3120 {
3121 unsigned char *saved_buffer;
3122 int pointer_buffer_mark_set = 0;
3123 if (*pPointer != RPC_FC_RP)
3124 ALIGN_POINTER(pStubMsg->Buffer, 4);
3125 saved_buffer = pStubMsg->Buffer;
3126 if (pStubMsg->PointerBufferMark)
3127 {
3128 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3129 pStubMsg->PointerBufferMark = NULL;
3130 pointer_buffer_mark_set = 1;
3131 }
3132 else if (*pPointer != RPC_FC_RP)
3133 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3134
3135 if (!pStubMsg->IgnoreEmbeddedPointers)
3136 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3137 if (pointer_buffer_mark_set)
3138 {
3139 STD_OVERFLOW_CHECK(pStubMsg);
3140 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3141 pStubMsg->Buffer = saved_buffer;
3142 if (*pPointer != RPC_FC_RP)
3143 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3144 }
3145 pPointer += 4;
3146 size += 4;
3147 break;
3148 }
3149 case RPC_FC_ALIGNM4:
3150 ALIGN_LENGTH(size, 4);
3151 break;
3152 case RPC_FC_ALIGNM8:
3153 ALIGN_LENGTH(size, 8);
3154 break;
3155 case RPC_FC_STRUCTPAD1:
3156 case RPC_FC_STRUCTPAD2:
3157 case RPC_FC_STRUCTPAD3:
3158 case RPC_FC_STRUCTPAD4:
3159 case RPC_FC_STRUCTPAD5:
3160 case RPC_FC_STRUCTPAD6:
3161 case RPC_FC_STRUCTPAD7:
3162 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3163 break;
3164 case RPC_FC_EMBEDDED_COMPLEX:
3165 size += pFormat[1];
3166 pFormat += 2;
3167 desc = pFormat + *(const SHORT*)pFormat;
3168 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3169 pFormat += 2;
3170 continue;
3171 case RPC_FC_PAD:
3172 break;
3173 default:
3174 FIXME("unhandled format 0x%02x\n", *pFormat);
3175 }
3176 pFormat++;
3177 }
3178
3179 return size;
3180 }
3181
3182 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
3183 PFORMAT_STRING pFormat)
3184 {
3185 PFORMAT_STRING desc;
3186 unsigned long size = 0;
3187
3188 while (*pFormat != RPC_FC_END) {
3189 switch (*pFormat) {
3190 case RPC_FC_BYTE:
3191 case RPC_FC_CHAR:
3192 case RPC_FC_SMALL:
3193 case RPC_FC_USMALL:
3194 size += 1;
3195 break;
3196 case RPC_FC_WCHAR:
3197 case RPC_FC_SHORT:
3198 case RPC_FC_USHORT:
3199 size += 2;
3200 break;
3201 case RPC_FC_LONG:
3202 case RPC_FC_ULONG:
3203 case RPC_FC_ENUM16:
3204 case RPC_FC_ENUM32:
3205 size += 4;
3206 break;
3207 case RPC_FC_HYPER:
3208 size += 8;
3209 break;
3210 case RPC_FC_POINTER:
3211 size += sizeof(void *);
3212 break;
3213 case RPC_FC_ALIGNM4:
3214 ALIGN_LENGTH(size, 4);
3215 break;
3216 case RPC_FC_ALIGNM8:
3217 ALIGN_LENGTH(size, 8);
3218 break;
3219 case RPC_FC_STRUCTPAD1:
3220 case RPC_FC_STRUCTPAD2:
3221 case RPC_FC_STRUCTPAD3:
3222 case RPC_FC_STRUCTPAD4:
3223 case RPC_FC_STRUCTPAD5:
3224 case RPC_FC_STRUCTPAD6:
3225 case RPC_FC_STRUCTPAD7:
3226 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3227 break;
3228 case RPC_FC_EMBEDDED_COMPLEX:
3229 size += pFormat[1];
3230 pFormat += 2;
3231 desc = pFormat + *(const SHORT*)pFormat;
3232 size += EmbeddedComplexSize(pStubMsg, desc);
3233 pFormat += 2;
3234 continue;
3235 case RPC_FC_PAD:
3236 break;
3237 default:
3238 FIXME("unhandled format 0x%02x\n", *pFormat);
3239 }
3240 pFormat++;
3241 }
3242
3243 return size;
3244 }
3245
3246 /***********************************************************************
3247 * NdrComplexStructMarshall [RPCRT4.@]
3248 */
3249 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3250 unsigned char *pMemory,
3251 PFORMAT_STRING pFormat)
3252 {
3253 PFORMAT_STRING conf_array = NULL;
3254 PFORMAT_STRING pointer_desc = NULL;
3255 unsigned char *OldMemory = pStubMsg->Memory;
3256 int pointer_buffer_mark_set = 0;
3257 ULONG count = 0;
3258 ULONG max_count = 0;
3259 ULONG offset = 0;
3260
3261 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3262
3263 if (!pStubMsg->PointerBufferMark)
3264 {
3265 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3266 /* save buffer length */
3267 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3268
3269 /* get the buffer pointer after complex array data, but before
3270 * pointer data */
3271 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3272 pStubMsg->IgnoreEmbeddedPointers = 1;
3273 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3274 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3275
3276 /* save it for use by embedded pointer code later */
3277 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3278 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
3279 pointer_buffer_mark_set = 1;
3280
3281 /* restore the original buffer length */
3282 pStubMsg->BufferLength = saved_buffer_length;
3283 }
3284
3285 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3286
3287 pFormat += 4;
3288 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3289 pFormat += 2;
3290 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3291 pFormat += 2;
3292
3293 pStubMsg->Memory = pMemory;
3294
3295 if (conf_array)
3296 {
3297 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3298 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3299 pMemory + struct_size, conf_array);
3300 /* these could be changed in ComplexMarshall so save them for later */
3301 max_count = pStubMsg->MaxCount;
3302 count = pStubMsg->ActualCount;
3303 offset = pStubMsg->Offset;
3304 }
3305
3306 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3307
3308 if (conf_array)
3309 {
3310 pStubMsg->MaxCount = max_count;
3311 pStubMsg->ActualCount = count;
3312 pStubMsg->Offset = offset;
3313 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3314 conf_array, TRUE /* fHasPointers */);
3315 }
3316
3317 pStubMsg->Memory = OldMemory;
3318
3319 if (pointer_buffer_mark_set)
3320 {
3321 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3322 pStubMsg->PointerBufferMark = NULL;
3323 }
3324
3325 STD_OVERFLOW_CHECK(pStubMsg);
3326
3327 return NULL;
3328 }
3329
3330 /***********************************************************************
3331 * NdrComplexStructUnmarshall [RPCRT4.@]
3332 */
3333 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3334 unsigned char **ppMemory,
3335 PFORMAT_STRING pFormat,
3336 unsigned char fMustAlloc)
3337 {
3338 unsigned size = *(const WORD*)(pFormat+2);
3339 PFORMAT_STRING conf_array = NULL;
3340 PFORMAT_STRING pointer_desc = NULL;
3341 unsigned char *pMemory;
3342 int pointer_buffer_mark_set = 0;
3343 ULONG count = 0;
3344 ULONG max_count = 0;
3345 ULONG offset = 0;
3346 ULONG array_size = 0;
3347
3348 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3349
3350 if (!pStubMsg->PointerBufferMark)
3351 {
3352 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3353 /* save buffer pointer */
3354 unsigned char *saved_buffer = pStubMsg->Buffer;
3355
3356 /* get the buffer pointer after complex array data, but before
3357 * pointer data */
3358 pStubMsg->IgnoreEmbeddedPointers = 1;
3359 NdrComplexStructMemorySize(pStubMsg, pFormat);
3360 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3361
3362 /* save it for use by embedded pointer code later */
3363 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3364 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
3365 pointer_buffer_mark_set = 1;
3366
3367 /* restore the original buffer */
3368 pStubMsg->Buffer = saved_buffer;
3369 }
3370
3371 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3372
3373 pFormat += 4;
3374 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3375 pFormat += 2;
3376 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3377 pFormat += 2;
3378
3379 if (conf_array)
3380 {
3381 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3382 size += array_size;
3383
3384 /* these could be changed in ComplexMarshall so save them for later */
3385 max_count = pStubMsg->MaxCount;
3386 count = pStubMsg->ActualCount;
3387 offset = pStubMsg->Offset;
3388 }
3389
3390 if (!fMustAlloc && !*ppMemory)
3391 fMustAlloc = TRUE;
3392 if (fMustAlloc)
3393 *ppMemory = NdrAllocate(pStubMsg, size);
3394
3395 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3396
3397 if (conf_array)
3398 {
3399 pStubMsg->MaxCount = max_count;
3400 pStubMsg->ActualCount = count;
3401 pStubMsg->Offset = offset;
3402 if (fMustAlloc)
3403 memset(pMemory, 0, array_size);
3404 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3405 conf_array, FALSE,
3406 FALSE /* fUseBufferMemoryServer */,
3407 TRUE /* fUnmarshall */);
3408 }
3409
3410 if (pointer_buffer_mark_set)
3411 {
3412 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3413 pStubMsg->PointerBufferMark = NULL;
3414 }
3415
3416 return NULL;
3417 }
3418
3419 /***********************************************************************
3420 * NdrComplexStructBufferSize [RPCRT4.@]
3421 */
3422 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3423 unsigned char *pMemory,
3424 PFORMAT_STRING pFormat)
3425 {
3426 PFORMAT_STRING conf_array = NULL;
3427 PFORMAT_STRING pointer_desc = NULL;
3428 unsigned char *OldMemory = pStubMsg->Memory;
3429 int pointer_length_set = 0;
3430 ULONG count = 0;
3431 ULONG max_count = 0;
3432 ULONG offset = 0;
3433
3434 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3435
3436 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3437
3438 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3439 {
3440 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3441 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3442
3443 /* get the buffer length after complex struct data, but before
3444 * pointer data */
3445 pStubMsg->IgnoreEmbeddedPointers = 1;
3446 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3447 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3448
3449 /* save it for use by embedded pointer code later */
3450 pStubMsg->PointerLength = pStubMsg->BufferLength;
3451 pointer_length_set = 1;
3452 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
3453
3454 /* restore the original buffer length */
3455 pStubMsg->BufferLength = saved_buffer_length;
3456 }
3457
3458 pFormat += 4;
3459 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3460 pFormat += 2;
3461 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3462 pFormat += 2;
3463
3464 pStubMsg->Memory = pMemory;
3465
3466 if (conf_array)
3467 {
3468 unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat);
3469 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3470 conf_array);
3471
3472 /* these could be changed in ComplexMarshall so save them for later */
3473 max_count = pStubMsg->MaxCount;
3474 count = pStubMsg->ActualCount;
3475 offset = pStubMsg->Offset;
3476 }
3477
3478 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3479
3480 if (conf_array)
3481 {
3482 pStubMsg->MaxCount = max_count;
3483 pStubMsg->ActualCount = count;
3484 pStubMsg->Offset = offset;
3485 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3486 TRUE /* fHasPointers */);
3487 }
3488
3489 pStubMsg->Memory = OldMemory;
3490
3491 if(pointer_length_set)
3492 {
3493 pStubMsg->BufferLength = pStubMsg->PointerLength;
3494 pStubMsg->PointerLength = 0;
3495 }
3496
3497 }
3498
3499 /***********************************************************************
3500 * NdrComplexStructMemorySize [RPCRT4.@]
3501 */
3502 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3503 PFORMAT_STRING pFormat)
3504 {
3505 unsigned size = *(const WORD*)(pFormat+2);
3506 PFORMAT_STRING conf_array = NULL;
3507 PFORMAT_STRING pointer_desc = NULL;
3508 ULONG count = 0;
3509 ULONG max_count = 0;
3510 ULONG offset = 0;
3511
3512 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3513
3514 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3515
3516 pFormat += 4;
3517 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3518 pFormat += 2;
3519 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3520 pFormat += 2;
3521
3522 if (conf_array)
3523 {
3524 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3525
3526 /* these could be changed in ComplexStructMemorySize so save them for
3527 * later */
3528 max_count = pStubMsg->MaxCount;
3529 count = pStubMsg->ActualCount;
3530 offset = pStubMsg->Offset;
3531 }
3532
3533 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3534
3535 if (conf_array)
3536 {
3537 pStubMsg->MaxCount = max_count;
3538 pStubMsg->ActualCount = count;
3539 pStubMsg->Offset = offset;
3540 array_memory_size(conf_array[0], pStubMsg, conf_array,
3541 TRUE /* fHasPointers */);
3542 }
3543
3544 return size;
3545 }
3546
3547 /***********************************************************************
3548 * NdrComplexStructFree [RPCRT4.@]
3549 */
3550 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3551 unsigned char *pMemory,
3552 PFORMAT_STRING pFormat)
3553 {
3554 PFORMAT_STRING conf_array = NULL;
3555 PFORMAT_STRING pointer_desc = NULL;
3556 unsigned char *OldMemory = pStubMsg->Memory;
3557
3558 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3559
3560 pFormat += 4;
3561 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3562 pFormat += 2;
3563 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3564 pFormat += 2;
3565
3566 pStubMsg->Memory = pMemory;
3567
3568 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3569
3570 if (conf_array)
3571 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3572 TRUE /* fHasPointers */);
3573
3574 pStubMsg->Memory = OldMemory;
3575 }
3576
3577 /***********************************************************************
3578 * NdrConformantArrayMarshall [RPCRT4.@]
3579 */
3580 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3581 unsigned char *pMemory,
3582 PFORMAT_STRING pFormat)
3583 {
3584 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3585 if (pFormat[0] != RPC_FC_CARRAY)
3586 {
3587 ERR("invalid format = 0x%x\n", pFormat[0]);
3588 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3589 }
3590
3591 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3592 pFormat);
3593 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3594 TRUE /* fHasPointers */);
3595
3596 return NULL;
3597 }
3598
3599 /***********************************************************************
3600 * NdrConformantArrayUnmarshall [RPCRT4.@]
3601 */
3602 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3603 unsigned char **ppMemory,
3604 PFORMAT_STRING pFormat,
3605 unsigned char fMustAlloc)
3606 {
3607 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3608 if (pFormat[0] != RPC_FC_CARRAY)
3609 {
3610 ERR("invalid format = 0x%x\n", pFormat[0]);
3611 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3612 }
3613
3614 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3615 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3616 fMustAlloc,
3617 TRUE /* fUseBufferMemoryServer */,
3618 TRUE /* fUnmarshall */);
3619
3620 return NULL;
3621 }
3622
3623 /***********************************************************************
3624 * NdrConformantArrayBufferSize [RPCRT4.@]
3625 */
3626 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3627 unsigned char *pMemory,
3628 PFORMAT_STRING pFormat)
3629 {
3630 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3631 if (pFormat[0] != RPC_FC_CARRAY)
3632 {
3633 ERR("invalid format = 0x%x\n", pFormat[0]);
3634 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3635 }
3636
3637 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3638 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3639 TRUE /* fHasPointers */);
3640 }
3641
3642 /***********************************************************************
3643 * NdrConformantArrayMemorySize [RPCRT4.@]
3644 */
3645 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3646 PFORMAT_STRING pFormat)
3647 {
3648 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3649 if (pFormat[0] != RPC_FC_CARRAY)
3650 {
3651 ERR("invalid format = 0x%x\n", pFormat[0]);
3652 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3653 }
3654
3655 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3656 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3657
3658 return pStubMsg->MemorySize;
3659 }
3660
3661 /***********************************************************************
3662 * NdrConformantArrayFree [RPCRT4.@]
3663 */
3664 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3665 unsigned char *pMemory,
3666 PFORMAT_STRING pFormat)
3667 {
3668 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3669 if (pFormat[0] != RPC_FC_CARRAY)
3670 {
3671 ERR("invalid format = 0x%x\n", pFormat[0]);
3672 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3673 }
3674
3675 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3676 TRUE /* fHasPointers */);
3677 }
3678
3679
3680 /***********************************************************************
3681 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3682 */
3683 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3684 unsigned char* pMemory,
3685 PFORMAT_STRING pFormat )
3686 {
3687 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3688
3689 if (pFormat[0] != RPC_FC_CVARRAY)
3690 {
3691 ERR("invalid format type %x\n", pFormat[0]);
3692 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3693 return NULL;
3694 }
3695
3696 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3697 pFormat);
3698 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3699 pFormat, TRUE /* fHasPointers */);
3700
3701 return NULL;
3702 }
3703
3704
3705 /***********************************************************************
3706 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3707 */
3708 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3709 unsigned char** ppMemory,
3710 PFORMAT_STRING pFormat,
3711 unsigned char fMustAlloc )
3712 {
3713 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3714
3715 if (pFormat[0] != RPC_FC_CVARRAY)
3716 {
3717 ERR("invalid format type %x\n", pFormat[0]);
3718 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3719 return NULL;
3720 }
3721
3722 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3723 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3724 pFormat, fMustAlloc,
3725 TRUE /* fUseBufferMemoryServer */,
3726 TRUE /* fUnmarshall */);
3727
3728 return NULL;
3729 }
3730
3731
3732 /***********************************************************************
3733 * NdrConformantVaryingArrayFree [RPCRT4.@]
3734 */
3735 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3736 unsigned char* pMemory,
3737 PFORMAT_STRING pFormat )
3738 {
3739 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3740
3741 if (pFormat[0] != RPC_FC_CVARRAY)
3742 {
3743 ERR("invalid format type %x\n", pFormat[0]);
3744 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3745 return;
3746 }
3747
3748 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3749 TRUE /* fHasPointers */);
3750 }
3751
3752
3753 /***********************************************************************
3754 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3755 */
3756 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3757 unsigned char* pMemory, PFORMAT_STRING pFormat )
3758 {
3759 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3760
3761 if (pFormat[0] != RPC_FC_CVARRAY)
3762 {
3763 ERR("invalid format type %x\n", pFormat[0]);
3764 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3765 return;
3766 }
3767
3768 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3769 pFormat);
3770 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3771 TRUE /* fHasPointers */);
3772 }
3773
3774
3775 /***********************************************************************
3776 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3777 */
3778 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3779 PFORMAT_STRING pFormat )
3780 {
3781 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3782
3783 if (pFormat[0] != RPC_FC_CVARRAY)
3784 {
3785 ERR("invalid format type %x\n", pFormat[0]);
3786 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3787 return pStubMsg->MemorySize;
3788 }
3789
3790 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3791 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3792 TRUE /* fHasPointers */);
3793
3794 return pStubMsg->MemorySize;
3795 }
3796
3797
3798 /***********************************************************************
3799 * NdrComplexArrayMarshall [RPCRT4.@]
3800 */
3801 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3802 unsigned char *pMemory,
3803 PFORMAT_STRING pFormat)
3804 {
3805 ULONG i, count, def;
3806 BOOL variance_present;
3807 unsigned char alignment;
3808 int pointer_buffer_mark_set = 0;
3809
3810 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3811
3812 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3813 {
3814 ERR("invalid format type %x\n", pFormat[0]);
3815 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3816 return NULL;
3817 }
3818
3819 alignment = pFormat[1] + 1;
3820
3821 if (!pStubMsg->PointerBufferMark)
3822 {
3823 /* save buffer fields that may be changed by buffer sizer functions
3824 * and that may be needed later on */
3825 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3826 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3827 unsigned long saved_max_count = pStubMsg->MaxCount;
3828 unsigned long saved_offset = pStubMsg->Offset;
3829 unsigned long saved_actual_count = pStubMsg->ActualCount;
3830
3831 /* get the buffer pointer after complex array data, but before
3832 * pointer data */
3833 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3834 pStubMsg->IgnoreEmbeddedPointers = 1;
3835 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3836 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3837
3838 /* save it for use by embedded pointer code later */
3839 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3840 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3841 pointer_buffer_mark_set = 1;
3842
3843 /* restore fields */
3844 pStubMsg->ActualCount = saved_actual_count;
3845 pStubMsg->Offset = saved_offset;
3846 pStubMsg->MaxCount = saved_max_count;
3847 pStubMsg->BufferLength = saved_buffer_length;
3848 }
3849
3850 def = *(const WORD*)&pFormat[2];
3851 pFormat += 4;
3852
3853 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3854 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3855
3856 variance_present = IsConformanceOrVariancePresent(pFormat);
3857 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3858 TRACE("variance = %d\n", pStubMsg->ActualCount);
3859
3860 WriteConformance(pStubMsg);
3861 if (variance_present)
3862 WriteVariance(pStubMsg);
3863
3864 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3865
3866 count = pStubMsg->ActualCount;
3867 for (i = 0; i < count; i++)
3868 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3869
3870 STD_OVERFLOW_CHECK(pStubMsg);
3871
3872 if (pointer_buffer_mark_set)
3873 {
3874 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3875 pStubMsg->PointerBufferMark = NULL;
3876 }
3877
3878 return NULL;
3879 }
3880
3881 /***********************************************************************
3882 * NdrComplexArrayUnmarshall [RPCRT4.@]
3883 */
3884 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3885 unsigned char **ppMemory,
3886 PFORMAT_STRING pFormat,
3887 unsigned char fMustAlloc)
3888 {
3889 ULONG i, count, size;
3890 unsigned char alignment;
3891 unsigned char *pMemory;
3892 unsigned char *saved_buffer;
3893 int pointer_buffer_mark_set = 0;
3894 int saved_ignore_embedded;
3895
3896 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3897
3898 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3899 {
3900 ERR("invalid format type %x\n", pFormat[0]);
3901 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3902 return NULL;
3903 }
3904
3905 alignment = pFormat[1] + 1;
3906
3907 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3908 /* save buffer pointer */
3909 saved_buffer = pStubMsg->Buffer;
3910 /* get the buffer pointer after complex array data, but before
3911 * pointer data */
3912 pStubMsg->IgnoreEmbeddedPointers = 1;
3913 pStubMsg->MemorySize = 0;
3914 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3915 size = pStubMsg->MemorySize;
3916 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3917
3918 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3919 if (!pStubMsg->PointerBufferMark)
3920 {
3921 /* save it for use by embedded pointer code later */
3922 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3923 pointer_buffer_mark_set = 1;
3924 }
3925 /* restore the original buffer */
3926 pStubMsg->Buffer = saved_buffer;
3927
3928 pFormat += 4;
3929
3930 pFormat = ReadConformance(pStubMsg, pFormat);
3931 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3932
3933 if (!fMustAlloc && !*ppMemory)
3934 fMustAlloc = TRUE;
3935 if (fMustAlloc)
3936 *ppMemory = NdrAllocate(pStubMsg, size);
3937
3938 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3939
3940 pMemory = *ppMemory;
3941 count = pStubMsg->ActualCount;
3942 for (i = 0; i < count; i++)
3943 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3944
3945 if (pointer_buffer_mark_set)
3946 {
3947 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3948 pStubMsg->PointerBufferMark = NULL;
3949 }
3950
3951 return NULL;
3952 }
3953
3954 /***********************************************************************
3955 * NdrComplexArrayBufferSize [RPCRT4.@]
3956 */
3957 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3958 unsigned char *pMemory,
3959 PFORMAT_STRING pFormat)
3960 {
3961 ULONG i, count, def;
3962 unsigned char alignment;
3963 BOOL variance_present;
3964 int pointer_length_set = 0;
3965
3966 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3967
3968 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3969 {
3970 ERR("invalid format type %x\n", pFormat[0]);
3971 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3972 return;
3973 }
3974
3975 alignment = pFormat[1] + 1;
3976
3977 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3978 {
3979 /* save buffer fields that may be changed by buffer sizer functions
3980 * and that may be needed later on */
3981 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3982 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3983 unsigned long saved_max_count = pStubMsg->MaxCount;
3984 unsigned long saved_offset = pStubMsg->Offset;
3985 unsigned long saved_actual_count = pStubMsg->ActualCount;
3986
3987 /* get the buffer pointer after complex array data, but before
3988 * pointer data */
3989 pStubMsg->IgnoreEmbeddedPointers = 1;
3990 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3991 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3992
3993 /* save it for use by embedded pointer code later */
3994 pStubMsg->PointerLength = pStubMsg->BufferLength;
3995 pointer_length_set = 1;
3996
3997 /* restore fields */
3998 pStubMsg->ActualCount = saved_actual_count;
3999 pStubMsg->Offset = saved_offset;
4000 pStubMsg->MaxCount = saved_max_count;
4001 pStubMsg->BufferLength = saved_buffer_length;
4002 }
4003 def = *(const WORD*)&pFormat[2];
4004 pFormat += 4;
4005
4006 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4007 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4008 SizeConformance(pStubMsg);
4009
4010 variance_present = IsConformanceOrVariancePresent(pFormat);
4011 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4012 TRACE("variance = %d\n", pStubMsg->ActualCount);
4013
4014 if (variance_present)
4015 SizeVariance(pStubMsg);
4016
4017 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4018
4019 count = pStubMsg->ActualCount;
4020 for (i = 0; i < count; i++)
4021 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4022
4023 if(pointer_length_set)
4024 {
4025 pStubMsg->BufferLength = pStubMsg->PointerLength;
4026 pStubMsg->PointerLength = 0;
4027 }
4028 }
4029
4030 /***********************************************************************
4031 * NdrComplexArrayMemorySize [RPCRT4.@]
4032 */
4033 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4034 PFORMAT_STRING pFormat)
4035 {
4036 ULONG i, count, esize, SavedMemorySize, MemorySize;
4037 unsigned char alignment;
4038
4039 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4040
4041 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4042 {
4043 ERR("invalid format type %x\n", pFormat[0]);
4044 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4045 return 0;
4046 }
4047
4048 alignment = pFormat[1] + 1;
4049
4050 pFormat += 4;
4051
4052 pFormat = ReadConformance(pStubMsg, pFormat);
4053 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4054
4055 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4056
4057 SavedMemorySize = pStubMsg->MemorySize;
4058
4059 esize = ComplexStructSize(pStubMsg, pFormat);
4060
4061 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4062
4063 count = pStubMsg->ActualCount;
4064 for (i = 0; i < count; i++)
4065 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4066
4067 pStubMsg->MemorySize = SavedMemorySize;
4068
4069 pStubMsg->MemorySize += MemorySize;
4070 return MemorySize;
4071 }
4072
4073 /***********************************************************************
4074 * NdrComplexArrayFree [RPCRT4.@]
4075 */
4076 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4077 unsigned char *pMemory,
4078 PFORMAT_STRING pFormat)
4079 {
4080 ULONG i, count, def;
4081
4082 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4083
4084 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4085 {
4086 ERR("invalid format type %x\n", pFormat[0]);
4087 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4088 return;
4089 }
4090
4091 def = *(const WORD*)&pFormat[2];
4092 pFormat += 4;
4093
4094 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4095 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4096
4097 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4098 TRACE("variance = %d\n", pStubMsg->ActualCount);
4099
4100 count = pStubMsg->ActualCount;
4101 for (i = 0; i < count; i++)
4102 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4103 }
4104
4105 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4106 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4107 USER_MARSHAL_CB *umcb)
4108 {
4109 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4110 pStubMsg->RpcMsg->DataRepresentation);
4111 umcb->pStubMsg = pStubMsg;
4112 umcb->pReserve = NULL;
4113 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4114 umcb->CBType = cbtype;
4115 umcb->pFormat = pFormat;
4116 umcb->pTypeFormat = NULL /* FIXME */;
4117 }
4118
4119 #define USER_MARSHAL_PTR_PREFIX \
4120 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4121 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4122
4123 /***********************************************************************
4124 * NdrUserMarshalMarshall [RPCRT4.@]
4125 */
4126 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4127 unsigned char *pMemory,
4128 PFORMAT_STRING pFormat)
4129 {
4130 unsigned flags = pFormat[1];
4131 unsigned index = *(const WORD*)&pFormat[2];
4132 unsigned char *saved_buffer = NULL;
4133 USER_MARSHAL_CB umcb;
4134
4135 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4136 TRACE("index=%d\n", index);
4137
4138 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4139
4140 if (flags & USER_MARSHAL_POINTER)
4141 {
4142 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4143 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4144 pStubMsg->Buffer += 4;
4145 if (pStubMsg->PointerBufferMark)
4146 {
4147 saved_buffer = pStubMsg->Buffer;
4148 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4149 pStubMsg->PointerBufferMark = NULL;
4150 }
4151 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4152 }
4153 else
4154 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4155
4156 pStubMsg->Buffer =
4157 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4158 &umcb.Flags, pStubMsg->Buffer, pMemory);
4159
4160 if (saved_buffer)
4161 {
4162 STD_OVERFLOW_CHECK(pStubMsg);
4163 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4164 pStubMsg->Buffer = saved_buffer;
4165 }
4166
4167 STD_OVERFLOW_CHECK(pStubMsg);
4168
4169 return NULL;
4170 }
4171
4172 /***********************************************************************
4173 * NdrUserMarshalUnmarshall [RPCRT4.@]
4174 */
4175 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4176 unsigned char **ppMemory,
4177 PFORMAT_STRING pFormat,
4178 unsigned char fMustAlloc)
4179 {
4180 unsigned flags = pFormat[1];
4181 unsigned index = *(const WORD*)&pFormat[2];
4182 DWORD memsize = *(const WORD*)&pFormat[4];
4183 unsigned char *saved_buffer = NULL;
4184 USER_MARSHAL_CB umcb;
4185
4186 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4187 TRACE("index=%d\n", index);
4188
4189 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4190
4191 if (flags & USER_MARSHAL_POINTER)
4192 {
4193 ALIGN_POINTER(pStubMsg->Buffer, 4);
4194 /* skip pointer prefix */
4195 pStubMsg->Buffer += 4;
4196 if (pStubMsg->PointerBufferMark)
4197 {
4198 saved_buffer = pStubMsg->Buffer;
4199 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4200 pStubMsg->PointerBufferMark = NULL;
4201 }
4202 ALIGN_POINTER(pStubMsg->Buffer, 8);
4203 }
4204 else
4205 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4206
4207 if (!fMustAlloc && !*ppMemory)
4208 fMustAlloc = TRUE;
4209 if (fMustAlloc)
4210 {
4211 *ppMemory = NdrAllocate(pStubMsg, memsize);
4212 memset(*ppMemory, 0, memsize);
4213 }
4214
4215 pStubMsg->Buffer =
4216 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4217 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4218
4219 if (saved_buffer)
4220 {
4221 STD_OVERFLOW_CHECK(pStubMsg);
4222 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4223 pStubMsg->Buffer = saved_buffer;
4224 }
4225
4226 return NULL;
4227 }
4228
4229 /***********************************************************************
4230 * NdrUserMarshalBufferSize [RPCRT4.@]
4231 */
4232 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4233 unsigned char *pMemory,
4234 PFORMAT_STRING pFormat)
4235 {
4236 unsigned flags = pFormat[1];
4237 unsigned index = *(const WORD*)&pFormat[2];
4238 DWORD bufsize = *(const WORD*)&pFormat[6];
4239 USER_MARSHAL_CB umcb;
4240 unsigned long saved_buffer_length = 0;
4241
4242 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4243 TRACE("index=%d\n", index);
4244
4245 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4246
4247 if (flags & USER_MARSHAL_POINTER)
4248 {
4249 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4250 /* skip pointer prefix */
4251 safe_buffer_length_increment(pStubMsg, 4);
4252 if (pStubMsg->IgnoreEmbeddedPointers)
4253 return;
4254 if (pStubMsg->PointerLength)
4255 {
4256 saved_buffer_length = pStubMsg->BufferLength;
4257 pStubMsg->BufferLength = pStubMsg->PointerLength;
4258 pStubMsg->PointerLength = 0;
4259 }
4260 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4261 }
4262 else
4263 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4264
4265 if (bufsize) {
4266 TRACE("size=%d\n", bufsize);
4267 safe_buffer_length_increment(pStubMsg, bufsize);
4268 }
4269 else
4270 pStubMsg->BufferLength =
4271 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4272 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4273
4274 if (saved_buffer_length)
4275 {
4276 pStubMsg->PointerLength = pStubMsg->BufferLength;
4277 pStubMsg->BufferLength = saved_buffer_length;
4278 }
4279
4280 }
4281
4282 /***********************************************************************
4283 * NdrUserMarshalMemorySize [RPCRT4.@]
4284 */
4285 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4286 PFORMAT_STRING pFormat)
4287 {
4288 unsigned flags = pFormat[1];
4289 unsigned index = *(const WORD*)&pFormat[2];
4290 DWORD memsize = *(const WORD*)&pFormat[4];
4291 DWORD bufsize = *(const WORD*)&pFormat[6];
4292
4293 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4294 TRACE("index=%d\n", index);
4295
4296 pStubMsg->MemorySize += memsize;
4297
4298 if (flags & USER_MARSHAL_POINTER)
4299 {
4300 ALIGN_POINTER(pStubMsg->Buffer, 4);
4301 /* skip pointer prefix */
4302 pStubMsg->Buffer += 4;
4303 if (pStubMsg->IgnoreEmbeddedPointers)
4304 return pStubMsg->MemorySize;
4305 ALIGN_POINTER(pStubMsg->Buffer, 8);
4306 }
4307 else
4308 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4309
4310 if (!bufsize)
4311 FIXME("not implemented for varying buffer size\n");
4312
4313 pStubMsg->Buffer += bufsize;
4314
4315 return pStubMsg->MemorySize;
4316 }
4317
4318 /***********************************************************************
4319 * NdrUserMarshalFree [RPCRT4.@]
4320 */
4321 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4322 unsigned char *pMemory,
4323 PFORMAT_STRING pFormat)
4324 {
4325 /* unsigned flags = pFormat[1]; */
4326 unsigned index = *(const WORD*)&pFormat[2];
4327 USER_MARSHAL_CB umcb;
4328
4329 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4330 TRACE("index=%d\n", index);
4331
4332 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4333
4334 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4335 &umcb.Flags, pMemory);
4336 }
4337
4338 /***********************************************************************
4339 * NdrGetUserMarshalInfo [RPCRT4.@]
4340 */
4341 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4342 {
4343 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4344
4345 TRACE("(%p,%u,%p)\n", flags, level, umi);
4346
4347 if (level != 1)
4348 return RPC_S_INVALID_ARG;
4349
4350 memset(&umi->Level1, 0, sizeof(umi->Level1));
4351 umi->InformationLevel = level;
4352
4353 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4354 return RPC_S_INVALID_ARG;
4355
4356 umi->Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4357 umi->Level1.pfnFree = umcb->pStubMsg->pfnFree;
4358 umi->Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4359
4360 switch (umcb->CBType)
4361 {
4362 case USER_MARSHAL_CB_MARSHALL:
4363 case USER_MARSHAL_CB_UNMARSHALL:
4364 {
4365 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4366 unsigned char *buffer_start = msg->Buffer;
4367 unsigned char *buffer_end =
4368 (unsigned char *)msg->Buffer + msg->BufferLength;
4369
4370 if (umcb->pStubMsg->Buffer < buffer_start ||
4371 umcb->pStubMsg->Buffer > buffer_end)
4372 return ERROR_INVALID_USER_BUFFER;
4373
4374 umi->Level1.Buffer = umcb->pStubMsg->Buffer;
4375 umi->Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4376 break;
4377 }
4378 case USER_MARSHAL_CB_BUFFER_SIZE:
4379 case USER_MARSHAL_CB_FREE:
4380 break;
4381 default:
4382 WARN("unrecognised CBType %d\n", umcb->CBType);
4383 }
4384
4385 return RPC_S_OK;
4386 }
4387
4388 /***********************************************************************
4389 * NdrClearOutParameters [RPCRT4.@]
4390 */
4391 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4392 PFORMAT_STRING pFormat,
4393 void *ArgAddr)
4394 {
4395 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4396 }
4397
4398 /***********************************************************************
4399 * NdrConvert [RPCRT4.@]
4400 */
4401 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4402 {
4403 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4404 /* FIXME: since this stub doesn't do any converting, the proper behavior
4405 is to raise an exception */
4406 }
4407
4408 /***********************************************************************
4409 * NdrConvert2 [RPCRT4.@]
4410 */
4411 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4412 {
4413 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4414 pStubMsg, pFormat, NumberParams);
4415 /* FIXME: since this stub doesn't do any converting, the proper behavior
4416 is to raise an exception */
4417 }
4418
4419 #include "pshpack1.h"
4420 typedef struct _NDR_CSTRUCT_FORMAT
4421 {
4422 unsigned char type;
4423 unsigned char alignment;
4424 unsigned short memory_size;
4425 short offset_to_array_description;
4426 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4427 #include "poppack.h"
4428
4429 /***********************************************************************
4430 * NdrConformantStructMarshall [RPCRT4.@]
4431 */
4432 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4433 unsigned char *pMemory,
4434 PFORMAT_STRING pFormat)
4435 {
4436 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4437 PFORMAT_STRING pCArrayFormat;
4438 ULONG esize, bufsize;
4439
4440 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4441
4442 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4443 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4444 {
4445 ERR("invalid format type %x\n", pCStructFormat->type);
4446 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4447 return NULL;
4448 }
4449
4450 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4451 pCStructFormat->offset_to_array_description;
4452 if (*pCArrayFormat != RPC_FC_CARRAY)
4453 {
4454 ERR("invalid array format type %x\n", pCStructFormat->type);
4455 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4456 return NULL;
4457 }
4458 esize = *(const WORD*)(pCArrayFormat+2);
4459
4460 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4461 pCArrayFormat + 4, 0);
4462
4463 WriteConformance(pStubMsg);
4464
4465 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4466
4467 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4468
4469 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4470 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4471 {
4472 ERR("integer overflow of memory_size %u with bufsize %u\n",
4473 pCStructFormat->memory_size, bufsize);
4474 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4475 }
4476 /* copy constant sized part of struct */
4477 pStubMsg->BufferMark = pStubMsg->Buffer;
4478 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4479
4480 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4481 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4482
4483 return NULL;
4484 }
4485
4486 /***********************************************************************
4487 * NdrConformantStructUnmarshall [RPCRT4.@]
4488 */
4489 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4490 unsigned char **ppMemory,
4491 PFORMAT_STRING pFormat,
4492 unsigned char fMustAlloc)
4493 {
4494 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4495 PFORMAT_STRING pCArrayFormat;
4496 ULONG esize, bufsize;
4497 unsigned char *saved_buffer;
4498
4499 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4500
4501 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4502 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4503 {
4504 ERR("invalid format type %x\n", pCStructFormat->type);
4505 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4506 return NULL;
4507 }
4508 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4509 pCStructFormat->offset_to_array_description;
4510 if (*pCArrayFormat != RPC_FC_CARRAY)
4511 {
4512 ERR("invalid array format type %x\n", pCStructFormat->type);
4513 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4514 return NULL;
4515 }
4516 esize = *(const WORD*)(pCArrayFormat+2);
4517
4518 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4519
4520 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4521
4522 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4523
4524 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4525 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4526 {
4527 ERR("integer overflow of memory_size %u with bufsize %u\n",
4528 pCStructFormat->memory_size, bufsize);
4529 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4530 }
4531
4532 if (fMustAlloc)
4533 {
4534 SIZE_T size = pCStructFormat->memory_size + bufsize;
4535 *ppMemory = NdrAllocate(pStubMsg, size);
4536 }
4537 else
4538 {
4539 if (!pStubMsg->IsClient && !*ppMemory)
4540 /* for servers, we just point straight into the RPC buffer */
4541 *ppMemory = pStubMsg->Buffer;
4542 }
4543
4544 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4545 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4546 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4547 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4548
4549 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4550 if (*ppMemory != saved_buffer)
4551 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4552
4553 return NULL;
4554 }
4555
4556 /***********************************************************************
4557 * NdrConformantStructBufferSize [RPCRT4.@]
4558 */
4559 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4560 unsigned char *pMemory,
4561 PFORMAT_STRING pFormat)
4562 {
4563 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4564 PFORMAT_STRING pCArrayFormat;
4565 ULONG esize;
4566
4567 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4568
4569 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4570 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4571 {
4572 ERR("invalid format type %x\n", pCStructFormat->type);
4573 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4574 return;
4575 }
4576 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4577 pCStructFormat->offset_to_array_description;
4578 if (*pCArrayFormat != RPC_FC_CARRAY)
4579 {
4580 ERR("invalid array format type %x\n", pCStructFormat->type);
4581 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4582 return;
4583 }
4584 esize = *(const WORD*)(pCArrayFormat+2);
4585
4586 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4587 SizeConformance(pStubMsg);
4588
4589 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4590
4591 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4592
4593 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4594 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4595
4596 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4597 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4598 }
4599
4600 /***********************************************************************
4601 * NdrConformantStructMemorySize [RPCRT4.@]
4602 */
4603 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4604 PFORMAT_STRING pFormat)
4605 {
4606 FIXME("stub\n");
4607 return 0;
4608 }
4609
4610 /***********************************************************************
4611 * NdrConformantStructFree [RPCRT4.@]
4612 */
4613 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4614 unsigned char *pMemory,
4615 PFORMAT_STRING pFormat)
4616 {
4617 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4618 PFORMAT_STRING pCArrayFormat;
4619
4620 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4621
4622 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4623 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4624 {
4625 ERR("invalid format type %x\n", pCStructFormat->type);
4626 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4627 return;
4628 }
4629
4630 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4631 pCStructFormat->offset_to_array_description;
4632 if (*pCArrayFormat != RPC_FC_CARRAY)
4633 {
4634 ERR("invalid array format type %x\n", pCStructFormat->type);
4635 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4636 return;
4637 }
4638
4639 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4640 pCArrayFormat + 4, 0);
4641
4642 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4643
4644 /* copy constant sized part of struct */
4645 pStubMsg->BufferMark = pStubMsg->Buffer;
4646
4647 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4648 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4649 }
4650
4651 /***********************************************************************
4652 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4653 */
4654 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4655 unsigned char *pMemory,
4656 PFORMAT_STRING pFormat)
4657 {
4658 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4659 PFORMAT_STRING pCVArrayFormat;
4660
4661 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4662
4663 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4664 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4665 {
4666 ERR("invalid format type %x\n", pCVStructFormat->type);
4667 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4668 return NULL;
4669 }
4670
4671 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4672 pCVStructFormat->offset_to_array_description;
4673
4674 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4675 pMemory + pCVStructFormat->memory_size,
4676 pCVArrayFormat);
4677
4678 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4679
4680 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4681
4682 /* write constant sized part */
4683 pStubMsg->BufferMark = pStubMsg->Buffer;
4684 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4685
4686 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4687 pMemory + pCVStructFormat->memory_size,
4688 pCVArrayFormat, FALSE /* fHasPointers */);
4689
4690 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4691
4692 return NULL;
4693 }
4694
4695 /***********************************************************************
4696 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4697 */
4698 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4699 unsigned char **ppMemory,
4700 PFORMAT_STRING pFormat,
4701 unsigned char fMustAlloc)
4702 {
4703 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4704 PFORMAT_STRING pCVArrayFormat;
4705 ULONG memsize, bufsize;
4706 unsigned char *saved_buffer, *saved_array_buffer;
4707 ULONG offset;
4708 unsigned char *array_memory;
4709
4710 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4711
4712 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4713 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4714 {
4715 ERR("invalid format type %x\n", pCVStructFormat->type);
4716 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4717 return NULL;
4718 }
4719
4720 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4721 pCVStructFormat->offset_to_array_description;
4722
4723 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4724 pCVArrayFormat);
4725
4726 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4727
4728 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4729
4730 /* work out how much memory to allocate if we need to do so */
4731 if (!fMustAlloc && !*ppMemory)
4732 fMustAlloc = TRUE;
4733 if (fMustAlloc)
4734 {
4735 SIZE_T size = pCVStructFormat->memory_size + memsize;
4736 *ppMemory = NdrAllocate(pStubMsg, size);
4737 }
4738
4739 /* mark the start of the constant data */
4740 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4741 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4742
4743 array_memory = *ppMemory + pCVStructFormat->memory_size;
4744 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4745 &array_memory, pCVArrayFormat,
4746 FALSE /* fMustAlloc */,
4747 FALSE /* fUseServerBufferMemory */,
4748 FALSE /* fUnmarshall */);
4749
4750 /* save offset in case unmarshalling pointers changes it */
4751 offset = pStubMsg->Offset;
4752
4753 /* mark the start of the array data */
4754 saved_array_buffer = pStubMsg->Buffer;
4755 safe_buffer_increment(pStubMsg, bufsize);
4756
4757 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4758
4759 /* copy the constant data */
4760 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4761 /* copy the array data */
4762 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4763 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4764 saved_array_buffer, bufsize);
4765
4766 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4767 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4768 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4769 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4770
4771 return NULL;
4772 }
4773
4774 /***********************************************************************
4775 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4776 */
4777 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4778 unsigned char *pMemory,
4779 PFORMAT_STRING pFormat)
4780 {
4781 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4782 PFORMAT_STRING pCVArrayFormat;
4783
4784 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4785
4786 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4787 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4788 {
4789 ERR("invalid format type %x\n", pCVStructFormat->type);
4790 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4791 return;
4792 }
4793
4794 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4795 pCVStructFormat->offset_to_array_description;
4796 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4797 pMemory + pCVStructFormat->memory_size,
4798 pCVArrayFormat);
4799
4800 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4801
4802 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4803
4804 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4805
4806 array_buffer_size(*pCVArrayFormat, pStubMsg,
4807 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4808 FALSE /* fHasPointers */);
4809
4810 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4811 }
4812
4813 /***********************************************************************
4814 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4815 */
4816 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4817 PFORMAT_STRING pFormat)
4818 {
4819 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4820 PFORMAT_STRING pCVArrayFormat;
4821
4822 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4823
4824 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4825 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4826 {
4827 ERR("invalid format type %x\n", pCVStructFormat->type);
4828 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4829 return 0;
4830 }
4831
4832 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4833 pCVStructFormat->offset_to_array_description;
4834 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4835
4836 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4837
4838 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4839
4840 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4841 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4842 FALSE /* fHasPointers */);
4843
4844 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4845
4846 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4847
4848 return pStubMsg->MemorySize;
4849 }
4850
4851 /***********************************************************************
4852 * NdrConformantVaryingStructFree [RPCRT4.@]
4853 */
4854 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4855 unsigned char *pMemory,
4856 PFORMAT_STRING pFormat)
4857 {
4858 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4859 PFORMAT_STRING pCVArrayFormat;
4860
4861 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4862
4863 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4864 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4865 {
4866 ERR("invalid format type %x\n", pCVStructFormat->type);
4867 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4868 return;
4869 }
4870
4871 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4872 pCVStructFormat->offset_to_array_description;
4873 array_free(*pCVArrayFormat, pStubMsg,
4874 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4875 FALSE /* fHasPointers */);
4876
4877 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4878
4879 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4880 }
4881
4882 #include "pshpack1.h"
4883 typedef struct
4884 {
4885 unsigned char type;
4886 unsigned char alignment;
4887 unsigned short total_size;
4888 } NDR_SMFARRAY_FORMAT;
4889
4890 typedef struct
4891 {
4892 unsigned char type;
4893 unsigned char alignment;
4894 unsigned long total_size;
4895 } NDR_LGFARRAY_FORMAT;
4896 #include "poppack.h"
4897
4898 /***********************************************************************
4899 * NdrFixedArrayMarshall [RPCRT4.@]
4900 */
4901 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4902 unsigned char *pMemory,
4903 PFORMAT_STRING pFormat)
4904 {
4905 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4906 unsigned long total_size;
4907
4908 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4909
4910 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4911 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4912 {
4913 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4914 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4915 return NULL;
4916 }
4917
4918 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4919
4920 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4921 {
4922 total_size = pSmFArrayFormat->total_size;
4923 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4924 }
4925 else
4926 {
4927 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4928 total_size = pLgFArrayFormat->total_size;
4929 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4930 }
4931
4932 pStubMsg->BufferMark = pStubMsg->Buffer;
4933 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4934
4935 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4936
4937 return NULL;
4938 }
4939
4940 /***********************************************************************
4941 * NdrFixedArrayUnmarshall [RPCRT4.@]
4942 */
4943 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4944 unsigned char **ppMemory,
4945 PFORMAT_STRING pFormat,
4946 unsigned char fMustAlloc)
4947 {
4948 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4949 unsigned long total_size;
4950 unsigned char *saved_buffer;
4951
4952 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4953
4954 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4955 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4956 {
4957 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4958 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4959 return NULL;
4960 }
4961
4962 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4963
4964 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4965 {
4966 total_size = pSmFArrayFormat->total_size;
4967 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4968 }
4969 else
4970 {
4971 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4972 total_size = pLgFArrayFormat->total_size;
4973 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4974 }
4975
4976 if (fMustAlloc)
4977 *ppMemory = NdrAllocate(pStubMsg, total_size);
4978 else
4979 {
4980 if (!pStubMsg->IsClient && !*ppMemory)
4981 /* for servers, we just point straight into the RPC buffer */
4982 *ppMemory = pStubMsg->Buffer;
4983 }
4984
4985 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4986 safe_buffer_increment(pStubMsg, total_size);
4987 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4988
4989 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4990 if (*ppMemory != saved_buffer)
4991 memcpy(*ppMemory, saved_buffer, total_size);
4992
4993 return NULL;
4994 }
4995
4996 /***********************************************************************
4997 * NdrFixedArrayBufferSize [RPCRT4.@]
4998 */
4999 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5000 unsigned char *pMemory,
5001 PFORMAT_STRING pFormat)
5002 {
5003 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5004 unsigned long total_size;
5005
5006 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5007
5008 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5009 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5010 {
5011 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5012 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5013 return;
5014 }
5015
5016 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5017
5018 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5019 {
5020 total_size = pSmFArrayFormat->total_size;
5021 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5022 }
5023 else
5024 {
5025 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5026 total_size = pLgFArrayFormat->total_size;
5027 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5028 }
5029 safe_buffer_length_increment(pStubMsg, total_size);
5030
5031 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5032 }
5033
5034 /***********************************************************************
5035 * NdrFixedArrayMemorySize [RPCRT4.@]
5036 */
5037 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5038 PFORMAT_STRING pFormat)
5039 {
5040 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5041 ULONG total_size;
5042
5043 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5044
5045 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5046 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5047 {
5048 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5049 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5050 return 0;
5051 }
5052
5053 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5054
5055 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5056 {
5057 total_size = pSmFArrayFormat->total_size;
5058 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5059 }
5060 else
5061 {
5062 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5063 total_size = pLgFArrayFormat->total_size;
5064 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5065 }
5066 pStubMsg->BufferMark = pStubMsg->Buffer;
5067 safe_buffer_increment(pStubMsg, total_size);
5068 pStubMsg->MemorySize += total_size;
5069
5070 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5071
5072 return total_size;
5073 }
5074
5075 /***********************************************************************
5076 * NdrFixedArrayFree [RPCRT4.@]
5077 */
5078 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5079 unsigned char *pMemory,
5080 PFORMAT_STRING pFormat)
5081 {
5082 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5083
5084 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5085
5086 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5087 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5088 {
5089 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5090 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5091 return;
5092 }
5093
5094 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5095 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5096 else
5097 {
5098 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5099 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5100 }
5101
5102 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5103 }
5104
5105 /***********************************************************************
5106 * NdrVaryingArrayMarshall [RPCRT4.@]
5107 */
5108 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5109 unsigned char *pMemory,
5110 PFORMAT_STRING pFormat)
5111 {
5112 unsigned char alignment;
5113 DWORD elements, esize;
5114 ULONG bufsize;
5115
5116 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5117
5118 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5119 (pFormat[0] != RPC_FC_LGVARRAY))
5120 {
5121 ERR("invalid format type %x\n", pFormat[0]);
5122 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5123 return NULL;
5124 }
5125
5126 alignment = pFormat[1] + 1;
5127
5128 if (pFormat[0] == RPC_FC_SMVARRAY)
5129 {
5130 pFormat += 2;
5131 pFormat += sizeof(WORD);
5132 elements = *(const WORD*)pFormat;
5133 pFormat += sizeof(WORD);
5134 }
5135 else
5136 {
5137 pFormat += 2;
5138 pFormat += sizeof(DWORD);
5139 elements = *(const DWORD*)pFormat;
5140 pFormat += sizeof(DWORD);
5141 }
5142
5143 esize = *(const WORD*)pFormat;
5144 pFormat += sizeof(WORD);
5145
5146 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5147 if ((pStubMsg->ActualCount > elements) ||
5148 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5149 {
5150 RpcRaiseException(RPC_S_INVALID_BOUND);
5151 return NULL;
5152 }
5153
5154 WriteVariance(pStubMsg);
5155
5156 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5157
5158 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5159 pStubMsg->BufferMark = pStubMsg->Buffer;
5160 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5161
5162 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5163
5164 return NULL;
5165 }
5166
5167 /***********************************************************************
5168 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5169 */
5170 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5171 unsigned char **ppMemory,
5172 PFORMAT_STRING pFormat,
5173 unsigned char fMustAlloc)
5174 {
5175 unsigned char alignment;
5176 DWORD size, elements, esize;
5177 ULONG bufsize;
5178 unsigned char *saved_buffer;
5179 ULONG offset;
5180
5181 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5182
5183 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5184 (pFormat[0] != RPC_FC_LGVARRAY))
5185 {
5186 ERR("invalid format type %x\n", pFormat[0]);
5187 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5188 return NULL;
5189 }
5190
5191 alignment = pFormat[1] + 1;
5192
5193 if (pFormat[0] == RPC_FC_SMVARRAY)
5194 {
5195 pFormat += 2;
5196 size = *(const WORD*)pFormat;
5197 pFormat += sizeof(WORD);
5198 elements = *(const WORD*)pFormat;
5199 pFormat += sizeof(WORD);
5200 }
5201 else
5202 {
5203 pFormat += 2;
5204 size = *(const DWORD*)pFormat;
5205 pFormat += sizeof(DWORD);
5206 elements = *(const DWORD*)pFormat;
5207 pFormat += sizeof(DWORD);
5208 }
5209
5210 esize = *(const WORD*)pFormat;
5211 pFormat += sizeof(WORD);
5212
5213 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5214
5215 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5216
5217 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5218 offset = pStubMsg->Offset;
5219
5220 if (!fMustAlloc && !*ppMemory)
5221 fMustAlloc = TRUE;
5222 if (fMustAlloc)
5223 *ppMemory = NdrAllocate(pStubMsg, size);
5224 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5225 safe_buffer_increment(pStubMsg, bufsize);
5226
5227 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5228
5229 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5230
5231 return NULL;
5232 }
5233
5234 /***********************************************************************
5235 * NdrVaryingArrayBufferSize [RPCRT4.@]
5236 */
5237 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5238 unsigned char *pMemory,
5239 PFORMAT_STRING pFormat)
5240 {
5241 unsigned char alignment;
5242 DWORD elements, esize;
5243
5244 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5245
5246 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5247 (pFormat[0] != RPC_FC_LGVARRAY))
5248 {
5249 ERR("invalid format type %x\n", pFormat[0]);
5250 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5251 return;
5252 }
5253
5254 alignment = pFormat[1] + 1;
5255
5256 if (pFormat[0] == RPC_FC_SMVARRAY)
5257 {
5258 pFormat += 2;
5259 pFormat += sizeof(WORD);
5260 elements = *(const WORD*)pFormat;
5261 pFormat += sizeof(WORD);
5262 }
5263 else
5264 {
5265 pFormat += 2;
5266 pFormat += sizeof(DWORD);
5267 elements = *(const DWORD*)pFormat;
5268 pFormat += sizeof(DWORD);
5269 }
5270
5271 esize = *(const WORD*)pFormat;
5272 pFormat += sizeof(WORD);
5273
5274 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5275 if ((pStubMsg->ActualCount > elements) ||
5276 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5277 {
5278 RpcRaiseException(RPC_S_INVALID_BOUND);
5279 return;
5280 }
5281
5282 SizeVariance(pStubMsg);
5283
5284 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5285
5286 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5287
5288 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5289 }
5290
5291 /***********************************************************************
5292 * NdrVaryingArrayMemorySize [RPCRT4.@]
5293 */
5294 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5295 PFORMAT_STRING pFormat)
5296 {
5297 unsigned char alignment;
5298 DWORD size, elements, esize;
5299
5300 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5301
5302 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5303 (pFormat[0] != RPC_FC_LGVARRAY))
5304 {
5305 ERR("invalid format type %x\n", pFormat[0]);
5306 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5307 return 0;
5308 }
5309
5310 alignment = pFormat[1] + 1;
5311
5312 if (pFormat[0] == RPC_FC_SMVARRAY)
5313 {
5314 pFormat += 2;
5315 size = *(const WORD*)pFormat;
5316 pFormat += sizeof(WORD);
5317 elements = *(const WORD*)pFormat;
5318 pFormat += sizeof(WORD);
5319 }
5320 else
5321 {
5322 pFormat += 2;
5323 size = *(const DWORD*)pFormat;
5324 pFormat += sizeof(DWORD);
5325 elements = *(const DWORD*)pFormat;
5326 pFormat += sizeof(DWORD);
5327 }
5328
5329 esize = *(const WORD*)pFormat;
5330 pFormat += sizeof(WORD);
5331
5332 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5333
5334 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5335
5336 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5337 pStubMsg->MemorySize += size;
5338
5339 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5340
5341 return pStubMsg->MemorySize;
5342 }
5343
5344 /***********************************************************************
5345 * NdrVaryingArrayFree [RPCRT4.@]
5346 */
5347 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5348 unsigned char *pMemory,
5349 PFORMAT_STRING pFormat)
5350 {
5351 DWORD elements;
5352
5353 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5354
5355 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5356 (pFormat[0] != RPC_FC_LGVARRAY))
5357 {
5358 ERR("invalid format type %x\n", pFormat[0]);
5359 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5360 return;
5361 }
5362
5363 if (pFormat[0] == RPC_FC_SMVARRAY)
5364 {
5365 pFormat += 2;
5366 pFormat += sizeof(WORD);
5367 elements = *(const WORD*)pFormat;
5368 pFormat += sizeof(WORD);
5369 }
5370 else
5371 {
5372 pFormat += 2;
5373 pFormat += sizeof(DWORD);
5374 elements = *(const DWORD*)pFormat;
5375 pFormat += sizeof(DWORD);
5376 }
5377
5378 pFormat += sizeof(WORD);
5379
5380 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5381 if ((pStubMsg->ActualCount > elements) ||
5382 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5383 {
5384 RpcRaiseException(RPC_S_INVALID_BOUND);
5385 return;
5386 }
5387
5388 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5389 }
5390
5391 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5392 {
5393 switch (fc)
5394 {
5395 case RPC_FC_BYTE:
5396 case RPC_FC_CHAR:
5397 case RPC_FC_SMALL:
5398 case RPC_FC_USMALL:
5399 return *pMemory;
5400 case RPC_FC_WCHAR:
5401 case RPC_FC_SHORT:
5402 case RPC_FC_USHORT:
5403 case RPC_FC_ENUM16:
5404 return *(const USHORT *)pMemory;
5405 case RPC_FC_LONG:
5406 case RPC_FC_ULONG:
5407 case RPC_FC_ENUM32:
5408 return *(const ULONG *)pMemory;
5409 default:
5410 FIXME("Unhandled base type: 0x%02x\n", fc);
5411 return 0;
5412 }
5413 }
5414
5415 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5416 unsigned long discriminant,
5417 PFORMAT_STRING pFormat)
5418 {
5419 unsigned short num_arms, arm, type;
5420
5421 num_arms = *(const SHORT*)pFormat & 0x0fff;
5422 pFormat += 2;
5423 for(arm = 0; arm < num_arms; arm++)
5424 {
5425 if(discriminant == *(const ULONG*)pFormat)
5426 {
5427 pFormat += 4;
5428 break;
5429 }
5430 pFormat += 6;
5431 }
5432
5433 type = *(const unsigned short*)pFormat;
5434 TRACE("type %04x\n", type);
5435 if(arm == num_arms) /* default arm extras */
5436 {
5437 if(type == 0xffff)
5438 {
5439 ERR("no arm for 0x%lx and no default case\n", discriminant);
5440 RpcRaiseException(RPC_S_INVALID_TAG);
5441 return NULL;
5442 }
5443 if(type == 0)
5444 {
5445 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5446 return NULL;
5447 }
5448 }
5449 return pFormat;
5450 }
5451
5452 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5453 {
5454 unsigned short type;
5455
5456 pFormat += 2;
5457
5458 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5459 if(!pFormat)
5460 return NULL;
5461
5462 type = *(const unsigned short*)pFormat;
5463 if((type & 0xff00) == 0x8000)
5464 {
5465 unsigned char basetype = LOBYTE(type);
5466 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5467 }
5468 else
5469 {
5470 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5471 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5472 if (m)
5473 {
5474 unsigned char *saved_buffer = NULL;
5475 int pointer_buffer_mark_set = 0;
5476 switch(*desc)
5477 {
5478 case RPC_FC_RP:
5479 case RPC_FC_UP:
5480 case RPC_FC_OP:
5481 case RPC_FC_FP:
5482 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5483 saved_buffer = pStubMsg->Buffer;
5484 if (pStubMsg->PointerBufferMark)
5485 {
5486 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5487 pStubMsg->PointerBufferMark = NULL;
5488 pointer_buffer_mark_set = 1;
5489 }
5490 else
5491 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5492
5493 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5494 if (pointer_buffer_mark_set)
5495 {
5496 STD_OVERFLOW_CHECK(pStubMsg);
5497 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5498 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5499 {
5500 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5501 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5502 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5503 }
5504 pStubMsg->Buffer = saved_buffer + 4;
5505 }
5506 break;
5507 default:
5508 m(pStubMsg, pMemory, desc);
5509 }
5510 }
5511 else FIXME("no marshaller for embedded type %02x\n", *desc);
5512 }
5513 return NULL;
5514 }
5515
5516 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5517 unsigned char **ppMemory,
5518 ULONG discriminant,
5519 PFORMAT_STRING pFormat,
5520 unsigned char fMustAlloc)
5521 {
5522 unsigned short type;
5523
5524 pFormat += 2;
5525
5526 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5527 if(!pFormat)
5528 return NULL;
5529
5530 type = *(const unsigned short*)pFormat;
5531 if((type & 0xff00) == 0x8000)
5532 {
5533 unsigned char basetype = LOBYTE(type);
5534 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5535 }
5536 else
5537 {
5538 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5539 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5540 if (m)
5541 {
5542 unsigned char *saved_buffer = NULL;
5543 int pointer_buffer_mark_set = 0;
5544 switch(*desc)
5545 {
5546 case RPC_FC_RP:
5547 case RPC_FC_UP:
5548 case RPC_FC_OP:
5549 case RPC_FC_FP:
5550 **(void***)ppMemory = NULL;
5551 ALIGN_POINTER(pStubMsg->Buffer, 4);
5552 saved_buffer = pStubMsg->Buffer;
5553 if (pStubMsg->PointerBufferMark)
5554 {
5555 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5556 pStubMsg->PointerBufferMark = NULL;
5557 pointer_buffer_mark_set = 1;
5558 }
5559 else
5560 pStubMsg->Buffer += 4; /* for pointer ID */
5561
5562 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5563 {
5564 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5565 saved_buffer, pStubMsg->BufferEnd);
5566 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5567 }
5568
5569 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5570 if (pointer_buffer_mark_set)
5571 {
5572 STD_OVERFLOW_CHECK(pStubMsg);
5573 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5574 pStubMsg->Buffer = saved_buffer + 4;
5575 }
5576 break;
5577 default:
5578 m(pStubMsg, ppMemory, desc, fMustAlloc);
5579 }
5580 }
5581 else FIXME("no marshaller for embedded type %02x\n", *desc);
5582 }
5583 return NULL;
5584 }
5585
5586 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5587 unsigned char *pMemory,
5588 ULONG discriminant,
5589 PFORMAT_STRING pFormat)
5590 {
5591 unsigned short type;
5592
5593 pFormat += 2;
5594
5595 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5596 if(!pFormat)
5597 return;
5598
5599 type = *(const unsigned short*)pFormat;
5600 if((type & 0xff00) == 0x8000)
5601 {
5602 unsigned char basetype = LOBYTE(type);
5603 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5604 }
5605 else
5606 {
5607 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5608 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5609 if (m)
5610 {
5611 switch(*desc)
5612 {
5613 case RPC_FC_RP:
5614 case RPC_FC_UP:
5615 case RPC_FC_OP:
5616 case RPC_FC_FP:
5617 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5618 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5619 if (!pStubMsg->IgnoreEmbeddedPointers)
5620 {
5621 int saved_buffer_length = pStubMsg->BufferLength;
5622 pStubMsg->BufferLength = pStubMsg->PointerLength;
5623 pStubMsg->PointerLength = 0;
5624 if(!pStubMsg->BufferLength)
5625 ERR("BufferLength == 0??\n");
5626 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5627 pStubMsg->PointerLength = pStubMsg->BufferLength;
5628 pStubMsg->BufferLength = saved_buffer_length;
5629 }
5630 break;
5631 default:
5632 m(pStubMsg, pMemory, desc);
5633 }
5634 }
5635 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5636 }
5637 }
5638
5639 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5640 ULONG discriminant,
5641 PFORMAT_STRING pFormat)
5642 {
5643 unsigned short type, size;
5644
5645 size = *(const unsigned short*)pFormat;
5646 pStubMsg->Memory += size;
5647 pFormat += 2;
5648
5649 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5650 if(!pFormat)
5651 return 0;
5652
5653 type = *(const unsigned short*)pFormat;
5654 if((type & 0xff00) == 0x8000)
5655 {
5656 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5657 }
5658 else
5659 {
5660 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5661 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5662 unsigned char *saved_buffer;
5663 if (m)
5664 {
5665 switch(*desc)
5666 {
5667 case RPC_FC_RP:
5668 case RPC_FC_UP:
5669 case RPC_FC_OP:
5670 case RPC_FC_FP:
5671 ALIGN_POINTER(pStubMsg->Buffer, 4);
5672 saved_buffer = pStubMsg->Buffer;
5673 safe_buffer_increment(pStubMsg, 4);
5674 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5675 pStubMsg->MemorySize += 4;
5676 if (!pStubMsg->IgnoreEmbeddedPointers)
5677 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5678 break;
5679 default:
5680 return m(pStubMsg, desc);
5681 }
5682 }
5683 else FIXME("no marshaller for embedded type %02x\n", *desc);
5684 }
5685
5686 TRACE("size %d\n", size);
5687 return size;
5688 }
5689
5690 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5691 unsigned char *pMemory,
5692 ULONG discriminant,
5693 PFORMAT_STRING pFormat)
5694 {
5695 unsigned short type;
5696
5697 pFormat += 2;
5698
5699 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5700 if(!pFormat)
5701 return;
5702
5703 type = *(const unsigned short*)pFormat;
5704 if((type & 0xff00) != 0x8000)
5705 {
5706 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5707 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5708 if (m)
5709 {
5710 switch(*desc)
5711 {
5712 case RPC_FC_RP:
5713 case RPC_FC_UP:
5714 case RPC_FC_OP:
5715 case RPC_FC_FP:
5716 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5717 break;
5718 default:
5719 m(pStubMsg, pMemory, desc);
5720 }
5721 }
5722 }
5723 }
5724
5725 /***********************************************************************
5726 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5727 */
5728 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5729 unsigned char *pMemory,
5730 PFORMAT_STRING pFormat)
5731 {
5732 unsigned char switch_type;
5733 unsigned char increment;
5734 ULONG switch_value;
5735
5736 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5737 pFormat++;
5738
5739 switch_type = *pFormat & 0xf;
5740 increment = (*pFormat & 0xf0) >> 4;
5741 pFormat++;
5742
5743 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5744
5745 switch_value = get_discriminant(switch_type, pMemory);
5746 TRACE("got switch value 0x%x\n", switch_value);
5747
5748 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5749 pMemory += increment;
5750
5751 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5752 }
5753
5754 /***********************************************************************
5755 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5756 */
5757 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5758 unsigned char **ppMemory,
5759 PFORMAT_STRING pFormat,
5760 unsigned char fMustAlloc)
5761 {
5762 unsigned char switch_type;
5763 unsigned char increment;
5764 ULONG switch_value;
5765 unsigned short size;
5766 unsigned char *pMemoryArm;
5767
5768 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5769 pFormat++;
5770
5771 switch_type = *pFormat & 0xf;
5772 increment = (*pFormat & 0xf0) >> 4;
5773 pFormat++;
5774
5775 ALIGN_POINTER(pStubMsg->Buffer, increment);
5776 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5777 TRACE("got switch value 0x%x\n", switch_value);
5778
5779 size = *(const unsigned short*)pFormat + increment;
5780 if (!fMustAlloc && !*ppMemory)
5781 fMustAlloc = TRUE;
5782 if (fMustAlloc)
5783 *ppMemory = NdrAllocate(pStubMsg, size);
5784
5785 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5786 pMemoryArm = *ppMemory + increment;
5787
5788 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5789 }
5790
5791 /***********************************************************************
5792 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5793 */
5794 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5795 unsigned char *pMemory,
5796 PFORMAT_STRING pFormat)
5797 {
5798 unsigned char switch_type;
5799 unsigned char increment;
5800 ULONG switch_value;
5801
5802 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5803 pFormat++;
5804
5805 switch_type = *pFormat & 0xf;
5806 increment = (*pFormat & 0xf0) >> 4;
5807 pFormat++;
5808
5809 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5810 switch_value = get_discriminant(switch_type, pMemory);
5811 TRACE("got switch value 0x%x\n", switch_value);
5812
5813 /* Add discriminant size */
5814 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5815 pMemory += increment;
5816
5817 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5818 }
5819
5820 /***********************************************************************
5821 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5822 */
5823 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5824 PFORMAT_STRING pFormat)
5825 {
5826 unsigned char switch_type;
5827 unsigned char increment;
5828 ULONG switch_value;
5829
5830 switch_type = *pFormat & 0xf;
5831 increment = (*pFormat & 0xf0) >> 4;
5832 pFormat++;
5833
5834 ALIGN_POINTER(pStubMsg->Buffer, increment);
5835 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5836 TRACE("got switch value 0x%x\n", switch_value);
5837
5838 pStubMsg->Memory += increment;
5839
5840 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5841 }
5842
5843 /***********************************************************************
5844 * NdrEncapsulatedUnionFree [RPCRT4.@]
5845 */
5846 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5847 unsigned char *pMemory,
5848 PFORMAT_STRING pFormat)
5849 {
5850 unsigned char switch_type;
5851 unsigned char increment;
5852 ULONG switch_value;
5853
5854 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5855 pFormat++;
5856
5857 switch_type = *pFormat & 0xf;
5858 increment = (*pFormat & 0xf0) >> 4;
5859 pFormat++;
5860
5861 switch_value = get_discriminant(switch_type, pMemory);
5862 TRACE("got switch value 0x%x\n", switch_value);
5863
5864 pMemory += increment;
5865
5866 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5867 }
5868
5869 /***********************************************************************
5870 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5871 */
5872 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5873 unsigned char *pMemory,
5874 PFORMAT_STRING pFormat)
5875 {
5876 unsigned char switch_type;
5877
5878 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5879 pFormat++;
5880
5881 switch_type = *pFormat;
5882 pFormat++;
5883
5884 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5885 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5886 /* Marshall discriminant */
5887 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5888
5889 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5890 }
5891
5892 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5893 PFORMAT_STRING *ppFormat)
5894 {
5895 long discriminant = 0;
5896
5897 switch(**ppFormat)
5898 {
5899 case RPC_FC_BYTE:
5900 case RPC_FC_CHAR:
5901 case RPC_FC_SMALL:
5902 case RPC_FC_USMALL:
5903 {
5904 UCHAR d;
5905 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5906 discriminant = d;
5907 break;
5908 }
5909 case RPC_FC_WCHAR:
5910 case RPC_FC_SHORT:
5911 case RPC_FC_USHORT:
5912 {
5913 USHORT d;
5914 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5915 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5916 discriminant = d;
5917 break;
5918 }
5919 case RPC_FC_LONG:
5920 case RPC_FC_ULONG:
5921 {
5922 ULONG d;
5923 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5924 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5925 discriminant = d;
5926 break;
5927 }
5928 default:
5929 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5930 }
5931 (*ppFormat)++;
5932
5933 if (pStubMsg->fHasNewCorrDesc)
5934 *ppFormat += 6;
5935 else
5936 *ppFormat += 4;
5937 return discriminant;
5938 }
5939
5940 /**********************************************************************
5941 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5942 */
5943 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5944 unsigned char **ppMemory,
5945 PFORMAT_STRING pFormat,
5946 unsigned char fMustAlloc)
5947 {
5948 long discriminant;
5949 unsigned short size;
5950
5951 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5952 pFormat++;
5953
5954 /* Unmarshall discriminant */
5955 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5956 TRACE("unmarshalled discriminant %lx\n", discriminant);
5957
5958 pFormat += *(const SHORT*)pFormat;
5959
5960 size = *(const unsigned short*)pFormat;
5961
5962 if (!fMustAlloc && !*ppMemory)
5963 fMustAlloc = TRUE;
5964 if (fMustAlloc)
5965 *ppMemory = NdrAllocate(pStubMsg, size);
5966
5967 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5968 }
5969
5970 /***********************************************************************
5971 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5972 */
5973 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5974 unsigned char *pMemory,
5975 PFORMAT_STRING pFormat)
5976 {
5977 unsigned char switch_type;
5978
5979 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5980 pFormat++;
5981
5982 switch_type = *pFormat;
5983 pFormat++;
5984
5985 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5986 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5987 /* Add discriminant size */
5988 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5989
5990 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5991 }
5992
5993 /***********************************************************************
5994 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5995 */
5996 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5997 PFORMAT_STRING pFormat)
5998 {
5999 ULONG discriminant;
6000
6001 pFormat++;
6002 /* Unmarshall discriminant */
6003 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6004 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6005
6006 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6007 }
6008
6009 /***********************************************************************
6010 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6011 */
6012 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6013 unsigned char *pMemory,
6014 PFORMAT_STRING pFormat)
6015 {
6016 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6017 pFormat++;
6018 pFormat++;
6019
6020 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6021 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6022
6023 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6024 }
6025
6026 /***********************************************************************
6027 * NdrByteCountPointerMarshall [RPCRT4.@]
6028 */
6029 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6030 unsigned char *pMemory,
6031 PFORMAT_STRING pFormat)
6032 {
6033 FIXME("stub\n");
6034 return NULL;
6035 }
6036
6037 /***********************************************************************
6038 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6039 */
6040 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6041 unsigned char **ppMemory,
6042 PFORMAT_STRING pFormat,
6043 unsigned char fMustAlloc)
6044 {
6045 FIXME("stub\n");
6046 return NULL;
6047 }
6048
6049 /***********************************************************************
6050 * NdrByteCountPointerBufferSize [RPCRT4.@]
6051 */
6052 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6053 unsigned char *pMemory,
6054 PFORMAT_STRING pFormat)
6055 {
6056 FIXME("stub\n");
6057 }
6058
6059 /***********************************************************************
6060 * NdrByteCountPointerMemorySize [internal]
6061 */
6062 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6063 PFORMAT_STRING pFormat)
6064 {
6065 FIXME("stub\n");
6066 return 0;
6067 }
6068
6069 /***********************************************************************
6070 * NdrByteCountPointerFree [RPCRT4.@]
6071 */
6072 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6073 unsigned char *pMemory,
6074 PFORMAT_STRING pFormat)
6075 {
6076 FIXME("stub\n");
6077 }
6078
6079 /***********************************************************************
6080 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6081 */
6082 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6083 unsigned char *pMemory,
6084 PFORMAT_STRING pFormat)
6085 {
6086 FIXME("stub\n");
6087 return NULL;
6088 }
6089
6090 /***********************************************************************
6091 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6092 */
6093 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6094 unsigned char **ppMemory,
6095 PFORMAT_STRING pFormat,
6096 unsigned char fMustAlloc)
6097 {
6098 FIXME("stub\n");
6099 return NULL;
6100 }
6101
6102 /***********************************************************************
6103 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6104 */
6105 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6106 unsigned char *pMemory,
6107 PFORMAT_STRING pFormat)
6108 {
6109 FIXME("stub\n");
6110 }
6111
6112 /***********************************************************************
6113 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6114 */
6115 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6116 PFORMAT_STRING pFormat)
6117 {
6118 FIXME("stub\n");
6119 return 0;
6120 }
6121
6122 /***********************************************************************
6123 * NdrXmitOrRepAsFree [RPCRT4.@]
6124 */
6125 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6126 unsigned char *pMemory,
6127 PFORMAT_STRING pFormat)
6128 {
6129 FIXME("stub\n");
6130 }
6131
6132 /***********************************************************************
6133 * NdrRangeMarshall [internal]
6134 */
6135 static unsigned char *WINAPI NdrRangeMarshall(
6136 PMIDL_STUB_MESSAGE pStubMsg,
6137 unsigned char *pMemory,
6138 PFORMAT_STRING pFormat)
6139 {
6140 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6141 unsigned char base_type;
6142
6143 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6144
6145 if (pRange->type != RPC_FC_RANGE)
6146 {
6147 ERR("invalid format type %x\n", pRange->type);
6148 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6149 return NULL;
6150 }
6151
6152 base_type = pRange->flags_type & 0xf;
6153
6154 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6155 }
6156
6157 /***********************************************************************
6158 * NdrRangeUnmarshall [RPCRT4.@]
6159 */
6160 unsigned char *WINAPI NdrRangeUnmarshall(
6161 PMIDL_STUB_MESSAGE pStubMsg,
6162 unsigned char **ppMemory,
6163 PFORMAT_STRING pFormat,
6164 unsigned char fMustAlloc)
6165 {
6166 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6167 unsigned char base_type;
6168
6169 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6170
6171 if (pRange->type != RPC_FC_RANGE)
6172 {
6173 ERR("invalid format type %x\n", pRange->type);
6174 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6175 return NULL;
6176 }
6177 base_type = pRange->flags_type & 0xf;
6178
6179 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6180 base_type, pRange->low_value, pRange->high_value);
6181
6182 #define RANGE_UNMARSHALL(type, format_spec) \
6183 do \
6184 { \
6185 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6186 if (!fMustAlloc && !*ppMemory) \
6187 fMustAlloc = TRUE; \
6188 if (fMustAlloc) \
6189 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6190 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
6191 { \
6192 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6193 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6194 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6195 } \
6196 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
6197 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
6198 { \
6199 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6200 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
6201 (type)pRange->high_value); \
6202 RpcRaiseException(RPC_S_INVALID_BOUND); \
6203 return NULL; \
6204 } \
6205 TRACE("*ppMemory: %p\n", *ppMemory); \
6206 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6207 pStubMsg->Buffer += sizeof(type); \
6208 } while (0)
6209
6210 switch(base_type)
6211 {
6212 case RPC_FC_CHAR:
6213 case RPC_FC_SMALL:
6214 RANGE_UNMARSHALL(UCHAR, "%d");
6215 TRACE("value: 0x%02x\n", **ppMemory);
6216 break;
6217 case RPC_FC_BYTE:
6218 case RPC_FC_USMALL:
6219 RANGE_UNMARSHALL(CHAR, "%u");
6220 TRACE("value: 0x%02x\n", **ppMemory);
6221 break;
6222 case RPC_FC_WCHAR: /* FIXME: valid? */
6223 case RPC_FC_USHORT:
6224 RANGE_UNMARSHALL(USHORT, "%u");
6225 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6226 break;
6227 case RPC_FC_SHORT:
6228 RANGE_UNMARSHALL(SHORT, "%d");
6229 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6230 break;
6231 case RPC_FC_LONG:
6232 RANGE_UNMARSHALL(LONG, "%d");
6233 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6234 break;
6235 case RPC_FC_ULONG:
6236 RANGE_UNMARSHALL(ULONG, "%u");
6237 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6238 break;
6239 case RPC_FC_ENUM16:
6240 case RPC_FC_ENUM32:
6241 FIXME("Unhandled enum type\n");
6242 break;
6243 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
6244 case RPC_FC_FLOAT:
6245 case RPC_FC_DOUBLE:
6246 case RPC_FC_HYPER:
6247 default:
6248 ERR("invalid range base type: 0x%02x\n", base_type);
6249 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6250 }
6251
6252 return NULL;
6253 }
6254
6255 /***********************************************************************
6256 * NdrRangeBufferSize [internal]
6257 */
6258 static void WINAPI NdrRangeBufferSize(
6259 PMIDL_STUB_MESSAGE pStubMsg,
6260 unsigned char *pMemory,
6261 PFORMAT_STRING pFormat)
6262 {
6263 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6264 unsigned char base_type;
6265
6266 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6267
6268 if (pRange->type != RPC_FC_RANGE)
6269 {
6270 ERR("invalid format type %x\n", pRange->type);
6271 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6272 }
6273 base_type = pRange->flags_type & 0xf;
6274
6275 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6276 }
6277
6278 /***********************************************************************
6279 * NdrRangeMemorySize [internal]
6280 */
6281 static ULONG WINAPI NdrRangeMemorySize(
6282 PMIDL_STUB_MESSAGE pStubMsg,
6283 PFORMAT_STRING pFormat)
6284 {
6285 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6286 unsigned char base_type;
6287
6288 if (pRange->type != RPC_FC_RANGE)
6289 {
6290 ERR("invalid format type %x\n", pRange->type);
6291 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6292 return 0;
6293 }
6294 base_type = pRange->flags_type & 0xf;
6295
6296 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6297 }
6298
6299 /***********************************************************************
6300 * NdrRangeFree [internal]
6301 */
6302 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6303 unsigned char *pMemory,
6304 PFORMAT_STRING pFormat)
6305 {
6306 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6307
6308 /* nothing to do */
6309 }
6310
6311 /***********************************************************************
6312 * NdrBaseTypeMarshall [internal]
6313 */
6314 static unsigned char *WINAPI NdrBaseTypeMarshall(
6315 PMIDL_STUB_MESSAGE pStubMsg,
6316 unsigned char *pMemory,
6317 PFORMAT_STRING pFormat)
6318 {
6319 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6320
6321 switch(*pFormat)
6322 {
6323 case RPC_FC_BYTE:
6324 case RPC_FC_CHAR:
6325 case RPC_FC_SMALL:
6326 case RPC_FC_USMALL:
6327 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6328 TRACE("value: 0x%02x\n", *pMemory);
6329 break;
6330 case RPC_FC_WCHAR:
6331 case RPC_FC_SHORT:
6332 case RPC_FC_USHORT:
6333 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6334 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6335 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6336 break;
6337 case RPC_FC_LONG:
6338 case RPC_FC_ULONG:
6339 case RPC_FC_ERROR_STATUS_T:
6340 case RPC_FC_ENUM32:
6341 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6342 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6343 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6344 break;
6345 case RPC_FC_FLOAT:
6346 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6347 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6348 break;
6349 case RPC_FC_DOUBLE:
6350 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6351 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6352 break;
6353 case RPC_FC_HYPER:
6354 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6355 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6356 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6357 break;
6358 case RPC_FC_ENUM16:
6359 /* only 16-bits on the wire, so do a sanity check */
6360 if (*(UINT *)pMemory > SHRT_MAX)
6361 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6362 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6363 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6364 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6365 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6366 pStubMsg->Buffer += sizeof(USHORT);
6367 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6368 break;
6369 case RPC_FC_IGNORE:
6370 break;
6371 default:
6372 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6373 }
6374
6375 /* FIXME: what is the correct return value? */
6376 return NULL;
6377 }
6378
6379 /***********************************************************************
6380 * NdrBaseTypeUnmarshall [internal]
6381 */
6382 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6383 PMIDL_STUB_MESSAGE pStubMsg,
6384 unsigned char **ppMemory,
6385 PFORMAT_STRING pFormat,
6386 unsigned char fMustAlloc)
6387 {
6388 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6389
6390 #define BASE_TYPE_UNMARSHALL(type) \
6391 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6392 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6393 { \
6394 *ppMemory = pStubMsg->Buffer; \
6395 TRACE("*ppMemory: %p\n", *ppMemory); \
6396 safe_buffer_increment(pStubMsg, sizeof(type)); \
6397 } \
6398 else \
6399 { \
6400 if (fMustAlloc) \
6401 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6402 TRACE("*ppMemory: %p\n", *ppMemory); \
6403 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6404 }
6405
6406 switch(*pFormat)
6407 {
6408 case RPC_FC_BYTE:
6409 case RPC_FC_CHAR:
6410 case RPC_FC_SMALL:
6411 case RPC_FC_USMALL:
6412 BASE_TYPE_UNMARSHALL(UCHAR);
6413 TRACE("value: 0x%02x\n", **ppMemory);
6414 break;
6415 case RPC_FC_WCHAR:
6416 case RPC_FC_SHORT:
6417 case RPC_FC_USHORT:
6418 BASE_TYPE_UNMARSHALL(USHORT);
6419 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6420 break;
6421 case RPC_FC_LONG:
6422 case RPC_FC_ULONG:
6423 case RPC_FC_ERROR_STATUS_T:
6424 case RPC_FC_ENUM32:
6425 BASE_TYPE_UNMARSHALL(ULONG);
6426 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6427 break;
6428 case RPC_FC_FLOAT:
6429 BASE_TYPE_UNMARSHALL(float);
6430 TRACE("value: %f\n", **(float **)ppMemory);
6431 break;
6432 case RPC_FC_DOUBLE:
6433 BASE_TYPE_UNMARSHALL(double);
6434 TRACE("value: %f\n", **(double **)ppMemory);
6435 break;
6436 case RPC_FC_HYPER:
6437 BASE_TYPE_UNMARSHALL(ULONGLONG);
6438 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6439 break;
6440 case RPC_FC_ENUM16:
6441 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6442 if (!fMustAlloc && !*ppMemory)
6443 fMustAlloc = TRUE;
6444 if (fMustAlloc)
6445 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6446 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6447 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6448 TRACE("*ppMemory: %p\n", *ppMemory);
6449 /* 16-bits on the wire, but int in memory */
6450 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6451 pStubMsg->Buffer += sizeof(USHORT);
6452 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6453 break;
6454 case RPC_FC_IGNORE:
6455 break;
6456 default:
6457 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6458 }
6459 #undef BASE_TYPE_UNMARSHALL
6460
6461 /* FIXME: what is the correct return value? */
6462
6463 return NULL;
6464 }
6465
6466 /***********************************************************************
6467 * NdrBaseTypeBufferSize [internal]
6468 */
6469 static void WINAPI NdrBaseTypeBufferSize(
6470 PMIDL_STUB_MESSAGE pStubMsg,
6471 unsigned char *pMemory,
6472 PFORMAT_STRING pFormat)
6473 {
6474 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6475
6476 switch(*pFormat)
6477 {
6478 case RPC_FC_BYTE:
6479 case RPC_FC_CHAR:
6480 case RPC_FC_SMALL:
6481 case RPC_FC_USMALL:
6482 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6483 break;
6484 case RPC_FC_WCHAR:
6485 case RPC_FC_SHORT:
6486 case RPC_FC_USHORT:
6487 case RPC_FC_ENUM16:
6488 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6489 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6490 break;
6491 case RPC_FC_LONG:
6492 case RPC_FC_ULONG:
6493 case RPC_FC_ENUM32:
6494 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6495 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6496 break;
6497 case RPC_FC_FLOAT:
6498 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6499 safe_buffer_length_increment(pStubMsg, sizeof(float));
6500 break;
6501 case RPC_FC_DOUBLE:
6502 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6503 safe_buffer_length_increment(pStubMsg, sizeof(double));
6504 break;
6505 case RPC_FC_HYPER:
6506 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6507 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6508 break;
6509 case RPC_FC_ERROR_STATUS_T:
6510 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6511 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6512 break;
6513 case RPC_FC_IGNORE:
6514 break;
6515 default:
6516 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6517 }
6518 }
6519
6520 /***********************************************************************
6521 * NdrBaseTypeMemorySize [internal]
6522 */
6523 static ULONG WINAPI NdrBaseTypeMemorySize(
6524 PMIDL_STUB_MESSAGE pStubMsg,
6525 PFORMAT_STRING pFormat)
6526 {
6527 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6528
6529 switch(*pFormat)
6530 {
6531 case RPC_FC_BYTE:
6532 case RPC_FC_CHAR:
6533 case RPC_FC_SMALL:
6534 case RPC_FC_USMALL:
6535 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6536 pStubMsg->MemorySize += sizeof(UCHAR);
6537 return sizeof(UCHAR);
6538 case RPC_FC_WCHAR:
6539 case RPC_FC_SHORT:
6540 case RPC_FC_USHORT:
6541 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6542 pStubMsg->MemorySize += sizeof(USHORT);
6543 return sizeof(USHORT);
6544 case RPC_FC_LONG:
6545 case RPC_FC_ULONG:
6546 case RPC_FC_ENUM32:
6547 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6548 pStubMsg->MemorySize += sizeof(ULONG);
6549 return sizeof(ULONG);
6550 case RPC_FC_FLOAT:
6551 safe_buffer_increment(pStubMsg, sizeof(float));
6552 pStubMsg->MemorySize += sizeof(float);
6553 return sizeof(float);
6554 case RPC_FC_DOUBLE:
6555 safe_buffer_increment(pStubMsg, sizeof(double));
6556 pStubMsg->MemorySize += sizeof(double);
6557 return sizeof(double);
6558 case RPC_FC_HYPER:
6559 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6560 pStubMsg->MemorySize += sizeof(ULONGLONG);
6561 return sizeof(ULONGLONG);
6562 case RPC_FC_ERROR_STATUS_T:
6563 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6564 pStubMsg->MemorySize += sizeof(error_status_t);
6565 return sizeof(error_status_t);
6566 case RPC_FC_ENUM16:
6567 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6568 pStubMsg->MemorySize += sizeof(UINT);
6569 return sizeof(UINT);
6570 case RPC_FC_IGNORE:
6571 pStubMsg->MemorySize += sizeof(void *);
6572 return sizeof(void *);
6573 default:
6574 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6575 return 0;
6576 }
6577 }
6578
6579 /***********************************************************************
6580 * NdrBaseTypeFree [internal]
6581 */
6582 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6583 unsigned char *pMemory,
6584 PFORMAT_STRING pFormat)
6585 {
6586 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6587
6588 /* nothing to do */
6589 }
6590
6591 /***********************************************************************
6592 * NdrContextHandleBufferSize [internal]
6593 */
6594 static void WINAPI NdrContextHandleBufferSize(
6595 PMIDL_STUB_MESSAGE pStubMsg,
6596 unsigned char *pMemory,
6597 PFORMAT_STRING pFormat)
6598 {
6599 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6600
6601 if (*pFormat != RPC_FC_BIND_CONTEXT)
6602 {
6603 ERR("invalid format type %x\n", *pFormat);
6604 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6605 }
6606 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6607 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6608 }
6609
6610 /***********************************************************************
6611 * NdrContextHandleMarshall [internal]
6612 */
6613 static unsigned char *WINAPI NdrContextHandleMarshall(
6614 PMIDL_STUB_MESSAGE pStubMsg,
6615 unsigned char *pMemory,
6616 PFORMAT_STRING pFormat)
6617 {
6618 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6619
6620 if (*pFormat != RPC_FC_BIND_CONTEXT)
6621 {
6622 ERR("invalid format type %x\n", *pFormat);
6623 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6624 }
6625 TRACE("flags: 0x%02x\n", pFormat[1]);
6626
6627 if (pFormat[1] & 0x80)
6628 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6629 else
6630 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6631
6632 return NULL;
6633 }
6634
6635 /***********************************************************************
6636 * NdrContextHandleUnmarshall [internal]
6637 */
6638 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6639 PMIDL_STUB_MESSAGE pStubMsg,
6640 unsigned char **ppMemory,
6641 PFORMAT_STRING pFormat,
6642 unsigned char fMustAlloc)
6643 {
6644 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6645 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6646
6647 if (*pFormat != RPC_FC_BIND_CONTEXT)
6648 {
6649 ERR("invalid format type %x\n", *pFormat);
6650 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6651 }
6652 TRACE("flags: 0x%02x\n", pFormat[1]);
6653
6654 /* [out]-only or [ret] param */
6655 if ((pFormat[1] & 0x60) == 0x20)
6656 **(NDR_CCONTEXT **)ppMemory = NULL;
6657 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6658
6659 return NULL;
6660 }
6661
6662 /***********************************************************************
6663 * NdrClientContextMarshall [RPCRT4.@]
6664 */
6665 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6666 NDR_CCONTEXT ContextHandle,
6667 int fCheck)
6668 {
6669 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6670
6671 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6672
6673 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6674 {
6675 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6676 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6677 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6678 }
6679
6680 /* FIXME: what does fCheck do? */
6681 NDRCContextMarshall(ContextHandle,
6682 pStubMsg->Buffer);
6683
6684 pStubMsg->Buffer += cbNDRContext;
6685 }
6686
6687 /***********************************************************************
6688 * NdrClientContextUnmarshall [RPCRT4.@]
6689 */
6690 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6691 NDR_CCONTEXT * pContextHandle,
6692 RPC_BINDING_HANDLE BindHandle)
6693 {
6694 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6695
6696 ALIGN_POINTER(pStubMsg->Buffer, 4);
6697
6698 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6699 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6700
6701 NDRCContextUnmarshall(pContextHandle,
6702 BindHandle,
6703 pStubMsg->Buffer,
6704 pStubMsg->RpcMsg->DataRepresentation);
6705
6706 pStubMsg->Buffer += cbNDRContext;
6707 }
6708
6709 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6710 NDR_SCONTEXT ContextHandle,
6711 NDR_RUNDOWN RundownRoutine )
6712 {
6713 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6714
6715 ALIGN_POINTER(pStubMsg->Buffer, 4);
6716
6717 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6718 {
6719 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6720 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6721 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6722 }
6723
6724 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6725 pStubMsg->Buffer, RundownRoutine, NULL,
6726 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6727 pStubMsg->Buffer += cbNDRContext;
6728 }
6729
6730 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6731 {
6732 NDR_SCONTEXT ContextHandle;
6733
6734 TRACE("(%p)\n", pStubMsg);
6735
6736 ALIGN_POINTER(pStubMsg->Buffer, 4);
6737
6738 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6739 {
6740 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6741 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6742 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6743 }
6744
6745 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6746 pStubMsg->Buffer,
6747 pStubMsg->RpcMsg->DataRepresentation,
6748 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6749 pStubMsg->Buffer += cbNDRContext;
6750
6751 return ContextHandle;
6752 }
6753
6754 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6755 unsigned char* pMemory,
6756 PFORMAT_STRING pFormat)
6757 {
6758 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6759 }
6760
6761 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6762 PFORMAT_STRING pFormat)
6763 {
6764 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6765 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6766
6767 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6768
6769 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6770 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6771 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6772 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6773 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6774 {
6775 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6776 if_id = &sif->InterfaceId;
6777 }
6778
6779 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6780 pStubMsg->RpcMsg->DataRepresentation, if_id,
6781 flags);
6782 }
6783
6784 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6785 NDR_SCONTEXT ContextHandle,
6786 NDR_RUNDOWN RundownRoutine,
6787 PFORMAT_STRING pFormat)
6788 {
6789 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6790 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6791
6792 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6793
6794 ALIGN_POINTER(pStubMsg->Buffer, 4);
6795
6796 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6797 {
6798 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6799 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6800 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6801 }
6802
6803 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6804 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6805 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6806 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6807 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6808 {
6809 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6810 if_id = &sif->InterfaceId;
6811 }
6812
6813 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6814 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6815 pStubMsg->Buffer += cbNDRContext;
6816 }
6817
6818 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6819 PFORMAT_STRING pFormat)
6820 {
6821 NDR_SCONTEXT ContextHandle;
6822 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6823 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6824
6825 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6826
6827 ALIGN_POINTER(pStubMsg->Buffer, 4);
6828
6829 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6830 {
6831 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6832 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6833 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6834 }
6835
6836 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6837 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6838 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6839 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6840 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6841 {
6842 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6843 if_id = &sif->InterfaceId;
6844 }
6845
6846 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6847 pStubMsg->Buffer,
6848 pStubMsg->RpcMsg->DataRepresentation,
6849 if_id, flags);
6850 pStubMsg->Buffer += cbNDRContext;
6851
6852 return ContextHandle;
6853 }
6854
6855 /***********************************************************************
6856 * NdrCorrelationInitialize [RPCRT4.@]
6857 *
6858 * Initializes correlation validity checking.
6859 *
6860 * PARAMS
6861 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6862 * pMemory [I] Pointer to memory to use as a cache.
6863 * CacheSize [I] Size of the memory pointed to by pMemory.
6864 * Flags [I] Reserved. Set to zero.
6865 *
6866 * RETURNS
6867 * Nothing.
6868 */
6869 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6870 {
6871 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6872 pStubMsg->fHasNewCorrDesc = TRUE;
6873 }
6874
6875 /***********************************************************************
6876 * NdrCorrelationPass [RPCRT4.@]
6877 *
6878 * Performs correlation validity checking.
6879 *
6880 * PARAMS
6881 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6882 *
6883 * RETURNS
6884 * Nothing.
6885 */
6886 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6887 {
6888 FIXME("(%p): stub\n", pStubMsg);
6889 }
6890
6891 /***********************************************************************
6892 * NdrCorrelationFree [RPCRT4.@]
6893 *
6894 * Frees any resources used while unmarshalling parameters that need
6895 * correlation validity checking.
6896 *
6897 * PARAMS
6898 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6899 *
6900 * RETURNS
6901 * Nothing.
6902 */
6903 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6904 {
6905 FIXME("(%p): stub\n", pStubMsg);
6906 }