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