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