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