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