rpcrt4: The conformant array offset in complex structs should be signed.
[wine/hacks.git] / dlls / rpcrt4 / ndr_marshall.c
blob41d5f31e1d44b196c4c754e7af5dc62b191f4ced
1 /*
2 * NDR data marshalling
4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
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.
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.
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
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
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <assert.h>
34 #include <limits.h>
36 #include "windef.h"
37 #include "winbase.h"
38 #include "winerror.h"
40 #include "ndr_misc.h"
41 #include "rpcndr.h"
43 #include "wine/unicode.h"
44 #include "wine/rpcfc.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole);
50 #if defined(__i386__)
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
56 #else
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
63 (uint32)) /* allow as r-value */
65 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
66 (MAKELONG( \
67 MAKEWORD(*(pchar), *((pchar)+1)), \
68 MAKEWORD(*((pchar)+2), *((pchar)+3))))
69 #endif
71 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
72 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
73 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
74 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
75 *(pchar) = HIBYTE(HIWORD(uint32)), \
76 (uint32)) /* allow as r-value */
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
79 (MAKELONG( \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
88 #else
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
93 #endif
95 /* _Align must be the desired alignment,
96 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
97 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
98 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
99 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
100 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
101 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
102 do { \
103 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
104 ALIGN_POINTER(_Ptr, _Align); \
105 } while(0)
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
111 } while (0)
113 #define NDR_POINTER_ID_BASE 0x20000
114 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
115 #define NDR_TABLE_SIZE 128
116 #define NDR_TABLE_MASK 127
118 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
120 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
121 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
122 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
124 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
125 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
126 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
128 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
130 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
132 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
133 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
134 /* 0x10 */
135 NdrBaseTypeMarshall,
136 /* 0x11 */
137 NdrPointerMarshall, NdrPointerMarshall,
138 NdrPointerMarshall, NdrPointerMarshall,
139 /* 0x15 */
140 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
141 NdrConformantStructMarshall, NdrConformantStructMarshall,
142 NdrConformantVaryingStructMarshall,
143 NdrComplexStructMarshall,
144 /* 0x1b */
145 NdrConformantArrayMarshall,
146 NdrConformantVaryingArrayMarshall,
147 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
148 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
149 NdrComplexArrayMarshall,
150 /* 0x22 */
151 NdrConformantStringMarshall, 0, 0,
152 NdrConformantStringMarshall,
153 NdrNonConformantStringMarshall, 0, 0, 0,
154 /* 0x2a */
155 NdrEncapsulatedUnionMarshall,
156 NdrNonEncapsulatedUnionMarshall,
157 NdrByteCountPointerMarshall,
158 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
159 /* 0x2f */
160 NdrInterfacePointerMarshall,
161 /* 0x30 */
162 NdrContextHandleMarshall,
163 /* 0xb1 */
164 0, 0, 0,
165 NdrUserMarshalMarshall,
166 0, 0,
167 /* 0xb7 */
168 NdrRangeMarshall
170 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
174 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
175 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
176 /* 0x10 */
177 NdrBaseTypeUnmarshall,
178 /* 0x11 */
179 NdrPointerUnmarshall, NdrPointerUnmarshall,
180 NdrPointerUnmarshall, NdrPointerUnmarshall,
181 /* 0x15 */
182 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
183 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
184 NdrConformantVaryingStructUnmarshall,
185 NdrComplexStructUnmarshall,
186 /* 0x1b */
187 NdrConformantArrayUnmarshall,
188 NdrConformantVaryingArrayUnmarshall,
189 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
190 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
191 NdrComplexArrayUnmarshall,
192 /* 0x22 */
193 NdrConformantStringUnmarshall, 0, 0,
194 NdrConformantStringUnmarshall,
195 NdrNonConformantStringUnmarshall, 0, 0, 0,
196 /* 0x2a */
197 NdrEncapsulatedUnionUnmarshall,
198 NdrNonEncapsulatedUnionUnmarshall,
199 NdrByteCountPointerUnmarshall,
200 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
201 /* 0x2f */
202 NdrInterfacePointerUnmarshall,
203 /* 0x30 */
204 NdrContextHandleUnmarshall,
205 /* 0xb1 */
206 0, 0, 0,
207 NdrUserMarshalUnmarshall,
208 0, 0,
209 /* 0xb7 */
210 NdrRangeUnmarshall
212 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
214 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
216 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
217 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
218 /* 0x10 */
219 NdrBaseTypeBufferSize,
220 /* 0x11 */
221 NdrPointerBufferSize, NdrPointerBufferSize,
222 NdrPointerBufferSize, NdrPointerBufferSize,
223 /* 0x15 */
224 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
225 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
226 NdrConformantVaryingStructBufferSize,
227 NdrComplexStructBufferSize,
228 /* 0x1b */
229 NdrConformantArrayBufferSize,
230 NdrConformantVaryingArrayBufferSize,
231 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
232 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
233 NdrComplexArrayBufferSize,
234 /* 0x22 */
235 NdrConformantStringBufferSize, 0, 0,
236 NdrConformantStringBufferSize,
237 NdrNonConformantStringBufferSize, 0, 0, 0,
238 /* 0x2a */
239 NdrEncapsulatedUnionBufferSize,
240 NdrNonEncapsulatedUnionBufferSize,
241 NdrByteCountPointerBufferSize,
242 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
243 /* 0x2f */
244 NdrInterfacePointerBufferSize,
245 /* 0x30 */
246 NdrContextHandleBufferSize,
247 /* 0xb1 */
248 0, 0, 0,
249 NdrUserMarshalBufferSize,
250 0, 0,
251 /* 0xb7 */
252 NdrRangeBufferSize
254 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
256 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
258 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
259 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
260 /* 0x10 */
261 NdrBaseTypeMemorySize,
262 /* 0x11 */
263 NdrPointerMemorySize, NdrPointerMemorySize,
264 NdrPointerMemorySize, NdrPointerMemorySize,
265 /* 0x15 */
266 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
267 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
268 NdrConformantVaryingStructMemorySize,
269 NdrComplexStructMemorySize,
270 /* 0x1b */
271 NdrConformantArrayMemorySize,
272 NdrConformantVaryingArrayMemorySize,
273 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
274 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
275 NdrComplexArrayMemorySize,
276 /* 0x22 */
277 NdrConformantStringMemorySize, 0, 0,
278 NdrConformantStringMemorySize,
279 NdrNonConformantStringMemorySize, 0, 0, 0,
280 /* 0x2a */
281 NdrEncapsulatedUnionMemorySize,
282 NdrNonEncapsulatedUnionMemorySize,
283 NdrByteCountPointerMemorySize,
284 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
285 /* 0x2f */
286 NdrInterfacePointerMemorySize,
287 /* 0x30 */
289 /* 0xb1 */
290 0, 0, 0,
291 NdrUserMarshalMemorySize,
292 0, 0,
293 /* 0xb7 */
294 NdrRangeMemorySize
296 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
298 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
299 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
300 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
301 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
302 /* 0x10 */
303 NdrBaseTypeFree,
304 /* 0x11 */
305 NdrPointerFree, NdrPointerFree,
306 NdrPointerFree, NdrPointerFree,
307 /* 0x15 */
308 NdrSimpleStructFree, NdrSimpleStructFree,
309 NdrConformantStructFree, NdrConformantStructFree,
310 NdrConformantVaryingStructFree,
311 NdrComplexStructFree,
312 /* 0x1b */
313 NdrConformantArrayFree,
314 NdrConformantVaryingArrayFree,
315 NdrFixedArrayFree, NdrFixedArrayFree,
316 NdrVaryingArrayFree, NdrVaryingArrayFree,
317 NdrComplexArrayFree,
318 /* 0x22 */
319 0, 0, 0,
320 0, 0, 0, 0, 0,
321 /* 0x2a */
322 NdrEncapsulatedUnionFree,
323 NdrNonEncapsulatedUnionFree,
325 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
326 /* 0x2f */
327 NdrInterfacePointerFree,
328 /* 0x30 */
330 /* 0xb1 */
331 0, 0, 0,
332 NdrUserMarshalFree,
333 0, 0,
334 /* 0xb7 */
335 NdrRangeFree
338 typedef struct _NDR_MEMORY_LIST
340 ULONG magic;
341 ULONG size;
342 ULONG reserved;
343 struct _NDR_MEMORY_LIST *next;
344 } NDR_MEMORY_LIST;
346 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
348 /***********************************************************************
349 * NdrAllocate [RPCRT4.@]
351 * Allocates a block of memory using pStubMsg->pfnAllocate.
353 * PARAMS
354 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
355 * len [I] Size of memory block to allocate.
357 * RETURNS
358 * The memory block of size len that was allocated.
360 * NOTES
361 * The memory block is always 8-byte aligned.
362 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
363 * exception is raised.
365 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
367 size_t aligned_len;
368 size_t adjusted_len;
369 void *p;
370 NDR_MEMORY_LIST *mem_list;
372 aligned_len = ALIGNED_LENGTH(len, 8);
373 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
374 /* check for overflow */
375 if (adjusted_len < len)
377 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len);
378 RpcRaiseException(RPC_X_BAD_STUB_DATA);
381 p = pStubMsg->pfnAllocate(adjusted_len);
382 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
384 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
385 mem_list->magic = MEML_MAGIC;
386 mem_list->size = aligned_len;
387 mem_list->reserved = 0;
388 mem_list->next = pStubMsg->pMemoryList;
389 pStubMsg->pMemoryList = mem_list;
391 TRACE("-- %p\n", p);
392 return p;
395 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
397 TRACE("(%p, %p)\n", pStubMsg, Pointer);
399 pStubMsg->pfnFree(Pointer);
402 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
404 return (*(const ULONG *)pFormat != -1);
407 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
409 ALIGN_POINTER(pStubMsg->Buffer, 4);
410 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
411 RpcRaiseException(RPC_X_BAD_STUB_DATA);
412 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
413 pStubMsg->Buffer += 4;
414 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
415 if (pStubMsg->fHasNewCorrDesc)
416 return pFormat+6;
417 else
418 return pFormat+4;
421 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
423 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
425 pStubMsg->Offset = 0;
426 pStubMsg->ActualCount = pStubMsg->MaxCount;
427 goto done;
430 ALIGN_POINTER(pStubMsg->Buffer, 4);
431 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
432 RpcRaiseException(RPC_X_BAD_STUB_DATA);
433 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
434 pStubMsg->Buffer += 4;
435 TRACE("offset is %d\n", pStubMsg->Offset);
436 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
437 pStubMsg->Buffer += 4;
438 TRACE("variance is %d\n", pStubMsg->ActualCount);
440 if ((pStubMsg->ActualCount > MaxValue) ||
441 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
443 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
444 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
445 RpcRaiseException(RPC_S_INVALID_BOUND);
446 return NULL;
449 done:
450 if (pStubMsg->fHasNewCorrDesc)
451 return pFormat+6;
452 else
453 return pFormat+4;
456 /* writes the conformance value to the buffer */
457 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
459 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
460 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
461 RpcRaiseException(RPC_X_BAD_STUB_DATA);
462 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
463 pStubMsg->Buffer += 4;
466 /* writes the variance values to the buffer */
467 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
469 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
470 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
471 RpcRaiseException(RPC_X_BAD_STUB_DATA);
472 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
473 pStubMsg->Buffer += 4;
474 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
475 pStubMsg->Buffer += 4;
478 /* requests buffer space for the conformance value */
479 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
481 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
482 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
483 RpcRaiseException(RPC_X_BAD_STUB_DATA);
484 pStubMsg->BufferLength += 4;
487 /* requests buffer space for the variance values */
488 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
490 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
491 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
492 RpcRaiseException(RPC_X_BAD_STUB_DATA);
493 pStubMsg->BufferLength += 8;
496 PFORMAT_STRING ComputeConformanceOrVariance(
497 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
498 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
500 BYTE dtype = pFormat[0] & 0xf;
501 short ofs = *(const short *)&pFormat[2];
502 LPVOID ptr = NULL;
503 DWORD data = 0;
505 if (!IsConformanceOrVariancePresent(pFormat)) {
506 /* null descriptor */
507 *pCount = def;
508 goto finish_conf;
511 switch (pFormat[0] & 0xf0) {
512 case RPC_FC_NORMAL_CONFORMANCE:
513 TRACE("normal conformance, ofs=%d\n", ofs);
514 ptr = pMemory;
515 break;
516 case RPC_FC_POINTER_CONFORMANCE:
517 TRACE("pointer conformance, ofs=%d\n", ofs);
518 ptr = pStubMsg->Memory;
519 break;
520 case RPC_FC_TOP_LEVEL_CONFORMANCE:
521 TRACE("toplevel conformance, ofs=%d\n", ofs);
522 if (pStubMsg->StackTop) {
523 ptr = pStubMsg->StackTop;
525 else {
526 /* -Os mode, *pCount is already set */
527 goto finish_conf;
529 break;
530 case RPC_FC_CONSTANT_CONFORMANCE:
531 data = ofs | ((DWORD)pFormat[1] << 16);
532 TRACE("constant conformance, val=%d\n", data);
533 *pCount = data;
534 goto finish_conf;
535 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
536 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
537 if (pStubMsg->StackTop) {
538 ptr = pStubMsg->StackTop;
540 else {
541 /* ? */
542 goto done_conf_grab;
544 break;
545 default:
546 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
549 switch (pFormat[1]) {
550 case RPC_FC_DEREFERENCE:
551 ptr = *(LPVOID*)((char *)ptr + ofs);
552 break;
553 case RPC_FC_CALLBACK:
555 unsigned char *old_stack_top = pStubMsg->StackTop;
556 pStubMsg->StackTop = ptr;
558 /* ofs is index into StubDesc->apfnExprEval */
559 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
560 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
562 pStubMsg->StackTop = old_stack_top;
564 /* the callback function always stores the computed value in MaxCount */
565 *pCount = pStubMsg->MaxCount;
566 goto finish_conf;
568 default:
569 ptr = (char *)ptr + ofs;
570 break;
573 switch (dtype) {
574 case RPC_FC_LONG:
575 case RPC_FC_ULONG:
576 data = *(DWORD*)ptr;
577 break;
578 case RPC_FC_SHORT:
579 data = *(SHORT*)ptr;
580 break;
581 case RPC_FC_USHORT:
582 data = *(USHORT*)ptr;
583 break;
584 case RPC_FC_CHAR:
585 case RPC_FC_SMALL:
586 data = *(CHAR*)ptr;
587 break;
588 case RPC_FC_BYTE:
589 case RPC_FC_USMALL:
590 data = *(UCHAR*)ptr;
591 break;
592 default:
593 FIXME("unknown conformance data type %x\n", dtype);
594 goto done_conf_grab;
596 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
598 done_conf_grab:
599 switch (pFormat[1]) {
600 case RPC_FC_DEREFERENCE: /* already handled */
601 case 0: /* no op */
602 *pCount = data;
603 break;
604 case RPC_FC_ADD_1:
605 *pCount = data + 1;
606 break;
607 case RPC_FC_SUB_1:
608 *pCount = data - 1;
609 break;
610 case RPC_FC_MULT_2:
611 *pCount = data * 2;
612 break;
613 case RPC_FC_DIV_2:
614 *pCount = data / 2;
615 break;
616 default:
617 FIXME("unknown conformance op %d\n", pFormat[1]);
618 goto finish_conf;
621 finish_conf:
622 TRACE("resulting conformance is %ld\n", *pCount);
623 if (pStubMsg->fHasNewCorrDesc)
624 return pFormat+6;
625 else
626 return pFormat+4;
629 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
630 * the result overflows 32-bits */
631 static inline ULONG safe_multiply(ULONG a, ULONG b)
633 ULONGLONG ret = (ULONGLONG)a * b;
634 if (ret > 0xffffffff)
636 RpcRaiseException(RPC_S_INVALID_BOUND);
637 return 0;
639 return ret;
642 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
644 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
645 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
646 RpcRaiseException(RPC_X_BAD_STUB_DATA);
647 pStubMsg->Buffer += size;
650 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
652 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
654 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
655 pStubMsg->BufferLength, size);
656 RpcRaiseException(RPC_X_BAD_STUB_DATA);
658 pStubMsg->BufferLength += size;
661 /* copies data from the buffer, checking that there is enough data in the buffer
662 * to do so */
663 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
665 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
666 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
668 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
669 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
670 RpcRaiseException(RPC_X_BAD_STUB_DATA);
672 if (p == pStubMsg->Buffer)
673 ERR("pointer is the same as the buffer\n");
674 memcpy(p, pStubMsg->Buffer, size);
675 pStubMsg->Buffer += size;
678 /* copies data to the buffer, checking that there is enough space to do so */
679 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
681 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
682 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
684 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
685 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
686 size);
687 RpcRaiseException(RPC_X_BAD_STUB_DATA);
689 memcpy(pStubMsg->Buffer, p, size);
690 pStubMsg->Buffer += size;
693 /* verify that string data sitting in the buffer is valid and safe to
694 * unmarshall */
695 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
697 ULONG i;
699 /* verify the buffer is safe to access */
700 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
701 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
703 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
704 pStubMsg->BufferEnd, pStubMsg->Buffer);
705 RpcRaiseException(RPC_X_BAD_STUB_DATA);
708 /* strings must always have null terminating bytes */
709 if (bufsize < esize)
711 ERR("invalid string length of %d\n", bufsize / esize);
712 RpcRaiseException(RPC_S_INVALID_BOUND);
715 for (i = bufsize - esize; i < bufsize; i++)
716 if (pStubMsg->Buffer[i] != 0)
718 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
719 i, pStubMsg->Buffer[i]);
720 RpcRaiseException(RPC_S_INVALID_BOUND);
725 * NdrConformantString:
727 * What MS calls a ConformantString is, in DCE terminology,
728 * a Varying-Conformant String.
730 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
731 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
732 * into unmarshalled string)
733 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
734 * [
735 * data: CHARTYPE[maxlen]
736 * ]
737 * ], where CHARTYPE is the appropriate character type (specified externally)
741 /***********************************************************************
742 * NdrConformantStringMarshall [RPCRT4.@]
744 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
745 unsigned char *pszMessage, PFORMAT_STRING pFormat)
747 ULONG esize, size;
749 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
751 if (*pFormat == RPC_FC_C_CSTRING) {
752 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
753 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
754 esize = 1;
756 else if (*pFormat == RPC_FC_C_WSTRING) {
757 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
758 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
759 esize = 2;
761 else {
762 ERR("Unhandled string type: %#x\n", *pFormat);
763 /* FIXME: raise an exception. */
764 return NULL;
767 if (pFormat[1] == RPC_FC_STRING_SIZED)
768 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
769 else
770 pStubMsg->MaxCount = pStubMsg->ActualCount;
771 pStubMsg->Offset = 0;
772 WriteConformance(pStubMsg);
773 WriteVariance(pStubMsg);
775 size = safe_multiply(esize, pStubMsg->ActualCount);
776 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
778 /* success */
779 return NULL; /* is this always right? */
782 /***********************************************************************
783 * NdrConformantStringBufferSize [RPCRT4.@]
785 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
786 unsigned char* pMemory, PFORMAT_STRING pFormat)
788 ULONG esize;
790 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
792 SizeConformance(pStubMsg);
793 SizeVariance(pStubMsg);
795 if (*pFormat == RPC_FC_C_CSTRING) {
796 TRACE("string=%s\n", debugstr_a((char*)pMemory));
797 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
798 esize = 1;
800 else if (*pFormat == RPC_FC_C_WSTRING) {
801 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
802 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
803 esize = 2;
805 else {
806 ERR("Unhandled string type: %#x\n", *pFormat);
807 /* FIXME: raise an exception */
808 return;
811 if (pFormat[1] == RPC_FC_STRING_SIZED)
812 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
813 else
814 pStubMsg->MaxCount = pStubMsg->ActualCount;
816 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
819 /************************************************************************
820 * NdrConformantStringMemorySize [RPCRT4.@]
822 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
823 PFORMAT_STRING pFormat )
825 ULONG bufsize, memsize, esize;
827 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
829 ReadConformance(pStubMsg, NULL);
830 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
832 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
834 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
835 pStubMsg->ActualCount, pStubMsg->MaxCount);
836 RpcRaiseException(RPC_S_INVALID_BOUND);
838 if (pStubMsg->Offset)
840 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
841 RpcRaiseException(RPC_S_INVALID_BOUND);
844 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
845 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
846 else {
847 ERR("Unhandled string type: %#x\n", *pFormat);
848 /* FIXME: raise an exception */
849 esize = 0;
852 memsize = safe_multiply(esize, pStubMsg->MaxCount);
853 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
855 validate_string_data(pStubMsg, bufsize, esize);
857 safe_buffer_increment(pStubMsg, bufsize);
858 pStubMsg->MemorySize += memsize;
860 return pStubMsg->MemorySize;
863 /************************************************************************
864 * NdrConformantStringUnmarshall [RPCRT4.@]
866 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
867 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
869 ULONG bufsize, memsize, esize;
871 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
872 pStubMsg, *ppMemory, pFormat, fMustAlloc);
874 assert(pFormat && ppMemory && pStubMsg);
876 ReadConformance(pStubMsg, NULL);
877 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
879 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
881 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
882 pStubMsg->ActualCount, pStubMsg->MaxCount);
883 RpcRaiseException(RPC_S_INVALID_BOUND);
884 return NULL;
886 if (pStubMsg->Offset)
888 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
889 RpcRaiseException(RPC_S_INVALID_BOUND);
890 return NULL;
893 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
894 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
895 else {
896 ERR("Unhandled string type: %#x\n", *pFormat);
897 /* FIXME: raise an exception */
898 esize = 0;
901 memsize = safe_multiply(esize, pStubMsg->MaxCount);
902 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
904 validate_string_data(pStubMsg, bufsize, esize);
906 if (fMustAlloc)
907 *ppMemory = NdrAllocate(pStubMsg, memsize);
908 else
910 if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
911 /* if the data in the RPC buffer is big enough, we just point straight
912 * into it */
913 *ppMemory = pStubMsg->Buffer;
914 else if (!*ppMemory)
915 *ppMemory = NdrAllocate(pStubMsg, memsize);
918 if (*ppMemory == pStubMsg->Buffer)
919 safe_buffer_increment(pStubMsg, bufsize);
920 else
921 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
923 if (*pFormat == RPC_FC_C_CSTRING) {
924 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
926 else if (*pFormat == RPC_FC_C_WSTRING) {
927 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
930 return NULL; /* FIXME: is this always right? */
933 /***********************************************************************
934 * NdrNonConformantStringMarshall [RPCRT4.@]
936 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
937 unsigned char *pMemory,
938 PFORMAT_STRING pFormat)
940 ULONG esize, size, maxsize;
942 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
944 maxsize = *(USHORT *)&pFormat[2];
946 if (*pFormat == RPC_FC_CSTRING)
948 ULONG i;
949 const char *str = (const char *)pMemory;
950 for (i = 0; i < maxsize && *str; i++, str++)
952 TRACE("string=%s\n", debugstr_an(str, i));
953 pStubMsg->ActualCount = i + 1;
954 esize = 1;
956 else if (*pFormat == RPC_FC_WSTRING)
958 ULONG i;
959 const WCHAR *str = (const WCHAR *)pMemory;
960 for (i = 0; i < maxsize && *str; i++, str++)
962 TRACE("string=%s\n", debugstr_wn(str, i));
963 pStubMsg->ActualCount = i + 1;
964 esize = 2;
966 else
968 ERR("Unhandled string type: %#x\n", *pFormat);
969 RpcRaiseException(RPC_X_BAD_STUB_DATA);
972 pStubMsg->Offset = 0;
973 WriteVariance(pStubMsg);
975 size = safe_multiply(esize, pStubMsg->ActualCount);
976 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
978 return NULL;
981 /***********************************************************************
982 * NdrNonConformantStringUnmarshall [RPCRT4.@]
984 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
985 unsigned char **ppMemory,
986 PFORMAT_STRING pFormat,
987 unsigned char fMustAlloc)
989 ULONG bufsize, memsize, esize, maxsize;
991 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
992 pStubMsg, *ppMemory, pFormat, fMustAlloc);
994 maxsize = *(USHORT *)&pFormat[2];
996 ReadVariance(pStubMsg, NULL, maxsize);
997 if (pStubMsg->Offset)
999 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1000 RpcRaiseException(RPC_S_INVALID_BOUND);
1003 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1004 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1005 else
1007 ERR("Unhandled string type: %#x\n", *pFormat);
1008 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1011 memsize = esize * maxsize;
1012 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1014 validate_string_data(pStubMsg, bufsize, esize);
1016 if (fMustAlloc || !*ppMemory)
1017 *ppMemory = NdrAllocate(pStubMsg, memsize);
1019 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
1021 if (*pFormat == RPC_FC_CSTRING) {
1022 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
1024 else if (*pFormat == RPC_FC_WSTRING) {
1025 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
1028 return NULL;
1031 /***********************************************************************
1032 * NdrNonConformantStringBufferSize [RPCRT4.@]
1034 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1035 unsigned char *pMemory,
1036 PFORMAT_STRING pFormat)
1038 ULONG esize, maxsize;
1040 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
1042 maxsize = *(USHORT *)&pFormat[2];
1044 SizeVariance(pStubMsg);
1046 if (*pFormat == RPC_FC_CSTRING)
1048 ULONG i;
1049 const char *str = (const char *)pMemory;
1050 for (i = 0; i < maxsize && *str; i++, str++)
1052 TRACE("string=%s\n", debugstr_an(str, i));
1053 pStubMsg->ActualCount = i + 1;
1054 esize = 1;
1056 else if (*pFormat == RPC_FC_WSTRING)
1058 ULONG i;
1059 const WCHAR *str = (const WCHAR *)pMemory;
1060 for (i = 0; i < maxsize && *str; i++, str++)
1062 TRACE("string=%s\n", debugstr_wn(str, i));
1063 pStubMsg->ActualCount = i + 1;
1064 esize = 2;
1066 else
1068 ERR("Unhandled string type: %#x\n", *pFormat);
1069 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1072 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
1075 /***********************************************************************
1076 * NdrNonConformantStringMemorySize [RPCRT4.@]
1078 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1079 PFORMAT_STRING pFormat)
1081 ULONG bufsize, memsize, esize, maxsize;
1083 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
1085 maxsize = *(USHORT *)&pFormat[2];
1087 ReadVariance(pStubMsg, NULL, maxsize);
1089 if (pStubMsg->Offset)
1091 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1092 RpcRaiseException(RPC_S_INVALID_BOUND);
1095 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1096 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1097 else
1099 ERR("Unhandled string type: %#x\n", *pFormat);
1100 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1103 memsize = esize * maxsize;
1104 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1106 validate_string_data(pStubMsg, bufsize, esize);
1108 safe_buffer_increment(pStubMsg, bufsize);
1109 pStubMsg->MemorySize += memsize;
1111 return pStubMsg->MemorySize;
1114 static inline void dump_pointer_attr(unsigned char attr)
1116 if (attr & RPC_FC_P_ALLOCALLNODES)
1117 TRACE(" RPC_FC_P_ALLOCALLNODES");
1118 if (attr & RPC_FC_P_DONTFREE)
1119 TRACE(" RPC_FC_P_DONTFREE");
1120 if (attr & RPC_FC_P_ONSTACK)
1121 TRACE(" RPC_FC_P_ONSTACK");
1122 if (attr & RPC_FC_P_SIMPLEPOINTER)
1123 TRACE(" RPC_FC_P_SIMPLEPOINTER");
1124 if (attr & RPC_FC_P_DEREF)
1125 TRACE(" RPC_FC_P_DEREF");
1126 TRACE("\n");
1129 /***********************************************************************
1130 * PointerMarshall [internal]
1132 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1133 unsigned char *Buffer,
1134 unsigned char *Pointer,
1135 PFORMAT_STRING pFormat)
1137 unsigned type = pFormat[0], attr = pFormat[1];
1138 PFORMAT_STRING desc;
1139 NDR_MARSHALL m;
1140 ULONG pointer_id;
1141 int pointer_needs_marshaling;
1143 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
1144 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1145 pFormat += 2;
1146 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1147 else desc = pFormat + *(const SHORT*)pFormat;
1149 switch (type) {
1150 case RPC_FC_RP: /* ref pointer (always non-null) */
1151 if (!Pointer)
1153 ERR("NULL ref pointer is not allowed\n");
1154 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1156 pointer_needs_marshaling = 1;
1157 break;
1158 case RPC_FC_UP: /* unique pointer */
1159 case RPC_FC_OP: /* object pointer - same as unique here */
1160 if (Pointer)
1161 pointer_needs_marshaling = 1;
1162 else
1163 pointer_needs_marshaling = 0;
1164 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
1165 TRACE("writing 0x%08x to buffer\n", pointer_id);
1166 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1167 break;
1168 case RPC_FC_FP:
1169 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
1170 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
1171 TRACE("writing 0x%08x to buffer\n", pointer_id);
1172 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1173 break;
1174 default:
1175 FIXME("unhandled ptr type=%02x\n", type);
1176 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1177 return;
1180 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
1182 if (pointer_needs_marshaling) {
1183 if (attr & RPC_FC_P_DEREF) {
1184 Pointer = *(unsigned char**)Pointer;
1185 TRACE("deref => %p\n", Pointer);
1187 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1188 if (m) m(pStubMsg, Pointer, desc);
1189 else FIXME("no marshaller for data type=%02x\n", *desc);
1192 STD_OVERFLOW_CHECK(pStubMsg);
1195 /***********************************************************************
1196 * PointerUnmarshall [internal]
1198 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1199 unsigned char *Buffer,
1200 unsigned char **pPointer,
1201 unsigned char *pSrcPointer,
1202 PFORMAT_STRING pFormat,
1203 unsigned char fMustAlloc)
1205 unsigned type = pFormat[0], attr = pFormat[1];
1206 PFORMAT_STRING desc;
1207 NDR_UNMARSHALL m;
1208 DWORD pointer_id = 0;
1209 int pointer_needs_unmarshaling;
1211 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
1212 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1213 pFormat += 2;
1214 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1215 else desc = pFormat + *(const SHORT*)pFormat;
1217 switch (type) {
1218 case RPC_FC_RP: /* ref pointer (always non-null) */
1219 pointer_needs_unmarshaling = 1;
1220 break;
1221 case RPC_FC_UP: /* unique pointer */
1222 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1223 TRACE("pointer_id is 0x%08x\n", pointer_id);
1224 if (pointer_id)
1225 pointer_needs_unmarshaling = 1;
1226 else {
1227 *pPointer = NULL;
1228 pointer_needs_unmarshaling = 0;
1230 break;
1231 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1232 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1233 TRACE("pointer_id is 0x%08x\n", pointer_id);
1234 if (!fMustAlloc && pSrcPointer)
1236 FIXME("free object pointer %p\n", pSrcPointer);
1237 fMustAlloc = TRUE;
1239 if (pointer_id)
1240 pointer_needs_unmarshaling = 1;
1241 else
1242 pointer_needs_unmarshaling = 0;
1243 break;
1244 case RPC_FC_FP:
1245 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1246 TRACE("pointer_id is 0x%08x\n", pointer_id);
1247 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1248 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1249 break;
1250 default:
1251 FIXME("unhandled ptr type=%02x\n", type);
1252 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1253 return;
1256 if (pointer_needs_unmarshaling) {
1257 unsigned char *base_ptr_val = *pPointer;
1258 unsigned char **current_ptr = pPointer;
1259 if (pStubMsg->IsClient) {
1260 TRACE("client\n");
1261 /* if we aren't forcing allocation of memory then try to use the existing
1262 * (source) pointer to unmarshall the data into so that [in,out]
1263 * parameters behave correctly. it doesn't matter if the parameter is
1264 * [out] only since in that case the pointer will be NULL. we force
1265 * allocation when the source pointer is NULL here instead of in the type
1266 * unmarshalling routine for the benefit of the deref code below */
1267 if (!fMustAlloc) {
1268 if (pSrcPointer) {
1269 TRACE("setting *pPointer to %p\n", pSrcPointer);
1270 *pPointer = base_ptr_val = pSrcPointer;
1271 } else
1272 fMustAlloc = TRUE;
1274 } else {
1275 TRACE("server\n");
1276 /* the memory in a stub is never initialised, so we have to work out here
1277 * whether we have to initialise it so we can use the optimisation of
1278 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1279 * TRUE. */
1280 if (attr & RPC_FC_P_DEREF) {
1281 fMustAlloc = TRUE;
1282 } else {
1283 base_ptr_val = NULL;
1284 *current_ptr = NULL;
1288 if (attr & RPC_FC_P_ALLOCALLNODES)
1289 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1291 if (attr & RPC_FC_P_DEREF) {
1292 if (fMustAlloc) {
1293 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1294 *pPointer = base_ptr_val;
1295 current_ptr = (unsigned char **)base_ptr_val;
1296 } else
1297 current_ptr = *(unsigned char***)current_ptr;
1298 TRACE("deref => %p\n", current_ptr);
1299 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1301 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1302 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1303 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1305 if (type == RPC_FC_FP)
1306 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1307 base_ptr_val);
1310 TRACE("pointer=%p\n", *pPointer);
1313 /***********************************************************************
1314 * PointerBufferSize [internal]
1316 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1317 unsigned char *Pointer,
1318 PFORMAT_STRING pFormat)
1320 unsigned type = pFormat[0], attr = pFormat[1];
1321 PFORMAT_STRING desc;
1322 NDR_BUFFERSIZE m;
1323 int pointer_needs_sizing;
1324 ULONG pointer_id;
1326 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1327 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1328 pFormat += 2;
1329 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1330 else desc = pFormat + *(const SHORT*)pFormat;
1332 switch (type) {
1333 case RPC_FC_RP: /* ref pointer (always non-null) */
1334 if (!Pointer)
1336 ERR("NULL ref pointer is not allowed\n");
1337 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1339 break;
1340 case RPC_FC_OP:
1341 case RPC_FC_UP:
1342 /* NULL pointer has no further representation */
1343 if (!Pointer)
1344 return;
1345 break;
1346 case RPC_FC_FP:
1347 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1348 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1349 if (!pointer_needs_sizing)
1350 return;
1351 break;
1352 default:
1353 FIXME("unhandled ptr type=%02x\n", type);
1354 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1355 return;
1358 if (attr & RPC_FC_P_DEREF) {
1359 Pointer = *(unsigned char**)Pointer;
1360 TRACE("deref => %p\n", Pointer);
1363 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1364 if (m) m(pStubMsg, Pointer, desc);
1365 else FIXME("no buffersizer for data type=%02x\n", *desc);
1368 /***********************************************************************
1369 * PointerMemorySize [internal]
1371 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1372 unsigned char *Buffer,
1373 PFORMAT_STRING pFormat)
1375 unsigned type = pFormat[0], attr = pFormat[1];
1376 PFORMAT_STRING desc;
1377 NDR_MEMORYSIZE m;
1378 DWORD pointer_id = 0;
1379 int pointer_needs_sizing;
1381 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1382 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1383 pFormat += 2;
1384 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1385 else desc = pFormat + *(const SHORT*)pFormat;
1387 switch (type) {
1388 case RPC_FC_RP: /* ref pointer (always non-null) */
1389 pointer_needs_sizing = 1;
1390 break;
1391 case RPC_FC_UP: /* unique pointer */
1392 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1393 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1394 TRACE("pointer_id is 0x%08x\n", pointer_id);
1395 if (pointer_id)
1396 pointer_needs_sizing = 1;
1397 else
1398 pointer_needs_sizing = 0;
1399 break;
1400 case RPC_FC_FP:
1402 void *pointer;
1403 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1404 TRACE("pointer_id is 0x%08x\n", pointer_id);
1405 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1406 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1407 break;
1409 default:
1410 FIXME("unhandled ptr type=%02x\n", type);
1411 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1412 return 0;
1415 if (attr & RPC_FC_P_DEREF) {
1416 TRACE("deref\n");
1419 if (pointer_needs_sizing) {
1420 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1421 if (m) m(pStubMsg, desc);
1422 else FIXME("no memorysizer for data type=%02x\n", *desc);
1425 return pStubMsg->MemorySize;
1428 /***********************************************************************
1429 * PointerFree [internal]
1431 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1432 unsigned char *Pointer,
1433 PFORMAT_STRING pFormat)
1435 unsigned type = pFormat[0], attr = pFormat[1];
1436 PFORMAT_STRING desc;
1437 NDR_FREE m;
1438 unsigned char *current_pointer = Pointer;
1440 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1441 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1442 if (attr & RPC_FC_P_DONTFREE) return;
1443 pFormat += 2;
1444 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1445 else desc = pFormat + *(const SHORT*)pFormat;
1447 if (!Pointer) return;
1449 if (type == RPC_FC_FP) {
1450 int pointer_needs_freeing = NdrFullPointerFree(
1451 pStubMsg->FullPtrXlatTables, Pointer);
1452 if (!pointer_needs_freeing)
1453 return;
1456 if (attr & RPC_FC_P_DEREF) {
1457 current_pointer = *(unsigned char**)Pointer;
1458 TRACE("deref => %p\n", current_pointer);
1461 m = NdrFreer[*desc & NDR_TABLE_MASK];
1462 if (m) m(pStubMsg, current_pointer, desc);
1464 /* this check stops us from trying to free buffer memory. we don't have to
1465 * worry about clients, since they won't call this function.
1466 * we don't have to check for the buffer being reallocated because
1467 * BufferStart and BufferEnd won't be reset when allocating memory for
1468 * sending the response. we don't have to check for the new buffer here as
1469 * it won't be used a type memory, only for buffer memory */
1470 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1471 goto notfree;
1473 if (attr & RPC_FC_P_ONSTACK) {
1474 TRACE("not freeing stack ptr %p\n", Pointer);
1475 return;
1477 TRACE("freeing %p\n", Pointer);
1478 NdrFree(pStubMsg, Pointer);
1479 return;
1480 notfree:
1481 TRACE("not freeing %p\n", Pointer);
1484 /***********************************************************************
1485 * EmbeddedPointerMarshall
1487 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1488 unsigned char *pMemory,
1489 PFORMAT_STRING pFormat)
1491 unsigned char *Mark = pStubMsg->BufferMark;
1492 unsigned rep, count, stride;
1493 unsigned i;
1494 unsigned char *saved_buffer = NULL;
1496 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1498 if (*pFormat != RPC_FC_PP) return NULL;
1499 pFormat += 2;
1501 if (pStubMsg->PointerBufferMark)
1503 saved_buffer = pStubMsg->Buffer;
1504 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1505 pStubMsg->PointerBufferMark = NULL;
1508 while (pFormat[0] != RPC_FC_END) {
1509 switch (pFormat[0]) {
1510 default:
1511 FIXME("unknown repeat type %d\n", pFormat[0]);
1512 case RPC_FC_NO_REPEAT:
1513 rep = 1;
1514 stride = 0;
1515 count = 1;
1516 pFormat += 2;
1517 break;
1518 case RPC_FC_FIXED_REPEAT:
1519 rep = *(const WORD*)&pFormat[2];
1520 stride = *(const WORD*)&pFormat[4];
1521 count = *(const WORD*)&pFormat[8];
1522 pFormat += 10;
1523 break;
1524 case RPC_FC_VARIABLE_REPEAT:
1525 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1526 stride = *(const WORD*)&pFormat[2];
1527 count = *(const WORD*)&pFormat[6];
1528 pFormat += 8;
1529 break;
1531 for (i = 0; i < rep; i++) {
1532 PFORMAT_STRING info = pFormat;
1533 unsigned char *membase = pMemory + (i * stride);
1534 unsigned char *bufbase = Mark + (i * stride);
1535 unsigned u;
1537 for (u=0; u<count; u++,info+=8) {
1538 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1539 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1540 unsigned char *saved_memory = pStubMsg->Memory;
1542 pStubMsg->Memory = pMemory;
1543 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1544 pStubMsg->Memory = saved_memory;
1547 pFormat += 8 * count;
1550 if (saved_buffer)
1552 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1553 pStubMsg->Buffer = saved_buffer;
1556 STD_OVERFLOW_CHECK(pStubMsg);
1558 return NULL;
1561 /***********************************************************************
1562 * EmbeddedPointerUnmarshall
1564 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1565 unsigned char *pDstBuffer,
1566 unsigned char *pSrcMemoryPtrs,
1567 PFORMAT_STRING pFormat,
1568 unsigned char fMustAlloc)
1570 unsigned char *Mark = pStubMsg->BufferMark;
1571 unsigned rep, count, stride;
1572 unsigned i;
1573 unsigned char *saved_buffer = NULL;
1575 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1577 if (*pFormat != RPC_FC_PP) return NULL;
1578 pFormat += 2;
1580 if (pStubMsg->PointerBufferMark)
1582 saved_buffer = pStubMsg->Buffer;
1583 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1584 pStubMsg->PointerBufferMark = NULL;
1587 while (pFormat[0] != RPC_FC_END) {
1588 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1589 switch (pFormat[0]) {
1590 default:
1591 FIXME("unknown repeat type %d\n", pFormat[0]);
1592 case RPC_FC_NO_REPEAT:
1593 rep = 1;
1594 stride = 0;
1595 count = 1;
1596 pFormat += 2;
1597 break;
1598 case RPC_FC_FIXED_REPEAT:
1599 rep = *(const WORD*)&pFormat[2];
1600 stride = *(const WORD*)&pFormat[4];
1601 count = *(const WORD*)&pFormat[8];
1602 pFormat += 10;
1603 break;
1604 case RPC_FC_VARIABLE_REPEAT:
1605 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1606 stride = *(const WORD*)&pFormat[2];
1607 count = *(const WORD*)&pFormat[6];
1608 pFormat += 8;
1609 break;
1611 for (i = 0; i < rep; i++) {
1612 PFORMAT_STRING info = pFormat;
1613 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1614 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1615 unsigned char *bufbase = Mark + (i * stride);
1616 unsigned u;
1618 for (u=0; u<count; u++,info+=8) {
1619 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1620 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1621 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1622 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1625 pFormat += 8 * count;
1628 if (saved_buffer)
1630 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1631 pStubMsg->Buffer = saved_buffer;
1634 return NULL;
1637 /***********************************************************************
1638 * EmbeddedPointerBufferSize
1640 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1641 unsigned char *pMemory,
1642 PFORMAT_STRING pFormat)
1644 unsigned rep, count, stride;
1645 unsigned i;
1646 ULONG saved_buffer_length = 0;
1648 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1650 if (pStubMsg->IgnoreEmbeddedPointers) return;
1652 if (*pFormat != RPC_FC_PP) return;
1653 pFormat += 2;
1655 if (pStubMsg->PointerLength)
1657 saved_buffer_length = pStubMsg->BufferLength;
1658 pStubMsg->BufferLength = pStubMsg->PointerLength;
1659 pStubMsg->PointerLength = 0;
1662 while (pFormat[0] != RPC_FC_END) {
1663 switch (pFormat[0]) {
1664 default:
1665 FIXME("unknown repeat type %d\n", pFormat[0]);
1666 case RPC_FC_NO_REPEAT:
1667 rep = 1;
1668 stride = 0;
1669 count = 1;
1670 pFormat += 2;
1671 break;
1672 case RPC_FC_FIXED_REPEAT:
1673 rep = *(const WORD*)&pFormat[2];
1674 stride = *(const WORD*)&pFormat[4];
1675 count = *(const WORD*)&pFormat[8];
1676 pFormat += 10;
1677 break;
1678 case RPC_FC_VARIABLE_REPEAT:
1679 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1680 stride = *(const WORD*)&pFormat[2];
1681 count = *(const WORD*)&pFormat[6];
1682 pFormat += 8;
1683 break;
1685 for (i = 0; i < rep; i++) {
1686 PFORMAT_STRING info = pFormat;
1687 unsigned char *membase = pMemory + (i * stride);
1688 unsigned u;
1690 for (u=0; u<count; u++,info+=8) {
1691 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1692 unsigned char *saved_memory = pStubMsg->Memory;
1694 pStubMsg->Memory = pMemory;
1695 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1696 pStubMsg->Memory = saved_memory;
1699 pFormat += 8 * count;
1702 if (saved_buffer_length)
1704 pStubMsg->PointerLength = pStubMsg->BufferLength;
1705 pStubMsg->BufferLength = saved_buffer_length;
1709 /***********************************************************************
1710 * EmbeddedPointerMemorySize [internal]
1712 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1713 PFORMAT_STRING pFormat)
1715 unsigned char *Mark = pStubMsg->BufferMark;
1716 unsigned rep, count, stride;
1717 unsigned i;
1718 unsigned char *saved_buffer = NULL;
1720 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1722 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1724 if (pStubMsg->PointerBufferMark)
1726 saved_buffer = pStubMsg->Buffer;
1727 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1728 pStubMsg->PointerBufferMark = NULL;
1731 if (*pFormat != RPC_FC_PP) return 0;
1732 pFormat += 2;
1734 while (pFormat[0] != RPC_FC_END) {
1735 switch (pFormat[0]) {
1736 default:
1737 FIXME("unknown repeat type %d\n", pFormat[0]);
1738 case RPC_FC_NO_REPEAT:
1739 rep = 1;
1740 stride = 0;
1741 count = 1;
1742 pFormat += 2;
1743 break;
1744 case RPC_FC_FIXED_REPEAT:
1745 rep = *(const WORD*)&pFormat[2];
1746 stride = *(const WORD*)&pFormat[4];
1747 count = *(const WORD*)&pFormat[8];
1748 pFormat += 10;
1749 break;
1750 case RPC_FC_VARIABLE_REPEAT:
1751 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1752 stride = *(const WORD*)&pFormat[2];
1753 count = *(const WORD*)&pFormat[6];
1754 pFormat += 8;
1755 break;
1757 for (i = 0; i < rep; i++) {
1758 PFORMAT_STRING info = pFormat;
1759 unsigned char *bufbase = Mark + (i * stride);
1760 unsigned u;
1761 for (u=0; u<count; u++,info+=8) {
1762 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1763 PointerMemorySize(pStubMsg, bufptr, info+4);
1766 pFormat += 8 * count;
1769 if (saved_buffer)
1771 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1772 pStubMsg->Buffer = saved_buffer;
1775 return 0;
1778 /***********************************************************************
1779 * EmbeddedPointerFree [internal]
1781 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1782 unsigned char *pMemory,
1783 PFORMAT_STRING pFormat)
1785 unsigned rep, count, stride;
1786 unsigned i;
1788 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1789 if (*pFormat != RPC_FC_PP) return;
1790 pFormat += 2;
1792 while (pFormat[0] != RPC_FC_END) {
1793 switch (pFormat[0]) {
1794 default:
1795 FIXME("unknown repeat type %d\n", pFormat[0]);
1796 case RPC_FC_NO_REPEAT:
1797 rep = 1;
1798 stride = 0;
1799 count = 1;
1800 pFormat += 2;
1801 break;
1802 case RPC_FC_FIXED_REPEAT:
1803 rep = *(const WORD*)&pFormat[2];
1804 stride = *(const WORD*)&pFormat[4];
1805 count = *(const WORD*)&pFormat[8];
1806 pFormat += 10;
1807 break;
1808 case RPC_FC_VARIABLE_REPEAT:
1809 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1810 stride = *(const WORD*)&pFormat[2];
1811 count = *(const WORD*)&pFormat[6];
1812 pFormat += 8;
1813 break;
1815 for (i = 0; i < rep; i++) {
1816 PFORMAT_STRING info = pFormat;
1817 unsigned char *membase = pMemory + (i * stride);
1818 unsigned u;
1820 for (u=0; u<count; u++,info+=8) {
1821 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1822 unsigned char *saved_memory = pStubMsg->Memory;
1824 pStubMsg->Memory = pMemory;
1825 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1826 pStubMsg->Memory = saved_memory;
1829 pFormat += 8 * count;
1833 /***********************************************************************
1834 * NdrPointerMarshall [RPCRT4.@]
1836 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1837 unsigned char *pMemory,
1838 PFORMAT_STRING pFormat)
1840 unsigned char *Buffer;
1842 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1844 /* Increment the buffer here instead of in PointerMarshall,
1845 * as that is used by embedded pointers which already handle the incrementing
1846 * the buffer, and shouldn't write any additional pointer data to the wire */
1847 if (*pFormat != RPC_FC_RP)
1849 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1850 Buffer = pStubMsg->Buffer;
1851 safe_buffer_increment(pStubMsg, 4);
1853 else
1854 Buffer = pStubMsg->Buffer;
1856 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1858 return NULL;
1861 /***********************************************************************
1862 * NdrPointerUnmarshall [RPCRT4.@]
1864 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1865 unsigned char **ppMemory,
1866 PFORMAT_STRING pFormat,
1867 unsigned char fMustAlloc)
1869 unsigned char *Buffer;
1871 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1873 /* Increment the buffer here instead of in PointerUnmarshall,
1874 * as that is used by embedded pointers which already handle the incrementing
1875 * the buffer, and shouldn't read any additional pointer data from the
1876 * buffer */
1877 if (*pFormat != RPC_FC_RP)
1879 ALIGN_POINTER(pStubMsg->Buffer, 4);
1880 Buffer = pStubMsg->Buffer;
1881 safe_buffer_increment(pStubMsg, 4);
1883 else
1884 Buffer = pStubMsg->Buffer;
1886 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1888 return NULL;
1891 /***********************************************************************
1892 * NdrPointerBufferSize [RPCRT4.@]
1894 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1895 unsigned char *pMemory,
1896 PFORMAT_STRING pFormat)
1898 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1900 /* Increment the buffer length here instead of in PointerBufferSize,
1901 * as that is used by embedded pointers which already handle the buffer
1902 * length, and shouldn't write anything more to the wire */
1903 if (*pFormat != RPC_FC_RP)
1905 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1906 safe_buffer_length_increment(pStubMsg, 4);
1909 PointerBufferSize(pStubMsg, pMemory, pFormat);
1912 /***********************************************************************
1913 * NdrPointerMemorySize [RPCRT4.@]
1915 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1916 PFORMAT_STRING pFormat)
1918 /* unsigned size = *(LPWORD)(pFormat+2); */
1919 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1920 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1921 return 0;
1924 /***********************************************************************
1925 * NdrPointerFree [RPCRT4.@]
1927 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1928 unsigned char *pMemory,
1929 PFORMAT_STRING pFormat)
1931 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1932 PointerFree(pStubMsg, pMemory, pFormat);
1935 /***********************************************************************
1936 * NdrSimpleTypeMarshall [RPCRT4.@]
1938 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1939 unsigned char FormatChar )
1941 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1944 /***********************************************************************
1945 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1947 * Unmarshall a base type.
1949 * NOTES
1950 * Doesn't check that the buffer is long enough before copying, so the caller
1951 * should do this.
1953 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1954 unsigned char FormatChar )
1956 #define BASE_TYPE_UNMARSHALL(type) \
1957 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1958 TRACE("pMemory: %p\n", pMemory); \
1959 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1960 pStubMsg->Buffer += sizeof(type);
1962 switch(FormatChar)
1964 case RPC_FC_BYTE:
1965 case RPC_FC_CHAR:
1966 case RPC_FC_SMALL:
1967 case RPC_FC_USMALL:
1968 BASE_TYPE_UNMARSHALL(UCHAR);
1969 TRACE("value: 0x%02x\n", *pMemory);
1970 break;
1971 case RPC_FC_WCHAR:
1972 case RPC_FC_SHORT:
1973 case RPC_FC_USHORT:
1974 BASE_TYPE_UNMARSHALL(USHORT);
1975 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1976 break;
1977 case RPC_FC_LONG:
1978 case RPC_FC_ULONG:
1979 case RPC_FC_ERROR_STATUS_T:
1980 case RPC_FC_ENUM32:
1981 BASE_TYPE_UNMARSHALL(ULONG);
1982 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1983 break;
1984 case RPC_FC_FLOAT:
1985 BASE_TYPE_UNMARSHALL(float);
1986 TRACE("value: %f\n", *(float *)pMemory);
1987 break;
1988 case RPC_FC_DOUBLE:
1989 BASE_TYPE_UNMARSHALL(double);
1990 TRACE("value: %f\n", *(double *)pMemory);
1991 break;
1992 case RPC_FC_HYPER:
1993 BASE_TYPE_UNMARSHALL(ULONGLONG);
1994 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1995 break;
1996 case RPC_FC_ENUM16:
1997 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1998 TRACE("pMemory: %p\n", pMemory);
1999 /* 16-bits on the wire, but int in memory */
2000 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
2001 pStubMsg->Buffer += sizeof(USHORT);
2002 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
2003 break;
2004 case RPC_FC_IGNORE:
2005 break;
2006 default:
2007 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
2009 #undef BASE_TYPE_UNMARSHALL
2012 /***********************************************************************
2013 * NdrSimpleStructMarshall [RPCRT4.@]
2015 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2016 unsigned char *pMemory,
2017 PFORMAT_STRING pFormat)
2019 unsigned size = *(const WORD*)(pFormat+2);
2020 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2022 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2024 pStubMsg->BufferMark = pStubMsg->Buffer;
2025 safe_copy_to_buffer(pStubMsg, pMemory, size);
2027 if (pFormat[0] != RPC_FC_STRUCT)
2028 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
2030 return NULL;
2033 /***********************************************************************
2034 * NdrSimpleStructUnmarshall [RPCRT4.@]
2036 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2037 unsigned char **ppMemory,
2038 PFORMAT_STRING pFormat,
2039 unsigned char fMustAlloc)
2041 unsigned size = *(const WORD*)(pFormat+2);
2042 unsigned char *saved_buffer;
2043 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2045 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2047 if (fMustAlloc)
2048 *ppMemory = NdrAllocate(pStubMsg, size);
2049 else
2051 if (!pStubMsg->IsClient && !*ppMemory)
2052 /* for servers, we just point straight into the RPC buffer */
2053 *ppMemory = pStubMsg->Buffer;
2056 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2057 safe_buffer_increment(pStubMsg, size);
2058 if (pFormat[0] == RPC_FC_PSTRUCT)
2059 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
2061 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2062 if (*ppMemory != saved_buffer)
2063 memcpy(*ppMemory, saved_buffer, size);
2065 return NULL;
2068 /***********************************************************************
2069 * NdrSimpleStructBufferSize [RPCRT4.@]
2071 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2072 unsigned char *pMemory,
2073 PFORMAT_STRING pFormat)
2075 unsigned size = *(const WORD*)(pFormat+2);
2076 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2078 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2080 safe_buffer_length_increment(pStubMsg, size);
2081 if (pFormat[0] != RPC_FC_STRUCT)
2082 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
2085 /***********************************************************************
2086 * NdrSimpleStructMemorySize [RPCRT4.@]
2088 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2089 PFORMAT_STRING pFormat)
2091 unsigned short size = *(const WORD *)(pFormat+2);
2093 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2095 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2096 pStubMsg->MemorySize += size;
2097 safe_buffer_increment(pStubMsg, size);
2099 if (pFormat[0] != RPC_FC_STRUCT)
2100 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
2101 return pStubMsg->MemorySize;
2104 /***********************************************************************
2105 * NdrSimpleStructFree [RPCRT4.@]
2107 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2108 unsigned char *pMemory,
2109 PFORMAT_STRING pFormat)
2111 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2112 if (pFormat[0] != RPC_FC_STRUCT)
2113 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
2117 #include "pshpack1.h"
2118 typedef struct
2120 unsigned char type;
2121 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2122 ULONG low_value;
2123 ULONG high_value;
2124 } NDR_RANGE;
2125 #include "poppack.h"
2127 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2128 PFORMAT_STRING pFormat)
2130 switch (*pFormat) {
2131 case RPC_FC_STRUCT:
2132 case RPC_FC_PSTRUCT:
2133 case RPC_FC_CSTRUCT:
2134 case RPC_FC_BOGUS_STRUCT:
2135 case RPC_FC_SMFARRAY:
2136 case RPC_FC_SMVARRAY:
2137 case RPC_FC_CSTRING:
2138 return *(const WORD*)&pFormat[2];
2139 case RPC_FC_USER_MARSHAL:
2140 return *(const WORD*)&pFormat[4];
2141 case RPC_FC_RANGE: {
2142 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2143 case RPC_FC_BYTE:
2144 case RPC_FC_CHAR:
2145 case RPC_FC_SMALL:
2146 case RPC_FC_USMALL:
2147 return sizeof(UCHAR);
2148 case RPC_FC_WCHAR:
2149 case RPC_FC_SHORT:
2150 case RPC_FC_USHORT:
2151 return sizeof(USHORT);
2152 case RPC_FC_LONG:
2153 case RPC_FC_ULONG:
2154 case RPC_FC_ENUM32:
2155 return sizeof(ULONG);
2156 case RPC_FC_FLOAT:
2157 return sizeof(float);
2158 case RPC_FC_DOUBLE:
2159 return sizeof(double);
2160 case RPC_FC_HYPER:
2161 return sizeof(ULONGLONG);
2162 case RPC_FC_ERROR_STATUS_T:
2163 return sizeof(error_status_t);
2164 case RPC_FC_ENUM16:
2165 return sizeof(UINT);
2166 default:
2167 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2168 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2171 case RPC_FC_NON_ENCAPSULATED_UNION:
2172 pFormat += 2;
2173 if (pStubMsg->fHasNewCorrDesc)
2174 pFormat += 6;
2175 else
2176 pFormat += 4;
2178 pFormat += *(const SHORT*)pFormat;
2179 return *(const SHORT*)pFormat;
2180 case RPC_FC_IP:
2181 return sizeof(void *);
2182 case RPC_FC_WSTRING:
2183 return *(const WORD*)&pFormat[2] * 2;
2184 default:
2185 FIXME("unhandled embedded type %02x\n", *pFormat);
2187 return 0;
2191 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2192 PFORMAT_STRING pFormat)
2194 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2196 if (!m)
2198 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2199 return 0;
2202 return m(pStubMsg, pFormat);
2206 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2207 unsigned char *pMemory,
2208 PFORMAT_STRING pFormat,
2209 PFORMAT_STRING pPointer)
2211 PFORMAT_STRING desc;
2212 NDR_MARSHALL m;
2213 unsigned long size;
2215 while (*pFormat != RPC_FC_END) {
2216 switch (*pFormat) {
2217 case RPC_FC_BYTE:
2218 case RPC_FC_CHAR:
2219 case RPC_FC_SMALL:
2220 case RPC_FC_USMALL:
2221 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2222 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2223 pMemory += 1;
2224 break;
2225 case RPC_FC_WCHAR:
2226 case RPC_FC_SHORT:
2227 case RPC_FC_USHORT:
2228 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2229 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2230 pMemory += 2;
2231 break;
2232 case RPC_FC_ENUM16:
2233 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2234 if (32767 < *(DWORD*)pMemory)
2235 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2236 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2237 pMemory += 4;
2238 break;
2239 case RPC_FC_LONG:
2240 case RPC_FC_ULONG:
2241 case RPC_FC_ENUM32:
2242 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2243 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2244 pMemory += 4;
2245 break;
2246 case RPC_FC_HYPER:
2247 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2248 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2249 pMemory += 8;
2250 break;
2251 case RPC_FC_POINTER:
2253 unsigned char *saved_buffer;
2254 int pointer_buffer_mark_set = 0;
2255 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2256 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2257 saved_buffer = pStubMsg->Buffer;
2258 if (pStubMsg->PointerBufferMark)
2260 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2261 pStubMsg->PointerBufferMark = NULL;
2262 pointer_buffer_mark_set = 1;
2264 else
2265 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2266 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2267 if (pointer_buffer_mark_set)
2269 STD_OVERFLOW_CHECK(pStubMsg);
2270 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2271 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2273 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2274 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2275 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2277 pStubMsg->Buffer = saved_buffer + 4;
2279 pPointer += 4;
2280 pMemory += 4;
2281 break;
2283 case RPC_FC_ALIGNM4:
2284 ALIGN_POINTER(pMemory, 4);
2285 break;
2286 case RPC_FC_ALIGNM8:
2287 ALIGN_POINTER(pMemory, 8);
2288 break;
2289 case RPC_FC_STRUCTPAD1:
2290 case RPC_FC_STRUCTPAD2:
2291 case RPC_FC_STRUCTPAD3:
2292 case RPC_FC_STRUCTPAD4:
2293 case RPC_FC_STRUCTPAD5:
2294 case RPC_FC_STRUCTPAD6:
2295 case RPC_FC_STRUCTPAD7:
2296 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2297 break;
2298 case RPC_FC_EMBEDDED_COMPLEX:
2299 pMemory += pFormat[1];
2300 pFormat += 2;
2301 desc = pFormat + *(const SHORT*)pFormat;
2302 size = EmbeddedComplexSize(pStubMsg, desc);
2303 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2304 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2305 if (m)
2307 /* for some reason interface pointers aren't generated as
2308 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2309 * they still need the derefencing treatment that pointers are
2310 * given */
2311 if (*desc == RPC_FC_IP)
2312 m(pStubMsg, *(unsigned char **)pMemory, desc);
2313 else
2314 m(pStubMsg, pMemory, desc);
2316 else FIXME("no marshaller for embedded type %02x\n", *desc);
2317 pMemory += size;
2318 pFormat += 2;
2319 continue;
2320 case RPC_FC_PAD:
2321 break;
2322 default:
2323 FIXME("unhandled format 0x%02x\n", *pFormat);
2325 pFormat++;
2328 return pMemory;
2331 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2332 unsigned char *pMemory,
2333 PFORMAT_STRING pFormat,
2334 PFORMAT_STRING pPointer,
2335 unsigned char fMustAlloc)
2337 PFORMAT_STRING desc;
2338 NDR_UNMARSHALL m;
2339 unsigned long size;
2341 while (*pFormat != RPC_FC_END) {
2342 switch (*pFormat) {
2343 case RPC_FC_BYTE:
2344 case RPC_FC_CHAR:
2345 case RPC_FC_SMALL:
2346 case RPC_FC_USMALL:
2347 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2348 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2349 pMemory += 1;
2350 break;
2351 case RPC_FC_WCHAR:
2352 case RPC_FC_SHORT:
2353 case RPC_FC_USHORT:
2354 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2355 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2356 pMemory += 2;
2357 break;
2358 case RPC_FC_ENUM16:
2359 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2360 *(DWORD*)pMemory &= 0xffff;
2361 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2362 if (32767 < *(DWORD*)pMemory)
2363 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2364 pMemory += 4;
2365 break;
2366 case RPC_FC_LONG:
2367 case RPC_FC_ULONG:
2368 case RPC_FC_ENUM32:
2369 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2370 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2371 pMemory += 4;
2372 break;
2373 case RPC_FC_HYPER:
2374 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2375 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2376 pMemory += 8;
2377 break;
2378 case RPC_FC_POINTER:
2380 unsigned char *saved_buffer;
2381 int pointer_buffer_mark_set = 0;
2382 TRACE("pointer => %p\n", pMemory);
2383 ALIGN_POINTER(pStubMsg->Buffer, 4);
2384 saved_buffer = pStubMsg->Buffer;
2385 if (pStubMsg->PointerBufferMark)
2387 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2388 pStubMsg->PointerBufferMark = NULL;
2389 pointer_buffer_mark_set = 1;
2391 else
2392 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2394 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2395 if (pointer_buffer_mark_set)
2397 STD_OVERFLOW_CHECK(pStubMsg);
2398 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2399 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2401 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2402 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2403 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2405 pStubMsg->Buffer = saved_buffer + 4;
2407 pPointer += 4;
2408 pMemory += 4;
2409 break;
2411 case RPC_FC_ALIGNM4:
2412 ALIGN_POINTER_CLEAR(pMemory, 4);
2413 break;
2414 case RPC_FC_ALIGNM8:
2415 ALIGN_POINTER_CLEAR(pMemory, 8);
2416 break;
2417 case RPC_FC_STRUCTPAD1:
2418 case RPC_FC_STRUCTPAD2:
2419 case RPC_FC_STRUCTPAD3:
2420 case RPC_FC_STRUCTPAD4:
2421 case RPC_FC_STRUCTPAD5:
2422 case RPC_FC_STRUCTPAD6:
2423 case RPC_FC_STRUCTPAD7:
2424 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2425 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2426 break;
2427 case RPC_FC_EMBEDDED_COMPLEX:
2428 pMemory += pFormat[1];
2429 pFormat += 2;
2430 desc = pFormat + *(const SHORT*)pFormat;
2431 size = EmbeddedComplexSize(pStubMsg, desc);
2432 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2433 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2434 if (m)
2436 /* for some reason interface pointers aren't generated as
2437 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2438 * they still need the derefencing treatment that pointers are
2439 * given */
2440 if (*desc == RPC_FC_IP)
2441 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2442 else
2443 m(pStubMsg, &pMemory, desc, FALSE);
2445 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2446 pMemory += size;
2447 pFormat += 2;
2448 continue;
2449 case RPC_FC_PAD:
2450 break;
2451 default:
2452 FIXME("unhandled format %d\n", *pFormat);
2454 pFormat++;
2457 return pMemory;
2460 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2461 unsigned char *pMemory,
2462 PFORMAT_STRING pFormat,
2463 PFORMAT_STRING pPointer)
2465 PFORMAT_STRING desc;
2466 NDR_BUFFERSIZE m;
2467 unsigned long size;
2469 while (*pFormat != RPC_FC_END) {
2470 switch (*pFormat) {
2471 case RPC_FC_BYTE:
2472 case RPC_FC_CHAR:
2473 case RPC_FC_SMALL:
2474 case RPC_FC_USMALL:
2475 safe_buffer_length_increment(pStubMsg, 1);
2476 pMemory += 1;
2477 break;
2478 case RPC_FC_WCHAR:
2479 case RPC_FC_SHORT:
2480 case RPC_FC_USHORT:
2481 safe_buffer_length_increment(pStubMsg, 2);
2482 pMemory += 2;
2483 break;
2484 case RPC_FC_ENUM16:
2485 safe_buffer_length_increment(pStubMsg, 2);
2486 pMemory += 4;
2487 break;
2488 case RPC_FC_LONG:
2489 case RPC_FC_ULONG:
2490 case RPC_FC_ENUM32:
2491 safe_buffer_length_increment(pStubMsg, 4);
2492 pMemory += 4;
2493 break;
2494 case RPC_FC_HYPER:
2495 safe_buffer_length_increment(pStubMsg, 8);
2496 pMemory += 8;
2497 break;
2498 case RPC_FC_POINTER:
2499 if (!pStubMsg->IgnoreEmbeddedPointers)
2501 int saved_buffer_length = pStubMsg->BufferLength;
2502 pStubMsg->BufferLength = pStubMsg->PointerLength;
2503 pStubMsg->PointerLength = 0;
2504 if(!pStubMsg->BufferLength)
2505 ERR("BufferLength == 0??\n");
2506 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2507 pStubMsg->PointerLength = pStubMsg->BufferLength;
2508 pStubMsg->BufferLength = saved_buffer_length;
2510 safe_buffer_length_increment(pStubMsg, 4);
2511 pPointer += 4;
2512 pMemory += 4;
2513 break;
2514 case RPC_FC_ALIGNM4:
2515 ALIGN_POINTER(pMemory, 4);
2516 break;
2517 case RPC_FC_ALIGNM8:
2518 ALIGN_POINTER(pMemory, 8);
2519 break;
2520 case RPC_FC_STRUCTPAD1:
2521 case RPC_FC_STRUCTPAD2:
2522 case RPC_FC_STRUCTPAD3:
2523 case RPC_FC_STRUCTPAD4:
2524 case RPC_FC_STRUCTPAD5:
2525 case RPC_FC_STRUCTPAD6:
2526 case RPC_FC_STRUCTPAD7:
2527 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2528 break;
2529 case RPC_FC_EMBEDDED_COMPLEX:
2530 pMemory += pFormat[1];
2531 pFormat += 2;
2532 desc = pFormat + *(const SHORT*)pFormat;
2533 size = EmbeddedComplexSize(pStubMsg, desc);
2534 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2535 if (m)
2537 /* for some reason interface pointers aren't generated as
2538 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2539 * they still need the derefencing treatment that pointers are
2540 * given */
2541 if (*desc == RPC_FC_IP)
2542 m(pStubMsg, *(unsigned char **)pMemory, desc);
2543 else
2544 m(pStubMsg, pMemory, desc);
2546 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2547 pMemory += size;
2548 pFormat += 2;
2549 continue;
2550 case RPC_FC_PAD:
2551 break;
2552 default:
2553 FIXME("unhandled format 0x%02x\n", *pFormat);
2555 pFormat++;
2558 return pMemory;
2561 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2562 unsigned char *pMemory,
2563 PFORMAT_STRING pFormat,
2564 PFORMAT_STRING pPointer)
2566 PFORMAT_STRING desc;
2567 NDR_FREE m;
2568 unsigned long size;
2570 while (*pFormat != RPC_FC_END) {
2571 switch (*pFormat) {
2572 case RPC_FC_BYTE:
2573 case RPC_FC_CHAR:
2574 case RPC_FC_SMALL:
2575 case RPC_FC_USMALL:
2576 pMemory += 1;
2577 break;
2578 case RPC_FC_WCHAR:
2579 case RPC_FC_SHORT:
2580 case RPC_FC_USHORT:
2581 pMemory += 2;
2582 break;
2583 case RPC_FC_LONG:
2584 case RPC_FC_ULONG:
2585 case RPC_FC_ENUM16:
2586 case RPC_FC_ENUM32:
2587 pMemory += 4;
2588 break;
2589 case RPC_FC_HYPER:
2590 pMemory += 8;
2591 break;
2592 case RPC_FC_POINTER:
2593 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2594 pPointer += 4;
2595 pMemory += 4;
2596 break;
2597 case RPC_FC_ALIGNM4:
2598 ALIGN_POINTER(pMemory, 4);
2599 break;
2600 case RPC_FC_ALIGNM8:
2601 ALIGN_POINTER(pMemory, 8);
2602 break;
2603 case RPC_FC_STRUCTPAD1:
2604 case RPC_FC_STRUCTPAD2:
2605 case RPC_FC_STRUCTPAD3:
2606 case RPC_FC_STRUCTPAD4:
2607 case RPC_FC_STRUCTPAD5:
2608 case RPC_FC_STRUCTPAD6:
2609 case RPC_FC_STRUCTPAD7:
2610 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2611 break;
2612 case RPC_FC_EMBEDDED_COMPLEX:
2613 pMemory += pFormat[1];
2614 pFormat += 2;
2615 desc = pFormat + *(const SHORT*)pFormat;
2616 size = EmbeddedComplexSize(pStubMsg, desc);
2617 m = NdrFreer[*desc & NDR_TABLE_MASK];
2618 if (m)
2620 /* for some reason interface pointers aren't generated as
2621 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2622 * they still need the derefencing treatment that pointers are
2623 * given */
2624 if (*desc == RPC_FC_IP)
2625 m(pStubMsg, *(unsigned char **)pMemory, desc);
2626 else
2627 m(pStubMsg, pMemory, desc);
2629 pMemory += size;
2630 pFormat += 2;
2631 continue;
2632 case RPC_FC_PAD:
2633 break;
2634 default:
2635 FIXME("unhandled format 0x%02x\n", *pFormat);
2637 pFormat++;
2640 return pMemory;
2643 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2644 PFORMAT_STRING pFormat)
2646 PFORMAT_STRING desc;
2647 unsigned long size = 0;
2649 while (*pFormat != RPC_FC_END) {
2650 switch (*pFormat) {
2651 case RPC_FC_BYTE:
2652 case RPC_FC_CHAR:
2653 case RPC_FC_SMALL:
2654 case RPC_FC_USMALL:
2655 size += 1;
2656 safe_buffer_increment(pStubMsg, 1);
2657 break;
2658 case RPC_FC_WCHAR:
2659 case RPC_FC_SHORT:
2660 case RPC_FC_USHORT:
2661 size += 2;
2662 safe_buffer_increment(pStubMsg, 2);
2663 break;
2664 case RPC_FC_ENUM16:
2665 size += 4;
2666 safe_buffer_increment(pStubMsg, 2);
2667 break;
2668 case RPC_FC_LONG:
2669 case RPC_FC_ULONG:
2670 case RPC_FC_ENUM32:
2671 size += 4;
2672 safe_buffer_increment(pStubMsg, 4);
2673 break;
2674 case RPC_FC_HYPER:
2675 size += 8;
2676 safe_buffer_increment(pStubMsg, 8);
2677 break;
2678 case RPC_FC_POINTER:
2679 size += 4;
2680 safe_buffer_increment(pStubMsg, 4);
2681 if (!pStubMsg->IgnoreEmbeddedPointers)
2682 FIXME("embedded pointers\n");
2683 break;
2684 case RPC_FC_ALIGNM4:
2685 ALIGN_LENGTH(size, 4);
2686 ALIGN_POINTER(pStubMsg->Buffer, 4);
2687 break;
2688 case RPC_FC_ALIGNM8:
2689 ALIGN_LENGTH(size, 8);
2690 ALIGN_POINTER(pStubMsg->Buffer, 8);
2691 break;
2692 case RPC_FC_STRUCTPAD1:
2693 case RPC_FC_STRUCTPAD2:
2694 case RPC_FC_STRUCTPAD3:
2695 case RPC_FC_STRUCTPAD4:
2696 case RPC_FC_STRUCTPAD5:
2697 case RPC_FC_STRUCTPAD6:
2698 case RPC_FC_STRUCTPAD7:
2699 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2700 break;
2701 case RPC_FC_EMBEDDED_COMPLEX:
2702 size += pFormat[1];
2703 pFormat += 2;
2704 desc = pFormat + *(const SHORT*)pFormat;
2705 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2706 pFormat += 2;
2707 continue;
2708 case RPC_FC_PAD:
2709 break;
2710 default:
2711 FIXME("unhandled format 0x%02x\n", *pFormat);
2713 pFormat++;
2716 return size;
2719 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
2720 PFORMAT_STRING pFormat)
2722 PFORMAT_STRING desc;
2723 unsigned long size = 0;
2725 while (*pFormat != RPC_FC_END) {
2726 switch (*pFormat) {
2727 case RPC_FC_BYTE:
2728 case RPC_FC_CHAR:
2729 case RPC_FC_SMALL:
2730 case RPC_FC_USMALL:
2731 size += 1;
2732 break;
2733 case RPC_FC_WCHAR:
2734 case RPC_FC_SHORT:
2735 case RPC_FC_USHORT:
2736 size += 2;
2737 break;
2738 case RPC_FC_LONG:
2739 case RPC_FC_ULONG:
2740 case RPC_FC_ENUM16:
2741 case RPC_FC_ENUM32:
2742 size += 4;
2743 break;
2744 case RPC_FC_HYPER:
2745 size += 8;
2746 break;
2747 case RPC_FC_POINTER:
2748 size += sizeof(void *);
2749 break;
2750 case RPC_FC_ALIGNM4:
2751 ALIGN_LENGTH(size, 4);
2752 break;
2753 case RPC_FC_ALIGNM8:
2754 ALIGN_LENGTH(size, 8);
2755 break;
2756 case RPC_FC_STRUCTPAD1:
2757 case RPC_FC_STRUCTPAD2:
2758 case RPC_FC_STRUCTPAD3:
2759 case RPC_FC_STRUCTPAD4:
2760 case RPC_FC_STRUCTPAD5:
2761 case RPC_FC_STRUCTPAD6:
2762 case RPC_FC_STRUCTPAD7:
2763 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2764 break;
2765 case RPC_FC_EMBEDDED_COMPLEX:
2766 size += pFormat[1];
2767 pFormat += 2;
2768 desc = pFormat + *(const SHORT*)pFormat;
2769 size += EmbeddedComplexSize(pStubMsg, desc);
2770 pFormat += 2;
2771 continue;
2772 case RPC_FC_PAD:
2773 break;
2774 default:
2775 FIXME("unhandled format 0x%02x\n", *pFormat);
2777 pFormat++;
2780 return size;
2783 /***********************************************************************
2784 * NdrComplexStructMarshall [RPCRT4.@]
2786 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2787 unsigned char *pMemory,
2788 PFORMAT_STRING pFormat)
2790 PFORMAT_STRING conf_array = NULL;
2791 PFORMAT_STRING pointer_desc = NULL;
2792 unsigned char *OldMemory = pStubMsg->Memory;
2793 int pointer_buffer_mark_set = 0;
2795 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2797 if (!pStubMsg->PointerBufferMark)
2799 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2800 /* save buffer length */
2801 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2803 /* get the buffer pointer after complex array data, but before
2804 * pointer data */
2805 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2806 pStubMsg->IgnoreEmbeddedPointers = 1;
2807 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2808 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2810 /* save it for use by embedded pointer code later */
2811 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2812 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2813 pointer_buffer_mark_set = 1;
2815 /* restore the original buffer length */
2816 pStubMsg->BufferLength = saved_buffer_length;
2819 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2821 pFormat += 4;
2822 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
2823 pFormat += 2;
2824 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2825 pFormat += 2;
2827 pStubMsg->Memory = pMemory;
2829 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2831 if (conf_array)
2832 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2834 pStubMsg->Memory = OldMemory;
2836 if (pointer_buffer_mark_set)
2838 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2839 pStubMsg->PointerBufferMark = NULL;
2842 STD_OVERFLOW_CHECK(pStubMsg);
2844 return NULL;
2847 /***********************************************************************
2848 * NdrComplexStructUnmarshall [RPCRT4.@]
2850 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2851 unsigned char **ppMemory,
2852 PFORMAT_STRING pFormat,
2853 unsigned char fMustAlloc)
2855 unsigned size = *(const WORD*)(pFormat+2);
2856 PFORMAT_STRING conf_array = NULL;
2857 PFORMAT_STRING pointer_desc = NULL;
2858 unsigned char *pMemory;
2859 int pointer_buffer_mark_set = 0;
2861 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2863 if (!pStubMsg->PointerBufferMark)
2865 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2866 /* save buffer pointer */
2867 unsigned char *saved_buffer = pStubMsg->Buffer;
2869 /* get the buffer pointer after complex array data, but before
2870 * pointer data */
2871 pStubMsg->IgnoreEmbeddedPointers = 1;
2872 NdrComplexStructMemorySize(pStubMsg, pFormat);
2873 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2875 /* save it for use by embedded pointer code later */
2876 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2877 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2878 pointer_buffer_mark_set = 1;
2880 /* restore the original buffer */
2881 pStubMsg->Buffer = saved_buffer;
2884 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2886 if (fMustAlloc || !*ppMemory)
2887 *ppMemory = NdrAllocate(pStubMsg, size);
2889 pFormat += 4;
2890 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
2891 pFormat += 2;
2892 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2893 pFormat += 2;
2895 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
2897 if (conf_array)
2898 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2900 if (pointer_buffer_mark_set)
2902 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2903 pStubMsg->PointerBufferMark = NULL;
2906 return NULL;
2909 /***********************************************************************
2910 * NdrComplexStructBufferSize [RPCRT4.@]
2912 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2913 unsigned char *pMemory,
2914 PFORMAT_STRING pFormat)
2916 PFORMAT_STRING conf_array = NULL;
2917 PFORMAT_STRING pointer_desc = NULL;
2918 unsigned char *OldMemory = pStubMsg->Memory;
2919 int pointer_length_set = 0;
2921 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2923 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2925 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2927 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2928 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2930 /* get the buffer length after complex struct data, but before
2931 * pointer data */
2932 pStubMsg->IgnoreEmbeddedPointers = 1;
2933 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2934 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2936 /* save it for use by embedded pointer code later */
2937 pStubMsg->PointerLength = pStubMsg->BufferLength;
2938 pointer_length_set = 1;
2939 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2941 /* restore the original buffer length */
2942 pStubMsg->BufferLength = saved_buffer_length;
2945 pFormat += 4;
2946 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
2947 pFormat += 2;
2948 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2949 pFormat += 2;
2951 pStubMsg->Memory = pMemory;
2953 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2955 if (conf_array)
2956 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2958 pStubMsg->Memory = OldMemory;
2960 if(pointer_length_set)
2962 pStubMsg->BufferLength = pStubMsg->PointerLength;
2963 pStubMsg->PointerLength = 0;
2968 /***********************************************************************
2969 * NdrComplexStructMemorySize [RPCRT4.@]
2971 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2972 PFORMAT_STRING pFormat)
2974 unsigned size = *(const WORD*)(pFormat+2);
2975 PFORMAT_STRING conf_array = NULL;
2977 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2979 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2981 pFormat += 4;
2982 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
2983 pFormat += 4;
2985 ComplexStructMemorySize(pStubMsg, pFormat);
2987 if (conf_array)
2988 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2990 return size;
2993 /***********************************************************************
2994 * NdrComplexStructFree [RPCRT4.@]
2996 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2997 unsigned char *pMemory,
2998 PFORMAT_STRING pFormat)
3000 PFORMAT_STRING conf_array = NULL;
3001 PFORMAT_STRING pointer_desc = NULL;
3002 unsigned char *OldMemory = pStubMsg->Memory;
3004 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3006 pFormat += 4;
3007 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3008 pFormat += 2;
3009 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3010 pFormat += 2;
3012 pStubMsg->Memory = pMemory;
3014 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3016 if (conf_array)
3017 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
3019 pStubMsg->Memory = OldMemory;
3022 /***********************************************************************
3023 * NdrConformantArrayMarshall [RPCRT4.@]
3025 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3026 unsigned char *pMemory,
3027 PFORMAT_STRING pFormat)
3029 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3030 unsigned char alignment = pFormat[1] + 1;
3032 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3033 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3035 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3037 WriteConformance(pStubMsg);
3039 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3041 size = safe_multiply(esize, pStubMsg->MaxCount);
3042 pStubMsg->BufferMark = pStubMsg->Buffer;
3043 safe_copy_to_buffer(pStubMsg, pMemory, size);
3045 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3047 return NULL;
3050 /***********************************************************************
3051 * NdrConformantArrayUnmarshall [RPCRT4.@]
3053 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3054 unsigned char **ppMemory,
3055 PFORMAT_STRING pFormat,
3056 unsigned char fMustAlloc)
3058 DWORD size, esize = *(const WORD*)(pFormat+2);
3059 unsigned char alignment = pFormat[1] + 1;
3060 unsigned char *saved_buffer;
3062 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3063 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3065 pFormat = ReadConformance(pStubMsg, pFormat+4);
3067 size = safe_multiply(esize, pStubMsg->MaxCount);
3068 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3070 if (fMustAlloc)
3071 *ppMemory = NdrAllocate(pStubMsg, size);
3072 else
3074 if (!pStubMsg->IsClient && !*ppMemory)
3075 /* for servers, we just point straight into the RPC buffer */
3076 *ppMemory = pStubMsg->Buffer;
3079 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3080 safe_buffer_increment(pStubMsg, size);
3081 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3083 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3084 if (*ppMemory != saved_buffer)
3085 memcpy(*ppMemory, saved_buffer, size);
3087 return NULL;
3090 /***********************************************************************
3091 * NdrConformantArrayBufferSize [RPCRT4.@]
3093 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3094 unsigned char *pMemory,
3095 PFORMAT_STRING pFormat)
3097 DWORD size, esize = *(const WORD*)(pFormat+2);
3098 unsigned char alignment = pFormat[1] + 1;
3100 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3101 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3103 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3105 SizeConformance(pStubMsg);
3107 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3109 size = safe_multiply(esize, pStubMsg->MaxCount);
3110 /* conformance value plus array */
3111 safe_buffer_length_increment(pStubMsg, size);
3113 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3116 /***********************************************************************
3117 * NdrConformantArrayMemorySize [RPCRT4.@]
3119 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3120 PFORMAT_STRING pFormat)
3122 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3123 unsigned char alignment = pFormat[1] + 1;
3125 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3126 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3128 pFormat = ReadConformance(pStubMsg, pFormat+4);
3129 size = safe_multiply(esize, pStubMsg->MaxCount);
3130 pStubMsg->MemorySize += size;
3132 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3133 pStubMsg->BufferMark = pStubMsg->Buffer;
3134 safe_buffer_increment(pStubMsg, size);
3136 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3138 return pStubMsg->MemorySize;
3141 /***********************************************************************
3142 * NdrConformantArrayFree [RPCRT4.@]
3144 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3145 unsigned char *pMemory,
3146 PFORMAT_STRING pFormat)
3148 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3149 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3151 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3153 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3157 /***********************************************************************
3158 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3160 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3161 unsigned char* pMemory,
3162 PFORMAT_STRING pFormat )
3164 ULONG bufsize;
3165 unsigned char alignment = pFormat[1] + 1;
3166 DWORD esize = *(const WORD*)(pFormat+2);
3168 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3170 if (pFormat[0] != RPC_FC_CVARRAY)
3172 ERR("invalid format type %x\n", pFormat[0]);
3173 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3174 return NULL;
3177 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3178 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3180 WriteConformance(pStubMsg);
3181 WriteVariance(pStubMsg);
3183 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3185 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3187 pStubMsg->BufferMark = pStubMsg->Buffer;
3188 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
3190 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3192 return NULL;
3196 /***********************************************************************
3197 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3199 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3200 unsigned char** ppMemory,
3201 PFORMAT_STRING pFormat,
3202 unsigned char fMustAlloc )
3204 ULONG bufsize, memsize;
3205 unsigned char alignment = pFormat[1] + 1;
3206 DWORD esize = *(const WORD*)(pFormat+2);
3207 unsigned char *saved_buffer;
3208 ULONG offset;
3210 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3212 if (pFormat[0] != RPC_FC_CVARRAY)
3214 ERR("invalid format type %x\n", pFormat[0]);
3215 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3216 return NULL;
3219 pFormat = ReadConformance(pStubMsg, pFormat+4);
3220 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3222 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3224 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3225 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3226 offset = pStubMsg->Offset;
3228 if (!*ppMemory || fMustAlloc)
3229 *ppMemory = NdrAllocate(pStubMsg, memsize);
3230 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3231 safe_buffer_increment(pStubMsg, bufsize);
3233 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3235 memcpy(*ppMemory + offset, saved_buffer, bufsize);
3237 return NULL;
3241 /***********************************************************************
3242 * NdrConformantVaryingArrayFree [RPCRT4.@]
3244 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3245 unsigned char* pMemory,
3246 PFORMAT_STRING pFormat )
3248 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3250 if (pFormat[0] != RPC_FC_CVARRAY)
3252 ERR("invalid format type %x\n", pFormat[0]);
3253 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3254 return;
3257 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3258 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3260 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3264 /***********************************************************************
3265 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3267 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3268 unsigned char* pMemory, PFORMAT_STRING pFormat )
3270 unsigned char alignment = pFormat[1] + 1;
3271 DWORD esize = *(const WORD*)(pFormat+2);
3273 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3275 if (pFormat[0] != RPC_FC_CVARRAY)
3277 ERR("invalid format type %x\n", pFormat[0]);
3278 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3279 return;
3282 /* compute size */
3283 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3284 /* compute length */
3285 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3287 SizeConformance(pStubMsg);
3288 SizeVariance(pStubMsg);
3290 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3292 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3294 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3298 /***********************************************************************
3299 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3301 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3302 PFORMAT_STRING pFormat )
3304 ULONG bufsize, memsize;
3305 unsigned char alignment = pFormat[1] + 1;
3306 DWORD esize = *(const WORD*)(pFormat+2);
3308 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3310 if (pFormat[0] != RPC_FC_CVARRAY)
3312 ERR("invalid format type %x\n", pFormat[0]);
3313 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3314 return pStubMsg->MemorySize;
3317 pFormat = ReadConformance(pStubMsg, pFormat+4);
3318 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3320 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3322 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3323 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3325 safe_buffer_increment(pStubMsg, bufsize);
3326 pStubMsg->MemorySize += memsize;
3328 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3330 return pStubMsg->MemorySize;
3334 /***********************************************************************
3335 * NdrComplexArrayMarshall [RPCRT4.@]
3337 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3338 unsigned char *pMemory,
3339 PFORMAT_STRING pFormat)
3341 ULONG i, count, def;
3342 BOOL variance_present;
3343 unsigned char alignment;
3344 int pointer_buffer_mark_set = 0;
3346 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3348 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3350 ERR("invalid format type %x\n", pFormat[0]);
3351 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3352 return NULL;
3355 alignment = pFormat[1] + 1;
3357 if (!pStubMsg->PointerBufferMark)
3359 /* save buffer fields that may be changed by buffer sizer functions
3360 * and that may be needed later on */
3361 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3362 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3363 unsigned long saved_max_count = pStubMsg->MaxCount;
3364 unsigned long saved_offset = pStubMsg->Offset;
3365 unsigned long saved_actual_count = pStubMsg->ActualCount;
3367 /* get the buffer pointer after complex array data, but before
3368 * pointer data */
3369 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3370 pStubMsg->IgnoreEmbeddedPointers = 1;
3371 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3372 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3374 /* save it for use by embedded pointer code later */
3375 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3376 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3377 pointer_buffer_mark_set = 1;
3379 /* restore fields */
3380 pStubMsg->ActualCount = saved_actual_count;
3381 pStubMsg->Offset = saved_offset;
3382 pStubMsg->MaxCount = saved_max_count;
3383 pStubMsg->BufferLength = saved_buffer_length;
3386 def = *(const WORD*)&pFormat[2];
3387 pFormat += 4;
3389 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3390 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3392 variance_present = IsConformanceOrVariancePresent(pFormat);
3393 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3394 TRACE("variance = %d\n", pStubMsg->ActualCount);
3396 WriteConformance(pStubMsg);
3397 if (variance_present)
3398 WriteVariance(pStubMsg);
3400 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3402 count = pStubMsg->ActualCount;
3403 for (i = 0; i < count; i++)
3404 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3406 STD_OVERFLOW_CHECK(pStubMsg);
3408 if (pointer_buffer_mark_set)
3410 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3411 pStubMsg->PointerBufferMark = NULL;
3414 return NULL;
3417 /***********************************************************************
3418 * NdrComplexArrayUnmarshall [RPCRT4.@]
3420 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3421 unsigned char **ppMemory,
3422 PFORMAT_STRING pFormat,
3423 unsigned char fMustAlloc)
3425 ULONG i, count, size;
3426 unsigned char alignment;
3427 unsigned char *pMemory;
3428 unsigned char *saved_buffer;
3429 int pointer_buffer_mark_set = 0;
3430 int saved_ignore_embedded;
3432 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3434 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3436 ERR("invalid format type %x\n", pFormat[0]);
3437 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3438 return NULL;
3441 alignment = pFormat[1] + 1;
3443 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3444 /* save buffer pointer */
3445 saved_buffer = pStubMsg->Buffer;
3446 /* get the buffer pointer after complex array data, but before
3447 * pointer data */
3448 pStubMsg->IgnoreEmbeddedPointers = 1;
3449 pStubMsg->MemorySize = 0;
3450 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3451 size = pStubMsg->MemorySize;
3452 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3454 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3455 if (!pStubMsg->PointerBufferMark)
3457 /* save it for use by embedded pointer code later */
3458 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3459 pointer_buffer_mark_set = 1;
3461 /* restore the original buffer */
3462 pStubMsg->Buffer = saved_buffer;
3464 pFormat += 4;
3466 pFormat = ReadConformance(pStubMsg, pFormat);
3467 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3469 if (fMustAlloc || !*ppMemory)
3470 *ppMemory = NdrAllocate(pStubMsg, size);
3472 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3474 pMemory = *ppMemory;
3475 count = pStubMsg->ActualCount;
3476 for (i = 0; i < count; i++)
3477 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3479 if (pointer_buffer_mark_set)
3481 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3482 pStubMsg->PointerBufferMark = NULL;
3485 return NULL;
3488 /***********************************************************************
3489 * NdrComplexArrayBufferSize [RPCRT4.@]
3491 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3492 unsigned char *pMemory,
3493 PFORMAT_STRING pFormat)
3495 ULONG i, count, def;
3496 unsigned char alignment;
3497 BOOL variance_present;
3498 int pointer_length_set = 0;
3500 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3502 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3504 ERR("invalid format type %x\n", pFormat[0]);
3505 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3506 return;
3509 alignment = pFormat[1] + 1;
3511 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3513 /* save buffer fields that may be changed by buffer sizer functions
3514 * and that may be needed later on */
3515 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3516 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3517 unsigned long saved_max_count = pStubMsg->MaxCount;
3518 unsigned long saved_offset = pStubMsg->Offset;
3519 unsigned long saved_actual_count = pStubMsg->ActualCount;
3521 /* get the buffer pointer after complex array data, but before
3522 * pointer data */
3523 pStubMsg->IgnoreEmbeddedPointers = 1;
3524 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3525 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3527 /* save it for use by embedded pointer code later */
3528 pStubMsg->PointerLength = pStubMsg->BufferLength;
3529 pointer_length_set = 1;
3531 /* restore fields */
3532 pStubMsg->ActualCount = saved_actual_count;
3533 pStubMsg->Offset = saved_offset;
3534 pStubMsg->MaxCount = saved_max_count;
3535 pStubMsg->BufferLength = saved_buffer_length;
3537 def = *(const WORD*)&pFormat[2];
3538 pFormat += 4;
3540 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3541 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3542 SizeConformance(pStubMsg);
3544 variance_present = IsConformanceOrVariancePresent(pFormat);
3545 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3546 TRACE("variance = %d\n", pStubMsg->ActualCount);
3548 if (variance_present)
3549 SizeVariance(pStubMsg);
3551 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3553 count = pStubMsg->ActualCount;
3554 for (i = 0; i < count; i++)
3555 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3557 if(pointer_length_set)
3559 pStubMsg->BufferLength = pStubMsg->PointerLength;
3560 pStubMsg->PointerLength = 0;
3564 /***********************************************************************
3565 * NdrComplexArrayMemorySize [RPCRT4.@]
3567 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3568 PFORMAT_STRING pFormat)
3570 ULONG i, count, esize, SavedMemorySize, MemorySize;
3571 unsigned char alignment;
3573 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3575 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3577 ERR("invalid format type %x\n", pFormat[0]);
3578 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3579 return 0;
3582 alignment = pFormat[1] + 1;
3584 pFormat += 4;
3586 pFormat = ReadConformance(pStubMsg, pFormat);
3587 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3589 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3591 SavedMemorySize = pStubMsg->MemorySize;
3593 esize = ComplexStructSize(pStubMsg, pFormat);
3595 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3597 count = pStubMsg->ActualCount;
3598 for (i = 0; i < count; i++)
3599 ComplexStructMemorySize(pStubMsg, pFormat);
3601 pStubMsg->MemorySize = SavedMemorySize;
3603 pStubMsg->MemorySize += MemorySize;
3604 return MemorySize;
3607 /***********************************************************************
3608 * NdrComplexArrayFree [RPCRT4.@]
3610 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3611 unsigned char *pMemory,
3612 PFORMAT_STRING pFormat)
3614 ULONG i, count, def;
3616 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3618 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3620 ERR("invalid format type %x\n", pFormat[0]);
3621 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3622 return;
3625 def = *(const WORD*)&pFormat[2];
3626 pFormat += 4;
3628 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3629 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3631 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3632 TRACE("variance = %d\n", pStubMsg->ActualCount);
3634 count = pStubMsg->ActualCount;
3635 for (i = 0; i < count; i++)
3636 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3639 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3640 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3641 USER_MARSHAL_CB *umcb)
3643 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3644 pStubMsg->RpcMsg->DataRepresentation);
3645 umcb->pStubMsg = pStubMsg;
3646 umcb->pReserve = NULL;
3647 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3648 umcb->CBType = cbtype;
3649 umcb->pFormat = pFormat;
3650 umcb->pTypeFormat = NULL /* FIXME */;
3653 #define USER_MARSHAL_PTR_PREFIX \
3654 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3655 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3657 /***********************************************************************
3658 * NdrUserMarshalMarshall [RPCRT4.@]
3660 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3661 unsigned char *pMemory,
3662 PFORMAT_STRING pFormat)
3664 unsigned flags = pFormat[1];
3665 unsigned index = *(const WORD*)&pFormat[2];
3666 unsigned char *saved_buffer = NULL;
3667 USER_MARSHAL_CB umcb;
3669 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3670 TRACE("index=%d\n", index);
3672 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3674 if (flags & USER_MARSHAL_POINTER)
3676 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3677 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3678 pStubMsg->Buffer += 4;
3679 if (pStubMsg->PointerBufferMark)
3681 saved_buffer = pStubMsg->Buffer;
3682 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3683 pStubMsg->PointerBufferMark = NULL;
3685 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3687 else
3688 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3690 pStubMsg->Buffer =
3691 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3692 &umcb.Flags, pStubMsg->Buffer, pMemory);
3694 if (saved_buffer)
3696 STD_OVERFLOW_CHECK(pStubMsg);
3697 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3698 pStubMsg->Buffer = saved_buffer;
3701 STD_OVERFLOW_CHECK(pStubMsg);
3703 return NULL;
3706 /***********************************************************************
3707 * NdrUserMarshalUnmarshall [RPCRT4.@]
3709 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3710 unsigned char **ppMemory,
3711 PFORMAT_STRING pFormat,
3712 unsigned char fMustAlloc)
3714 unsigned flags = pFormat[1];
3715 unsigned index = *(const WORD*)&pFormat[2];
3716 DWORD memsize = *(const WORD*)&pFormat[4];
3717 unsigned char *saved_buffer = NULL;
3718 USER_MARSHAL_CB umcb;
3720 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3721 TRACE("index=%d\n", index);
3723 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3725 if (flags & USER_MARSHAL_POINTER)
3727 ALIGN_POINTER(pStubMsg->Buffer, 4);
3728 /* skip pointer prefix */
3729 pStubMsg->Buffer += 4;
3730 if (pStubMsg->PointerBufferMark)
3732 saved_buffer = pStubMsg->Buffer;
3733 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3734 pStubMsg->PointerBufferMark = NULL;
3736 ALIGN_POINTER(pStubMsg->Buffer, 8);
3738 else
3739 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3741 if (fMustAlloc || !*ppMemory)
3742 *ppMemory = NdrAllocate(pStubMsg, memsize);
3744 pStubMsg->Buffer =
3745 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3746 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3748 if (saved_buffer)
3750 STD_OVERFLOW_CHECK(pStubMsg);
3751 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3752 pStubMsg->Buffer = saved_buffer;
3755 return NULL;
3758 /***********************************************************************
3759 * NdrUserMarshalBufferSize [RPCRT4.@]
3761 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3762 unsigned char *pMemory,
3763 PFORMAT_STRING pFormat)
3765 unsigned flags = pFormat[1];
3766 unsigned index = *(const WORD*)&pFormat[2];
3767 DWORD bufsize = *(const WORD*)&pFormat[6];
3768 USER_MARSHAL_CB umcb;
3769 unsigned long saved_buffer_length = 0;
3771 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3772 TRACE("index=%d\n", index);
3774 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3776 if (flags & USER_MARSHAL_POINTER)
3778 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3779 /* skip pointer prefix */
3780 safe_buffer_length_increment(pStubMsg, 4);
3781 if (pStubMsg->IgnoreEmbeddedPointers)
3782 return;
3783 if (pStubMsg->PointerLength)
3785 saved_buffer_length = pStubMsg->BufferLength;
3786 pStubMsg->BufferLength = pStubMsg->PointerLength;
3787 pStubMsg->PointerLength = 0;
3789 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3791 else
3792 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3794 if (bufsize) {
3795 TRACE("size=%d\n", bufsize);
3796 safe_buffer_length_increment(pStubMsg, bufsize);
3798 else
3799 pStubMsg->BufferLength =
3800 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3801 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3803 if (saved_buffer_length)
3805 pStubMsg->PointerLength = pStubMsg->BufferLength;
3806 pStubMsg->BufferLength = saved_buffer_length;
3811 /***********************************************************************
3812 * NdrUserMarshalMemorySize [RPCRT4.@]
3814 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3815 PFORMAT_STRING pFormat)
3817 unsigned flags = pFormat[1];
3818 unsigned index = *(const WORD*)&pFormat[2];
3819 DWORD memsize = *(const WORD*)&pFormat[4];
3820 DWORD bufsize = *(const WORD*)&pFormat[6];
3822 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3823 TRACE("index=%d\n", index);
3825 pStubMsg->MemorySize += memsize;
3827 if (flags & USER_MARSHAL_POINTER)
3829 ALIGN_POINTER(pStubMsg->Buffer, 4);
3830 /* skip pointer prefix */
3831 pStubMsg->Buffer += 4;
3832 if (pStubMsg->IgnoreEmbeddedPointers)
3833 return pStubMsg->MemorySize;
3834 ALIGN_POINTER(pStubMsg->Buffer, 8);
3836 else
3837 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3839 if (!bufsize)
3840 FIXME("not implemented for varying buffer size\n");
3842 pStubMsg->Buffer += bufsize;
3844 return pStubMsg->MemorySize;
3847 /***********************************************************************
3848 * NdrUserMarshalFree [RPCRT4.@]
3850 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3851 unsigned char *pMemory,
3852 PFORMAT_STRING pFormat)
3854 /* unsigned flags = pFormat[1]; */
3855 unsigned index = *(const WORD*)&pFormat[2];
3856 USER_MARSHAL_CB umcb;
3858 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3859 TRACE("index=%d\n", index);
3861 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3863 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3864 &umcb.Flags, pMemory);
3867 /***********************************************************************
3868 * NdrClearOutParameters [RPCRT4.@]
3870 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3871 PFORMAT_STRING pFormat,
3872 void *ArgAddr)
3874 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3877 /***********************************************************************
3878 * NdrConvert [RPCRT4.@]
3880 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3882 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3883 /* FIXME: since this stub doesn't do any converting, the proper behavior
3884 is to raise an exception */
3887 /***********************************************************************
3888 * NdrConvert2 [RPCRT4.@]
3890 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3892 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3893 pStubMsg, pFormat, NumberParams);
3894 /* FIXME: since this stub doesn't do any converting, the proper behavior
3895 is to raise an exception */
3898 #include "pshpack1.h"
3899 typedef struct _NDR_CSTRUCT_FORMAT
3901 unsigned char type;
3902 unsigned char alignment;
3903 unsigned short memory_size;
3904 short offset_to_array_description;
3905 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3906 #include "poppack.h"
3908 /***********************************************************************
3909 * NdrConformantStructMarshall [RPCRT4.@]
3911 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3912 unsigned char *pMemory,
3913 PFORMAT_STRING pFormat)
3915 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3916 PFORMAT_STRING pCArrayFormat;
3917 ULONG esize, bufsize;
3919 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3921 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3922 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3924 ERR("invalid format type %x\n", pCStructFormat->type);
3925 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3926 return NULL;
3929 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3930 pCStructFormat->offset_to_array_description;
3931 if (*pCArrayFormat != RPC_FC_CARRAY)
3933 ERR("invalid array format type %x\n", pCStructFormat->type);
3934 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3935 return NULL;
3937 esize = *(const WORD*)(pCArrayFormat+2);
3939 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3940 pCArrayFormat + 4, 0);
3942 WriteConformance(pStubMsg);
3944 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3946 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3948 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3949 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3951 ERR("integer overflow of memory_size %u with bufsize %u\n",
3952 pCStructFormat->memory_size, bufsize);
3953 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3955 /* copy constant sized part of struct */
3956 pStubMsg->BufferMark = pStubMsg->Buffer;
3957 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3959 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3960 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3962 return NULL;
3965 /***********************************************************************
3966 * NdrConformantStructUnmarshall [RPCRT4.@]
3968 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3969 unsigned char **ppMemory,
3970 PFORMAT_STRING pFormat,
3971 unsigned char fMustAlloc)
3973 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3974 PFORMAT_STRING pCArrayFormat;
3975 ULONG esize, bufsize;
3976 unsigned char *saved_buffer;
3978 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3980 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3981 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3983 ERR("invalid format type %x\n", pCStructFormat->type);
3984 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3985 return NULL;
3987 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3988 pCStructFormat->offset_to_array_description;
3989 if (*pCArrayFormat != RPC_FC_CARRAY)
3991 ERR("invalid array format type %x\n", pCStructFormat->type);
3992 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3993 return NULL;
3995 esize = *(const WORD*)(pCArrayFormat+2);
3997 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3999 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4001 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4003 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4004 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4006 ERR("integer overflow of memory_size %u with bufsize %u\n",
4007 pCStructFormat->memory_size, bufsize);
4008 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4011 if (fMustAlloc)
4013 SIZE_T size = pCStructFormat->memory_size + bufsize;
4014 *ppMemory = NdrAllocate(pStubMsg, size);
4016 else
4018 if (!pStubMsg->IsClient && !*ppMemory)
4019 /* for servers, we just point straight into the RPC buffer */
4020 *ppMemory = pStubMsg->Buffer;
4023 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4024 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4025 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4026 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4028 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4029 if (*ppMemory != saved_buffer)
4030 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4032 return NULL;
4035 /***********************************************************************
4036 * NdrConformantStructBufferSize [RPCRT4.@]
4038 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4039 unsigned char *pMemory,
4040 PFORMAT_STRING pFormat)
4042 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4043 PFORMAT_STRING pCArrayFormat;
4044 ULONG esize;
4046 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4048 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4049 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4051 ERR("invalid format type %x\n", pCStructFormat->type);
4052 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4053 return;
4055 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4056 pCStructFormat->offset_to_array_description;
4057 if (*pCArrayFormat != RPC_FC_CARRAY)
4059 ERR("invalid array format type %x\n", pCStructFormat->type);
4060 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4061 return;
4063 esize = *(const WORD*)(pCArrayFormat+2);
4065 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4066 SizeConformance(pStubMsg);
4068 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4070 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4072 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4073 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4075 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4076 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4079 /***********************************************************************
4080 * NdrConformantStructMemorySize [RPCRT4.@]
4082 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4083 PFORMAT_STRING pFormat)
4085 FIXME("stub\n");
4086 return 0;
4089 /***********************************************************************
4090 * NdrConformantStructFree [RPCRT4.@]
4092 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4093 unsigned char *pMemory,
4094 PFORMAT_STRING pFormat)
4096 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4097 PFORMAT_STRING pCArrayFormat;
4099 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4101 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4102 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4104 ERR("invalid format type %x\n", pCStructFormat->type);
4105 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4106 return;
4109 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4110 pCStructFormat->offset_to_array_description;
4111 if (*pCArrayFormat != RPC_FC_CARRAY)
4113 ERR("invalid array format type %x\n", pCStructFormat->type);
4114 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4115 return;
4118 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4119 pCArrayFormat + 4, 0);
4121 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4123 /* copy constant sized part of struct */
4124 pStubMsg->BufferMark = pStubMsg->Buffer;
4126 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4127 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4130 /***********************************************************************
4131 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4133 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4134 unsigned char *pMemory,
4135 PFORMAT_STRING pFormat)
4137 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4138 PFORMAT_STRING pCVArrayFormat;
4139 ULONG esize, bufsize;
4141 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4143 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4144 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4146 ERR("invalid format type %x\n", pCVStructFormat->type);
4147 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4148 return NULL;
4151 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4152 pCVStructFormat->offset_to_array_description;
4153 switch (*pCVArrayFormat)
4155 case RPC_FC_CVARRAY:
4156 esize = *(const WORD*)(pCVArrayFormat+2);
4158 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4159 pCVArrayFormat + 4, 0);
4160 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4161 pCVArrayFormat, 0);
4162 break;
4163 case RPC_FC_C_CSTRING:
4164 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4165 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4166 esize = sizeof(char);
4167 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4168 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4169 pCVArrayFormat + 2, 0);
4170 else
4171 pStubMsg->MaxCount = pStubMsg->ActualCount;
4172 break;
4173 case RPC_FC_C_WSTRING:
4174 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4175 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4176 esize = sizeof(WCHAR);
4177 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4178 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4179 pCVArrayFormat + 2, 0);
4180 else
4181 pStubMsg->MaxCount = pStubMsg->ActualCount;
4182 break;
4183 default:
4184 ERR("invalid array format type %x\n", *pCVArrayFormat);
4185 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4186 return NULL;
4189 WriteConformance(pStubMsg);
4191 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4193 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4195 /* write constant sized part */
4196 pStubMsg->BufferMark = pStubMsg->Buffer;
4197 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4199 WriteVariance(pStubMsg);
4201 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4203 /* write array part */
4204 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
4206 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4208 return NULL;
4211 /***********************************************************************
4212 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4214 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4215 unsigned char **ppMemory,
4216 PFORMAT_STRING pFormat,
4217 unsigned char fMustAlloc)
4219 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4220 PFORMAT_STRING pCVArrayFormat;
4221 ULONG esize, bufsize;
4222 unsigned char cvarray_type;
4223 unsigned char *saved_buffer, *saved_array_buffer;
4225 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4227 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4228 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4230 ERR("invalid format type %x\n", pCVStructFormat->type);
4231 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4232 return NULL;
4235 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4236 pCVStructFormat->offset_to_array_description;
4237 cvarray_type = *pCVArrayFormat;
4238 switch (cvarray_type)
4240 case RPC_FC_CVARRAY:
4241 esize = *(const WORD*)(pCVArrayFormat+2);
4242 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4243 break;
4244 case RPC_FC_C_CSTRING:
4245 esize = sizeof(char);
4246 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4247 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4248 else
4249 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4250 break;
4251 case RPC_FC_C_WSTRING:
4252 esize = sizeof(WCHAR);
4253 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4254 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4255 else
4256 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4257 break;
4258 default:
4259 ERR("invalid array format type %x\n", *pCVArrayFormat);
4260 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4261 return NULL;
4264 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4266 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4268 /* work out how much memory to allocate if we need to do so */
4269 if (!*ppMemory || fMustAlloc)
4271 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4272 *ppMemory = NdrAllocate(pStubMsg, size);
4275 /* mark the start of the constant data */
4276 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4277 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4279 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4281 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4283 if ((cvarray_type == RPC_FC_C_CSTRING) ||
4284 (cvarray_type == RPC_FC_C_WSTRING))
4285 validate_string_data(pStubMsg, bufsize, esize);
4287 /* mark the start of the array data */
4288 saved_array_buffer = pStubMsg->Buffer;
4289 safe_buffer_increment(pStubMsg, bufsize);
4291 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4293 /* copy the constant data */
4294 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4295 /* copy the array data */
4296 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4297 memcpy(*ppMemory + pCVStructFormat->memory_size, saved_array_buffer, bufsize);
4299 if (cvarray_type == RPC_FC_C_CSTRING)
4300 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4301 else if (cvarray_type == RPC_FC_C_WSTRING)
4302 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4304 return NULL;
4307 /***********************************************************************
4308 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4310 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4311 unsigned char *pMemory,
4312 PFORMAT_STRING pFormat)
4314 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4315 PFORMAT_STRING pCVArrayFormat;
4316 ULONG esize;
4318 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4320 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4321 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4323 ERR("invalid format type %x\n", pCVStructFormat->type);
4324 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4325 return;
4328 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4329 pCVStructFormat->offset_to_array_description;
4330 switch (*pCVArrayFormat)
4332 case RPC_FC_CVARRAY:
4333 esize = *(const WORD*)(pCVArrayFormat+2);
4335 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4336 pCVArrayFormat + 4, 0);
4337 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4338 pCVArrayFormat, 0);
4339 break;
4340 case RPC_FC_C_CSTRING:
4341 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4342 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4343 esize = sizeof(char);
4344 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4345 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4346 pCVArrayFormat + 2, 0);
4347 else
4348 pStubMsg->MaxCount = pStubMsg->ActualCount;
4349 break;
4350 case RPC_FC_C_WSTRING:
4351 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4352 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4353 esize = sizeof(WCHAR);
4354 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4355 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4356 pCVArrayFormat + 2, 0);
4357 else
4358 pStubMsg->MaxCount = pStubMsg->ActualCount;
4359 break;
4360 default:
4361 ERR("invalid array format type %x\n", *pCVArrayFormat);
4362 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4363 return;
4366 SizeConformance(pStubMsg);
4368 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4370 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4372 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4373 SizeVariance(pStubMsg);
4374 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4376 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4379 /***********************************************************************
4380 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4382 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4383 PFORMAT_STRING pFormat)
4385 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4386 PFORMAT_STRING pCVArrayFormat;
4387 ULONG esize;
4388 unsigned char cvarray_type;
4390 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4392 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4393 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4395 ERR("invalid format type %x\n", pCVStructFormat->type);
4396 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4397 return 0;
4400 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4401 pCVStructFormat->offset_to_array_description;
4402 cvarray_type = *pCVArrayFormat;
4403 switch (cvarray_type)
4405 case RPC_FC_CVARRAY:
4406 esize = *(const WORD*)(pCVArrayFormat+2);
4407 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4408 break;
4409 case RPC_FC_C_CSTRING:
4410 esize = sizeof(char);
4411 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4412 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4413 else
4414 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4415 break;
4416 case RPC_FC_C_WSTRING:
4417 esize = sizeof(WCHAR);
4418 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4419 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4420 else
4421 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4422 break;
4423 default:
4424 ERR("invalid array format type %x\n", *pCVArrayFormat);
4425 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4426 return 0;
4429 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4431 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4433 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4434 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4435 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4437 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4439 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4441 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4444 /***********************************************************************
4445 * NdrConformantVaryingStructFree [RPCRT4.@]
4447 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4448 unsigned char *pMemory,
4449 PFORMAT_STRING pFormat)
4451 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4452 PFORMAT_STRING pCVArrayFormat;
4454 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4456 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4457 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4459 ERR("invalid format type %x\n", pCVStructFormat->type);
4460 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4461 return;
4464 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4465 pCVStructFormat->offset_to_array_description;
4466 switch (*pCVArrayFormat)
4468 case RPC_FC_CVARRAY:
4469 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4470 pCVArrayFormat + 4, 0);
4471 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4472 pCVArrayFormat, 0);
4473 break;
4474 case RPC_FC_C_CSTRING:
4475 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4476 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4477 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4478 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4479 pCVArrayFormat + 2, 0);
4480 else
4481 pStubMsg->MaxCount = pStubMsg->ActualCount;
4482 break;
4483 case RPC_FC_C_WSTRING:
4484 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4485 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4486 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4487 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4488 pCVArrayFormat + 2, 0);
4489 else
4490 pStubMsg->MaxCount = pStubMsg->ActualCount;
4491 break;
4492 default:
4493 ERR("invalid array format type %x\n", *pCVArrayFormat);
4494 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4495 return;
4498 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4500 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4503 #include "pshpack1.h"
4504 typedef struct
4506 unsigned char type;
4507 unsigned char alignment;
4508 unsigned short total_size;
4509 } NDR_SMFARRAY_FORMAT;
4511 typedef struct
4513 unsigned char type;
4514 unsigned char alignment;
4515 unsigned long total_size;
4516 } NDR_LGFARRAY_FORMAT;
4517 #include "poppack.h"
4519 /***********************************************************************
4520 * NdrFixedArrayMarshall [RPCRT4.@]
4522 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4523 unsigned char *pMemory,
4524 PFORMAT_STRING pFormat)
4526 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4527 unsigned long total_size;
4529 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4531 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4532 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4534 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4535 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4536 return NULL;
4539 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4541 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4543 total_size = pSmFArrayFormat->total_size;
4544 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4546 else
4548 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4549 total_size = pLgFArrayFormat->total_size;
4550 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4553 pStubMsg->BufferMark = pStubMsg->Buffer;
4554 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4556 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4558 return NULL;
4561 /***********************************************************************
4562 * NdrFixedArrayUnmarshall [RPCRT4.@]
4564 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4565 unsigned char **ppMemory,
4566 PFORMAT_STRING pFormat,
4567 unsigned char fMustAlloc)
4569 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4570 unsigned long total_size;
4571 unsigned char *saved_buffer;
4573 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4575 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4576 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4578 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4579 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4580 return NULL;
4583 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4585 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4587 total_size = pSmFArrayFormat->total_size;
4588 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4590 else
4592 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4593 total_size = pLgFArrayFormat->total_size;
4594 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4597 if (fMustAlloc)
4598 *ppMemory = NdrAllocate(pStubMsg, total_size);
4599 else
4601 if (!pStubMsg->IsClient && !*ppMemory)
4602 /* for servers, we just point straight into the RPC buffer */
4603 *ppMemory = pStubMsg->Buffer;
4606 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4607 safe_buffer_increment(pStubMsg, total_size);
4608 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4610 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4611 if (*ppMemory != saved_buffer)
4612 memcpy(*ppMemory, saved_buffer, total_size);
4614 return NULL;
4617 /***********************************************************************
4618 * NdrFixedArrayBufferSize [RPCRT4.@]
4620 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4621 unsigned char *pMemory,
4622 PFORMAT_STRING pFormat)
4624 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4625 unsigned long total_size;
4627 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4629 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4630 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4632 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4633 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4634 return;
4637 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4639 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4641 total_size = pSmFArrayFormat->total_size;
4642 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4644 else
4646 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4647 total_size = pLgFArrayFormat->total_size;
4648 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4650 safe_buffer_length_increment(pStubMsg, total_size);
4652 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4655 /***********************************************************************
4656 * NdrFixedArrayMemorySize [RPCRT4.@]
4658 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4659 PFORMAT_STRING pFormat)
4661 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4662 ULONG total_size;
4664 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4666 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4667 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4669 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4670 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4671 return 0;
4674 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4676 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4678 total_size = pSmFArrayFormat->total_size;
4679 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4681 else
4683 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4684 total_size = pLgFArrayFormat->total_size;
4685 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4687 pStubMsg->BufferMark = pStubMsg->Buffer;
4688 safe_buffer_increment(pStubMsg, total_size);
4689 pStubMsg->MemorySize += total_size;
4691 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4693 return total_size;
4696 /***********************************************************************
4697 * NdrFixedArrayFree [RPCRT4.@]
4699 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4700 unsigned char *pMemory,
4701 PFORMAT_STRING pFormat)
4703 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4705 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4707 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4708 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4710 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4711 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4712 return;
4715 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4716 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4717 else
4719 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4720 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4723 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4726 /***********************************************************************
4727 * NdrVaryingArrayMarshall [RPCRT4.@]
4729 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4730 unsigned char *pMemory,
4731 PFORMAT_STRING pFormat)
4733 unsigned char alignment;
4734 DWORD elements, esize;
4735 ULONG bufsize;
4737 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4739 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4740 (pFormat[0] != RPC_FC_LGVARRAY))
4742 ERR("invalid format type %x\n", pFormat[0]);
4743 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4744 return NULL;
4747 alignment = pFormat[1] + 1;
4749 if (pFormat[0] == RPC_FC_SMVARRAY)
4751 pFormat += 2;
4752 pFormat += sizeof(WORD);
4753 elements = *(const WORD*)pFormat;
4754 pFormat += sizeof(WORD);
4756 else
4758 pFormat += 2;
4759 pFormat += sizeof(DWORD);
4760 elements = *(const DWORD*)pFormat;
4761 pFormat += sizeof(DWORD);
4764 esize = *(const WORD*)pFormat;
4765 pFormat += sizeof(WORD);
4767 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4768 if ((pStubMsg->ActualCount > elements) ||
4769 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4771 RpcRaiseException(RPC_S_INVALID_BOUND);
4772 return NULL;
4775 WriteVariance(pStubMsg);
4777 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4779 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4780 pStubMsg->BufferMark = pStubMsg->Buffer;
4781 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4783 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4785 return NULL;
4788 /***********************************************************************
4789 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4791 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4792 unsigned char **ppMemory,
4793 PFORMAT_STRING pFormat,
4794 unsigned char fMustAlloc)
4796 unsigned char alignment;
4797 DWORD size, elements, esize;
4798 ULONG bufsize;
4799 unsigned char *saved_buffer;
4800 ULONG offset;
4802 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4804 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4805 (pFormat[0] != RPC_FC_LGVARRAY))
4807 ERR("invalid format type %x\n", pFormat[0]);
4808 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4809 return NULL;
4812 alignment = pFormat[1] + 1;
4814 if (pFormat[0] == RPC_FC_SMVARRAY)
4816 pFormat += 2;
4817 size = *(const WORD*)pFormat;
4818 pFormat += sizeof(WORD);
4819 elements = *(const WORD*)pFormat;
4820 pFormat += sizeof(WORD);
4822 else
4824 pFormat += 2;
4825 size = *(const DWORD*)pFormat;
4826 pFormat += sizeof(DWORD);
4827 elements = *(const DWORD*)pFormat;
4828 pFormat += sizeof(DWORD);
4831 esize = *(const WORD*)pFormat;
4832 pFormat += sizeof(WORD);
4834 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4836 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4838 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4839 offset = pStubMsg->Offset;
4841 if (!*ppMemory || fMustAlloc)
4842 *ppMemory = NdrAllocate(pStubMsg, size);
4843 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4844 safe_buffer_increment(pStubMsg, bufsize);
4846 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4848 memcpy(*ppMemory + offset, saved_buffer, bufsize);
4850 return NULL;
4853 /***********************************************************************
4854 * NdrVaryingArrayBufferSize [RPCRT4.@]
4856 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4857 unsigned char *pMemory,
4858 PFORMAT_STRING pFormat)
4860 unsigned char alignment;
4861 DWORD elements, esize;
4863 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4865 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4866 (pFormat[0] != RPC_FC_LGVARRAY))
4868 ERR("invalid format type %x\n", pFormat[0]);
4869 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4870 return;
4873 alignment = pFormat[1] + 1;
4875 if (pFormat[0] == RPC_FC_SMVARRAY)
4877 pFormat += 2;
4878 pFormat += sizeof(WORD);
4879 elements = *(const WORD*)pFormat;
4880 pFormat += sizeof(WORD);
4882 else
4884 pFormat += 2;
4885 pFormat += sizeof(DWORD);
4886 elements = *(const DWORD*)pFormat;
4887 pFormat += sizeof(DWORD);
4890 esize = *(const WORD*)pFormat;
4891 pFormat += sizeof(WORD);
4893 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4894 if ((pStubMsg->ActualCount > elements) ||
4895 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4897 RpcRaiseException(RPC_S_INVALID_BOUND);
4898 return;
4901 SizeVariance(pStubMsg);
4903 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4905 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4907 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4910 /***********************************************************************
4911 * NdrVaryingArrayMemorySize [RPCRT4.@]
4913 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4914 PFORMAT_STRING pFormat)
4916 unsigned char alignment;
4917 DWORD size, elements, esize;
4919 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4921 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4922 (pFormat[0] != RPC_FC_LGVARRAY))
4924 ERR("invalid format type %x\n", pFormat[0]);
4925 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4926 return 0;
4929 alignment = pFormat[1] + 1;
4931 if (pFormat[0] == RPC_FC_SMVARRAY)
4933 pFormat += 2;
4934 size = *(const WORD*)pFormat;
4935 pFormat += sizeof(WORD);
4936 elements = *(const WORD*)pFormat;
4937 pFormat += sizeof(WORD);
4939 else
4941 pFormat += 2;
4942 size = *(const DWORD*)pFormat;
4943 pFormat += sizeof(DWORD);
4944 elements = *(const DWORD*)pFormat;
4945 pFormat += sizeof(DWORD);
4948 esize = *(const WORD*)pFormat;
4949 pFormat += sizeof(WORD);
4951 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4953 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4955 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4956 pStubMsg->MemorySize += size;
4958 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4960 return pStubMsg->MemorySize;
4963 /***********************************************************************
4964 * NdrVaryingArrayFree [RPCRT4.@]
4966 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4967 unsigned char *pMemory,
4968 PFORMAT_STRING pFormat)
4970 DWORD elements;
4972 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4974 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4975 (pFormat[0] != RPC_FC_LGVARRAY))
4977 ERR("invalid format type %x\n", pFormat[0]);
4978 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4979 return;
4982 if (pFormat[0] == RPC_FC_SMVARRAY)
4984 pFormat += 2;
4985 pFormat += sizeof(WORD);
4986 elements = *(const WORD*)pFormat;
4987 pFormat += sizeof(WORD);
4989 else
4991 pFormat += 2;
4992 pFormat += sizeof(DWORD);
4993 elements = *(const DWORD*)pFormat;
4994 pFormat += sizeof(DWORD);
4997 pFormat += sizeof(WORD);
4999 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5000 if ((pStubMsg->ActualCount > elements) ||
5001 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5003 RpcRaiseException(RPC_S_INVALID_BOUND);
5004 return;
5007 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5010 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5012 switch (fc)
5014 case RPC_FC_BYTE:
5015 case RPC_FC_CHAR:
5016 case RPC_FC_SMALL:
5017 case RPC_FC_USMALL:
5018 return *pMemory;
5019 case RPC_FC_WCHAR:
5020 case RPC_FC_SHORT:
5021 case RPC_FC_USHORT:
5022 case RPC_FC_ENUM16:
5023 return *(const USHORT *)pMemory;
5024 case RPC_FC_LONG:
5025 case RPC_FC_ULONG:
5026 case RPC_FC_ENUM32:
5027 return *(const ULONG *)pMemory;
5028 default:
5029 FIXME("Unhandled base type: 0x%02x\n", fc);
5030 return 0;
5034 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5035 unsigned long discriminant,
5036 PFORMAT_STRING pFormat)
5038 unsigned short num_arms, arm, type;
5040 num_arms = *(const SHORT*)pFormat & 0x0fff;
5041 pFormat += 2;
5042 for(arm = 0; arm < num_arms; arm++)
5044 if(discriminant == *(const ULONG*)pFormat)
5046 pFormat += 4;
5047 break;
5049 pFormat += 6;
5052 type = *(const unsigned short*)pFormat;
5053 TRACE("type %04x\n", type);
5054 if(arm == num_arms) /* default arm extras */
5056 if(type == 0xffff)
5058 ERR("no arm for 0x%lx and no default case\n", discriminant);
5059 RpcRaiseException(RPC_S_INVALID_TAG);
5060 return NULL;
5062 if(type == 0)
5064 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5065 return NULL;
5068 return pFormat;
5071 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5073 unsigned short type;
5075 pFormat += 2;
5077 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5078 if(!pFormat)
5079 return NULL;
5081 type = *(const unsigned short*)pFormat;
5082 if((type & 0xff00) == 0x8000)
5084 unsigned char basetype = LOBYTE(type);
5085 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5087 else
5089 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5090 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5091 if (m)
5093 unsigned char *saved_buffer = NULL;
5094 int pointer_buffer_mark_set = 0;
5095 switch(*desc)
5097 case RPC_FC_RP:
5098 case RPC_FC_UP:
5099 case RPC_FC_OP:
5100 case RPC_FC_FP:
5101 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5102 saved_buffer = pStubMsg->Buffer;
5103 if (pStubMsg->PointerBufferMark)
5105 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5106 pStubMsg->PointerBufferMark = NULL;
5107 pointer_buffer_mark_set = 1;
5109 else
5110 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5112 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5113 if (pointer_buffer_mark_set)
5115 STD_OVERFLOW_CHECK(pStubMsg);
5116 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5117 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5119 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5120 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5121 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5123 pStubMsg->Buffer = saved_buffer + 4;
5125 break;
5126 default:
5127 m(pStubMsg, pMemory, desc);
5130 else FIXME("no marshaller for embedded type %02x\n", *desc);
5132 return NULL;
5135 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5136 unsigned char **ppMemory,
5137 ULONG discriminant,
5138 PFORMAT_STRING pFormat,
5139 unsigned char fMustAlloc)
5141 unsigned short type;
5143 pFormat += 2;
5145 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5146 if(!pFormat)
5147 return NULL;
5149 type = *(const unsigned short*)pFormat;
5150 if((type & 0xff00) == 0x8000)
5152 unsigned char basetype = LOBYTE(type);
5153 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5155 else
5157 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5158 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5159 if (m)
5161 unsigned char *saved_buffer = NULL;
5162 int pointer_buffer_mark_set = 0;
5163 switch(*desc)
5165 case RPC_FC_RP:
5166 case RPC_FC_UP:
5167 case RPC_FC_OP:
5168 case RPC_FC_FP:
5169 **(void***)ppMemory = NULL;
5170 ALIGN_POINTER(pStubMsg->Buffer, 4);
5171 saved_buffer = pStubMsg->Buffer;
5172 if (pStubMsg->PointerBufferMark)
5174 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5175 pStubMsg->PointerBufferMark = NULL;
5176 pointer_buffer_mark_set = 1;
5178 else
5179 pStubMsg->Buffer += 4; /* for pointer ID */
5181 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5183 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5184 saved_buffer, pStubMsg->BufferEnd);
5185 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5188 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5189 if (pointer_buffer_mark_set)
5191 STD_OVERFLOW_CHECK(pStubMsg);
5192 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5193 pStubMsg->Buffer = saved_buffer + 4;
5195 break;
5196 default:
5197 m(pStubMsg, ppMemory, desc, fMustAlloc);
5200 else FIXME("no marshaller for embedded type %02x\n", *desc);
5202 return NULL;
5205 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5206 unsigned char *pMemory,
5207 ULONG discriminant,
5208 PFORMAT_STRING pFormat)
5210 unsigned short type;
5212 pFormat += 2;
5214 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5215 if(!pFormat)
5216 return;
5218 type = *(const unsigned short*)pFormat;
5219 if((type & 0xff00) == 0x8000)
5221 unsigned char basetype = LOBYTE(type);
5222 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5224 else
5226 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5227 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5228 if (m)
5230 switch(*desc)
5232 case RPC_FC_RP:
5233 case RPC_FC_UP:
5234 case RPC_FC_OP:
5235 case RPC_FC_FP:
5236 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5237 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5238 if (!pStubMsg->IgnoreEmbeddedPointers)
5240 int saved_buffer_length = pStubMsg->BufferLength;
5241 pStubMsg->BufferLength = pStubMsg->PointerLength;
5242 pStubMsg->PointerLength = 0;
5243 if(!pStubMsg->BufferLength)
5244 ERR("BufferLength == 0??\n");
5245 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5246 pStubMsg->PointerLength = pStubMsg->BufferLength;
5247 pStubMsg->BufferLength = saved_buffer_length;
5249 break;
5250 default:
5251 m(pStubMsg, pMemory, desc);
5254 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5258 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5259 ULONG discriminant,
5260 PFORMAT_STRING pFormat)
5262 unsigned short type, size;
5264 size = *(const unsigned short*)pFormat;
5265 pStubMsg->Memory += size;
5266 pFormat += 2;
5268 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5269 if(!pFormat)
5270 return 0;
5272 type = *(const unsigned short*)pFormat;
5273 if((type & 0xff00) == 0x8000)
5275 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5277 else
5279 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5280 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5281 unsigned char *saved_buffer;
5282 if (m)
5284 switch(*desc)
5286 case RPC_FC_RP:
5287 case RPC_FC_UP:
5288 case RPC_FC_OP:
5289 case RPC_FC_FP:
5290 ALIGN_POINTER(pStubMsg->Buffer, 4);
5291 saved_buffer = pStubMsg->Buffer;
5292 safe_buffer_increment(pStubMsg, 4);
5293 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5294 pStubMsg->MemorySize += 4;
5295 if (!pStubMsg->IgnoreEmbeddedPointers)
5296 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5297 break;
5298 default:
5299 return m(pStubMsg, desc);
5302 else FIXME("no marshaller for embedded type %02x\n", *desc);
5305 TRACE("size %d\n", size);
5306 return size;
5309 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5310 unsigned char *pMemory,
5311 ULONG discriminant,
5312 PFORMAT_STRING pFormat)
5314 unsigned short type;
5316 pFormat += 2;
5318 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5319 if(!pFormat)
5320 return;
5322 type = *(const unsigned short*)pFormat;
5323 if((type & 0xff00) != 0x8000)
5325 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5326 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5327 if (m)
5329 switch(*desc)
5331 case RPC_FC_RP:
5332 case RPC_FC_UP:
5333 case RPC_FC_OP:
5334 case RPC_FC_FP:
5335 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5336 break;
5337 default:
5338 m(pStubMsg, pMemory, desc);
5344 /***********************************************************************
5345 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5347 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5348 unsigned char *pMemory,
5349 PFORMAT_STRING pFormat)
5351 unsigned char switch_type;
5352 unsigned char increment;
5353 ULONG switch_value;
5355 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5356 pFormat++;
5358 switch_type = *pFormat & 0xf;
5359 increment = (*pFormat & 0xf0) >> 4;
5360 pFormat++;
5362 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5364 switch_value = get_discriminant(switch_type, pMemory);
5365 TRACE("got switch value 0x%x\n", switch_value);
5367 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5368 pMemory += increment;
5370 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5373 /***********************************************************************
5374 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5376 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5377 unsigned char **ppMemory,
5378 PFORMAT_STRING pFormat,
5379 unsigned char fMustAlloc)
5381 unsigned char switch_type;
5382 unsigned char increment;
5383 ULONG switch_value;
5384 unsigned short size;
5385 unsigned char *pMemoryArm;
5387 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5388 pFormat++;
5390 switch_type = *pFormat & 0xf;
5391 increment = (*pFormat & 0xf0) >> 4;
5392 pFormat++;
5394 ALIGN_POINTER(pStubMsg->Buffer, increment);
5395 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5396 TRACE("got switch value 0x%x\n", switch_value);
5398 size = *(const unsigned short*)pFormat + increment;
5399 if(!*ppMemory || fMustAlloc)
5400 *ppMemory = NdrAllocate(pStubMsg, size);
5402 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5403 pMemoryArm = *ppMemory + increment;
5405 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5408 /***********************************************************************
5409 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5411 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5412 unsigned char *pMemory,
5413 PFORMAT_STRING pFormat)
5415 unsigned char switch_type;
5416 unsigned char increment;
5417 ULONG switch_value;
5419 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5420 pFormat++;
5422 switch_type = *pFormat & 0xf;
5423 increment = (*pFormat & 0xf0) >> 4;
5424 pFormat++;
5426 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5427 switch_value = get_discriminant(switch_type, pMemory);
5428 TRACE("got switch value 0x%x\n", switch_value);
5430 /* Add discriminant size */
5431 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5432 pMemory += increment;
5434 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5437 /***********************************************************************
5438 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5440 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5441 PFORMAT_STRING pFormat)
5443 unsigned char switch_type;
5444 unsigned char increment;
5445 ULONG switch_value;
5447 switch_type = *pFormat & 0xf;
5448 increment = (*pFormat & 0xf0) >> 4;
5449 pFormat++;
5451 ALIGN_POINTER(pStubMsg->Buffer, increment);
5452 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5453 TRACE("got switch value 0x%x\n", switch_value);
5455 pStubMsg->Memory += increment;
5457 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5460 /***********************************************************************
5461 * NdrEncapsulatedUnionFree [RPCRT4.@]
5463 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5464 unsigned char *pMemory,
5465 PFORMAT_STRING pFormat)
5467 unsigned char switch_type;
5468 unsigned char increment;
5469 ULONG switch_value;
5471 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5472 pFormat++;
5474 switch_type = *pFormat & 0xf;
5475 increment = (*pFormat & 0xf0) >> 4;
5476 pFormat++;
5478 switch_value = get_discriminant(switch_type, pMemory);
5479 TRACE("got switch value 0x%x\n", switch_value);
5481 pMemory += increment;
5483 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5486 /***********************************************************************
5487 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5489 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5490 unsigned char *pMemory,
5491 PFORMAT_STRING pFormat)
5493 unsigned char switch_type;
5495 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5496 pFormat++;
5498 switch_type = *pFormat;
5499 pFormat++;
5501 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5502 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5503 /* Marshall discriminant */
5504 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5506 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5509 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5510 PFORMAT_STRING *ppFormat)
5512 long discriminant = 0;
5514 switch(**ppFormat)
5516 case RPC_FC_BYTE:
5517 case RPC_FC_CHAR:
5518 case RPC_FC_SMALL:
5519 case RPC_FC_USMALL:
5521 UCHAR d;
5522 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5523 discriminant = d;
5524 break;
5526 case RPC_FC_WCHAR:
5527 case RPC_FC_SHORT:
5528 case RPC_FC_USHORT:
5530 USHORT d;
5531 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5532 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5533 discriminant = d;
5534 break;
5536 case RPC_FC_LONG:
5537 case RPC_FC_ULONG:
5539 ULONG d;
5540 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5541 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5542 discriminant = d;
5543 break;
5545 default:
5546 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5548 (*ppFormat)++;
5550 if (pStubMsg->fHasNewCorrDesc)
5551 *ppFormat += 6;
5552 else
5553 *ppFormat += 4;
5554 return discriminant;
5557 /**********************************************************************
5558 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5560 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5561 unsigned char **ppMemory,
5562 PFORMAT_STRING pFormat,
5563 unsigned char fMustAlloc)
5565 long discriminant;
5566 unsigned short size;
5568 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5569 pFormat++;
5571 /* Unmarshall discriminant */
5572 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5573 TRACE("unmarshalled discriminant %lx\n", discriminant);
5575 pFormat += *(const SHORT*)pFormat;
5577 size = *(const unsigned short*)pFormat;
5579 if(!*ppMemory || fMustAlloc)
5580 *ppMemory = NdrAllocate(pStubMsg, size);
5582 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5585 /***********************************************************************
5586 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5588 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5589 unsigned char *pMemory,
5590 PFORMAT_STRING pFormat)
5592 unsigned char switch_type;
5594 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5595 pFormat++;
5597 switch_type = *pFormat;
5598 pFormat++;
5600 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5601 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5602 /* Add discriminant size */
5603 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5605 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5608 /***********************************************************************
5609 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5611 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5612 PFORMAT_STRING pFormat)
5614 ULONG discriminant;
5616 pFormat++;
5617 /* Unmarshall discriminant */
5618 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5619 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5621 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5624 /***********************************************************************
5625 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5627 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5628 unsigned char *pMemory,
5629 PFORMAT_STRING pFormat)
5631 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5632 pFormat++;
5633 pFormat++;
5635 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5636 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5638 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5641 /***********************************************************************
5642 * NdrByteCountPointerMarshall [RPCRT4.@]
5644 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5645 unsigned char *pMemory,
5646 PFORMAT_STRING pFormat)
5648 FIXME("stub\n");
5649 return NULL;
5652 /***********************************************************************
5653 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5655 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5656 unsigned char **ppMemory,
5657 PFORMAT_STRING pFormat,
5658 unsigned char fMustAlloc)
5660 FIXME("stub\n");
5661 return NULL;
5664 /***********************************************************************
5665 * NdrByteCountPointerBufferSize [RPCRT4.@]
5667 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5668 unsigned char *pMemory,
5669 PFORMAT_STRING pFormat)
5671 FIXME("stub\n");
5674 /***********************************************************************
5675 * NdrByteCountPointerMemorySize [RPCRT4.@]
5677 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5678 PFORMAT_STRING pFormat)
5680 FIXME("stub\n");
5681 return 0;
5684 /***********************************************************************
5685 * NdrByteCountPointerFree [RPCRT4.@]
5687 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5688 unsigned char *pMemory,
5689 PFORMAT_STRING pFormat)
5691 FIXME("stub\n");
5694 /***********************************************************************
5695 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5697 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5698 unsigned char *pMemory,
5699 PFORMAT_STRING pFormat)
5701 FIXME("stub\n");
5702 return NULL;
5705 /***********************************************************************
5706 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5708 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5709 unsigned char **ppMemory,
5710 PFORMAT_STRING pFormat,
5711 unsigned char fMustAlloc)
5713 FIXME("stub\n");
5714 return NULL;
5717 /***********************************************************************
5718 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5720 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5721 unsigned char *pMemory,
5722 PFORMAT_STRING pFormat)
5724 FIXME("stub\n");
5727 /***********************************************************************
5728 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5730 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5731 PFORMAT_STRING pFormat)
5733 FIXME("stub\n");
5734 return 0;
5737 /***********************************************************************
5738 * NdrXmitOrRepAsFree [RPCRT4.@]
5740 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5741 unsigned char *pMemory,
5742 PFORMAT_STRING pFormat)
5744 FIXME("stub\n");
5747 /***********************************************************************
5748 * NdrRangeMarshall [internal]
5750 unsigned char *WINAPI NdrRangeMarshall(
5751 PMIDL_STUB_MESSAGE pStubMsg,
5752 unsigned char *pMemory,
5753 PFORMAT_STRING pFormat)
5755 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5756 unsigned char base_type;
5758 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5760 if (pRange->type != RPC_FC_RANGE)
5762 ERR("invalid format type %x\n", pRange->type);
5763 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5764 return NULL;
5767 base_type = pRange->flags_type & 0xf;
5769 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5772 /***********************************************************************
5773 * NdrRangeUnmarshall
5775 unsigned char *WINAPI NdrRangeUnmarshall(
5776 PMIDL_STUB_MESSAGE pStubMsg,
5777 unsigned char **ppMemory,
5778 PFORMAT_STRING pFormat,
5779 unsigned char fMustAlloc)
5781 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5782 unsigned char base_type;
5784 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5786 if (pRange->type != RPC_FC_RANGE)
5788 ERR("invalid format type %x\n", pRange->type);
5789 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5790 return NULL;
5792 base_type = pRange->flags_type & 0xf;
5794 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5795 base_type, pRange->low_value, pRange->high_value);
5797 #define RANGE_UNMARSHALL(type, format_spec) \
5798 do \
5800 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5801 if (fMustAlloc || !*ppMemory) \
5802 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5803 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5805 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5806 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5807 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5809 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5810 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5812 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5813 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5814 (type)pRange->high_value); \
5815 RpcRaiseException(RPC_S_INVALID_BOUND); \
5816 return NULL; \
5818 TRACE("*ppMemory: %p\n", *ppMemory); \
5819 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5820 pStubMsg->Buffer += sizeof(type); \
5821 } while (0)
5823 switch(base_type)
5825 case RPC_FC_CHAR:
5826 case RPC_FC_SMALL:
5827 RANGE_UNMARSHALL(UCHAR, "%d");
5828 TRACE("value: 0x%02x\n", **ppMemory);
5829 break;
5830 case RPC_FC_BYTE:
5831 case RPC_FC_USMALL:
5832 RANGE_UNMARSHALL(CHAR, "%u");
5833 TRACE("value: 0x%02x\n", **ppMemory);
5834 break;
5835 case RPC_FC_WCHAR: /* FIXME: valid? */
5836 case RPC_FC_USHORT:
5837 RANGE_UNMARSHALL(USHORT, "%u");
5838 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5839 break;
5840 case RPC_FC_SHORT:
5841 RANGE_UNMARSHALL(SHORT, "%d");
5842 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5843 break;
5844 case RPC_FC_LONG:
5845 RANGE_UNMARSHALL(LONG, "%d");
5846 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5847 break;
5848 case RPC_FC_ULONG:
5849 RANGE_UNMARSHALL(ULONG, "%u");
5850 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5851 break;
5852 case RPC_FC_ENUM16:
5853 case RPC_FC_ENUM32:
5854 FIXME("Unhandled enum type\n");
5855 break;
5856 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5857 case RPC_FC_FLOAT:
5858 case RPC_FC_DOUBLE:
5859 case RPC_FC_HYPER:
5860 default:
5861 ERR("invalid range base type: 0x%02x\n", base_type);
5862 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5865 return NULL;
5868 /***********************************************************************
5869 * NdrRangeBufferSize [internal]
5871 void WINAPI NdrRangeBufferSize(
5872 PMIDL_STUB_MESSAGE pStubMsg,
5873 unsigned char *pMemory,
5874 PFORMAT_STRING pFormat)
5876 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5877 unsigned char base_type;
5879 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5881 if (pRange->type != RPC_FC_RANGE)
5883 ERR("invalid format type %x\n", pRange->type);
5884 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5886 base_type = pRange->flags_type & 0xf;
5888 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5891 /***********************************************************************
5892 * NdrRangeMemorySize [internal]
5894 ULONG WINAPI NdrRangeMemorySize(
5895 PMIDL_STUB_MESSAGE pStubMsg,
5896 PFORMAT_STRING pFormat)
5898 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5899 unsigned char base_type;
5901 if (pRange->type != RPC_FC_RANGE)
5903 ERR("invalid format type %x\n", pRange->type);
5904 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5905 return 0;
5907 base_type = pRange->flags_type & 0xf;
5909 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5912 /***********************************************************************
5913 * NdrRangeFree [internal]
5915 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5916 unsigned char *pMemory,
5917 PFORMAT_STRING pFormat)
5919 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5921 /* nothing to do */
5924 /***********************************************************************
5925 * NdrBaseTypeMarshall [internal]
5927 static unsigned char *WINAPI NdrBaseTypeMarshall(
5928 PMIDL_STUB_MESSAGE pStubMsg,
5929 unsigned char *pMemory,
5930 PFORMAT_STRING pFormat)
5932 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5934 switch(*pFormat)
5936 case RPC_FC_BYTE:
5937 case RPC_FC_CHAR:
5938 case RPC_FC_SMALL:
5939 case RPC_FC_USMALL:
5940 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5941 TRACE("value: 0x%02x\n", *pMemory);
5942 break;
5943 case RPC_FC_WCHAR:
5944 case RPC_FC_SHORT:
5945 case RPC_FC_USHORT:
5946 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5947 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5948 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5949 break;
5950 case RPC_FC_LONG:
5951 case RPC_FC_ULONG:
5952 case RPC_FC_ERROR_STATUS_T:
5953 case RPC_FC_ENUM32:
5954 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
5955 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5956 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5957 break;
5958 case RPC_FC_FLOAT:
5959 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
5960 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5961 break;
5962 case RPC_FC_DOUBLE:
5963 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
5964 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5965 break;
5966 case RPC_FC_HYPER:
5967 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
5968 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5969 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5970 break;
5971 case RPC_FC_ENUM16:
5972 /* only 16-bits on the wire, so do a sanity check */
5973 if (*(UINT *)pMemory > SHRT_MAX)
5974 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5975 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5976 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5977 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5978 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5979 pStubMsg->Buffer += sizeof(USHORT);
5980 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5981 break;
5982 case RPC_FC_IGNORE:
5983 break;
5984 default:
5985 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5988 /* FIXME: what is the correct return value? */
5989 return NULL;
5992 /***********************************************************************
5993 * NdrBaseTypeUnmarshall [internal]
5995 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5996 PMIDL_STUB_MESSAGE pStubMsg,
5997 unsigned char **ppMemory,
5998 PFORMAT_STRING pFormat,
5999 unsigned char fMustAlloc)
6001 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6003 #define BASE_TYPE_UNMARSHALL(type) \
6004 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6005 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6007 *ppMemory = pStubMsg->Buffer; \
6008 TRACE("*ppMemory: %p\n", *ppMemory); \
6009 safe_buffer_increment(pStubMsg, sizeof(type)); \
6011 else \
6013 if (fMustAlloc) \
6014 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6015 TRACE("*ppMemory: %p\n", *ppMemory); \
6016 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6019 switch(*pFormat)
6021 case RPC_FC_BYTE:
6022 case RPC_FC_CHAR:
6023 case RPC_FC_SMALL:
6024 case RPC_FC_USMALL:
6025 BASE_TYPE_UNMARSHALL(UCHAR);
6026 TRACE("value: 0x%02x\n", **ppMemory);
6027 break;
6028 case RPC_FC_WCHAR:
6029 case RPC_FC_SHORT:
6030 case RPC_FC_USHORT:
6031 BASE_TYPE_UNMARSHALL(USHORT);
6032 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6033 break;
6034 case RPC_FC_LONG:
6035 case RPC_FC_ULONG:
6036 case RPC_FC_ERROR_STATUS_T:
6037 case RPC_FC_ENUM32:
6038 BASE_TYPE_UNMARSHALL(ULONG);
6039 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6040 break;
6041 case RPC_FC_FLOAT:
6042 BASE_TYPE_UNMARSHALL(float);
6043 TRACE("value: %f\n", **(float **)ppMemory);
6044 break;
6045 case RPC_FC_DOUBLE:
6046 BASE_TYPE_UNMARSHALL(double);
6047 TRACE("value: %f\n", **(double **)ppMemory);
6048 break;
6049 case RPC_FC_HYPER:
6050 BASE_TYPE_UNMARSHALL(ULONGLONG);
6051 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6052 break;
6053 case RPC_FC_ENUM16:
6054 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6055 if (fMustAlloc || !*ppMemory)
6056 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6057 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6058 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6059 TRACE("*ppMemory: %p\n", *ppMemory);
6060 /* 16-bits on the wire, but int in memory */
6061 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6062 pStubMsg->Buffer += sizeof(USHORT);
6063 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6064 break;
6065 case RPC_FC_IGNORE:
6066 break;
6067 default:
6068 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6070 #undef BASE_TYPE_UNMARSHALL
6072 /* FIXME: what is the correct return value? */
6074 return NULL;
6077 /***********************************************************************
6078 * NdrBaseTypeBufferSize [internal]
6080 static void WINAPI NdrBaseTypeBufferSize(
6081 PMIDL_STUB_MESSAGE pStubMsg,
6082 unsigned char *pMemory,
6083 PFORMAT_STRING pFormat)
6085 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6087 switch(*pFormat)
6089 case RPC_FC_BYTE:
6090 case RPC_FC_CHAR:
6091 case RPC_FC_SMALL:
6092 case RPC_FC_USMALL:
6093 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6094 break;
6095 case RPC_FC_WCHAR:
6096 case RPC_FC_SHORT:
6097 case RPC_FC_USHORT:
6098 case RPC_FC_ENUM16:
6099 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6100 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6101 break;
6102 case RPC_FC_LONG:
6103 case RPC_FC_ULONG:
6104 case RPC_FC_ENUM32:
6105 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6106 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6107 break;
6108 case RPC_FC_FLOAT:
6109 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6110 safe_buffer_length_increment(pStubMsg, sizeof(float));
6111 break;
6112 case RPC_FC_DOUBLE:
6113 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6114 safe_buffer_length_increment(pStubMsg, sizeof(double));
6115 break;
6116 case RPC_FC_HYPER:
6117 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6118 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6119 break;
6120 case RPC_FC_ERROR_STATUS_T:
6121 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6122 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6123 break;
6124 case RPC_FC_IGNORE:
6125 break;
6126 default:
6127 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6131 /***********************************************************************
6132 * NdrBaseTypeMemorySize [internal]
6134 static ULONG WINAPI NdrBaseTypeMemorySize(
6135 PMIDL_STUB_MESSAGE pStubMsg,
6136 PFORMAT_STRING pFormat)
6138 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6140 switch(*pFormat)
6142 case RPC_FC_BYTE:
6143 case RPC_FC_CHAR:
6144 case RPC_FC_SMALL:
6145 case RPC_FC_USMALL:
6146 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6147 pStubMsg->MemorySize += sizeof(UCHAR);
6148 return sizeof(UCHAR);
6149 case RPC_FC_WCHAR:
6150 case RPC_FC_SHORT:
6151 case RPC_FC_USHORT:
6152 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6153 pStubMsg->MemorySize += sizeof(USHORT);
6154 return sizeof(USHORT);
6155 case RPC_FC_LONG:
6156 case RPC_FC_ULONG:
6157 case RPC_FC_ENUM32:
6158 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6159 pStubMsg->MemorySize += sizeof(ULONG);
6160 return sizeof(ULONG);
6161 case RPC_FC_FLOAT:
6162 safe_buffer_increment(pStubMsg, sizeof(float));
6163 pStubMsg->MemorySize += sizeof(float);
6164 return sizeof(float);
6165 case RPC_FC_DOUBLE:
6166 safe_buffer_increment(pStubMsg, sizeof(double));
6167 pStubMsg->MemorySize += sizeof(double);
6168 return sizeof(double);
6169 case RPC_FC_HYPER:
6170 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6171 pStubMsg->MemorySize += sizeof(ULONGLONG);
6172 return sizeof(ULONGLONG);
6173 case RPC_FC_ERROR_STATUS_T:
6174 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6175 pStubMsg->MemorySize += sizeof(error_status_t);
6176 return sizeof(error_status_t);
6177 case RPC_FC_ENUM16:
6178 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6179 pStubMsg->MemorySize += sizeof(UINT);
6180 return sizeof(UINT);
6181 case RPC_FC_IGNORE:
6182 pStubMsg->MemorySize += sizeof(void *);
6183 return sizeof(void *);
6184 default:
6185 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6186 return 0;
6190 /***********************************************************************
6191 * NdrBaseTypeFree [internal]
6193 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6194 unsigned char *pMemory,
6195 PFORMAT_STRING pFormat)
6197 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6199 /* nothing to do */
6202 /***********************************************************************
6203 * NdrContextHandleBufferSize [internal]
6205 static void WINAPI NdrContextHandleBufferSize(
6206 PMIDL_STUB_MESSAGE pStubMsg,
6207 unsigned char *pMemory,
6208 PFORMAT_STRING pFormat)
6210 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6212 if (*pFormat != RPC_FC_BIND_CONTEXT)
6214 ERR("invalid format type %x\n", *pFormat);
6215 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6217 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6218 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6221 /***********************************************************************
6222 * NdrContextHandleMarshall [internal]
6224 static unsigned char *WINAPI NdrContextHandleMarshall(
6225 PMIDL_STUB_MESSAGE pStubMsg,
6226 unsigned char *pMemory,
6227 PFORMAT_STRING pFormat)
6229 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6231 if (*pFormat != RPC_FC_BIND_CONTEXT)
6233 ERR("invalid format type %x\n", *pFormat);
6234 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6236 TRACE("flags: 0x%02x\n", pFormat[1]);
6238 if (pFormat[1] & 0x80)
6239 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6240 else
6241 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6243 return NULL;
6246 /***********************************************************************
6247 * NdrContextHandleUnmarshall [internal]
6249 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6250 PMIDL_STUB_MESSAGE pStubMsg,
6251 unsigned char **ppMemory,
6252 PFORMAT_STRING pFormat,
6253 unsigned char fMustAlloc)
6255 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6256 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6258 if (*pFormat != RPC_FC_BIND_CONTEXT)
6260 ERR("invalid format type %x\n", *pFormat);
6261 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6263 TRACE("flags: 0x%02x\n", pFormat[1]);
6265 /* [out]-only or [ret] param */
6266 if ((pFormat[1] & 0x60) == 0x20)
6267 **(NDR_CCONTEXT **)ppMemory = NULL;
6268 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6270 return NULL;
6273 /***********************************************************************
6274 * NdrClientContextMarshall [RPCRT4.@]
6276 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6277 NDR_CCONTEXT ContextHandle,
6278 int fCheck)
6280 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6282 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6284 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6286 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6287 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6288 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6291 /* FIXME: what does fCheck do? */
6292 NDRCContextMarshall(ContextHandle,
6293 pStubMsg->Buffer);
6295 pStubMsg->Buffer += cbNDRContext;
6298 /***********************************************************************
6299 * NdrClientContextUnmarshall [RPCRT4.@]
6301 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6302 NDR_CCONTEXT * pContextHandle,
6303 RPC_BINDING_HANDLE BindHandle)
6305 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6307 ALIGN_POINTER(pStubMsg->Buffer, 4);
6309 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6310 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6312 NDRCContextUnmarshall(pContextHandle,
6313 BindHandle,
6314 pStubMsg->Buffer,
6315 pStubMsg->RpcMsg->DataRepresentation);
6317 pStubMsg->Buffer += cbNDRContext;
6320 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6321 NDR_SCONTEXT ContextHandle,
6322 NDR_RUNDOWN RundownRoutine )
6324 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6326 ALIGN_POINTER(pStubMsg->Buffer, 4);
6328 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6330 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6331 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6332 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6335 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6336 pStubMsg->Buffer, RundownRoutine, NULL,
6337 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6338 pStubMsg->Buffer += cbNDRContext;
6341 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6343 NDR_SCONTEXT ContextHandle;
6345 TRACE("(%p)\n", pStubMsg);
6347 ALIGN_POINTER(pStubMsg->Buffer, 4);
6349 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6351 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6352 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6353 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6356 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6357 pStubMsg->Buffer,
6358 pStubMsg->RpcMsg->DataRepresentation,
6359 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6360 pStubMsg->Buffer += cbNDRContext;
6362 return ContextHandle;
6365 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6366 unsigned char* pMemory,
6367 PFORMAT_STRING pFormat)
6369 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6372 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6373 PFORMAT_STRING pFormat)
6375 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6376 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6378 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6380 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6381 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6382 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6383 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6384 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6386 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6387 if_id = &sif->InterfaceId;
6390 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6391 pStubMsg->RpcMsg->DataRepresentation, if_id,
6392 flags);
6395 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6396 NDR_SCONTEXT ContextHandle,
6397 NDR_RUNDOWN RundownRoutine,
6398 PFORMAT_STRING pFormat)
6400 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6401 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6403 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6405 ALIGN_POINTER(pStubMsg->Buffer, 4);
6407 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6409 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6410 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6411 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6414 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6415 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6416 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6417 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6418 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6420 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6421 if_id = &sif->InterfaceId;
6424 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6425 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6426 pStubMsg->Buffer += cbNDRContext;
6429 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6430 PFORMAT_STRING pFormat)
6432 NDR_SCONTEXT ContextHandle;
6433 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6434 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6436 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6438 ALIGN_POINTER(pStubMsg->Buffer, 4);
6440 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6442 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6443 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6444 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6447 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6448 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6449 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6450 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6451 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6453 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6454 if_id = &sif->InterfaceId;
6457 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6458 pStubMsg->Buffer,
6459 pStubMsg->RpcMsg->DataRepresentation,
6460 if_id, flags);
6461 pStubMsg->Buffer += cbNDRContext;
6463 return ContextHandle;
6466 /***********************************************************************
6467 * NdrCorrelationInitialize [RPCRT4.@]
6469 * Initializes correlation validity checking.
6471 * PARAMS
6472 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6473 * pMemory [I] Pointer to memory to use as a cache.
6474 * CacheSize [I] Size of the memory pointed to by pMemory.
6475 * Flags [I] Reserved. Set to zero.
6477 * RETURNS
6478 * Nothing.
6480 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6482 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6483 pStubMsg->fHasNewCorrDesc = TRUE;
6486 /***********************************************************************
6487 * NdrCorrelationPass [RPCRT4.@]
6489 * Performs correlation validity checking.
6491 * PARAMS
6492 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6494 * RETURNS
6495 * Nothing.
6497 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6499 FIXME("(%p): stub\n", pStubMsg);
6502 /***********************************************************************
6503 * NdrCorrelationFree [RPCRT4.@]
6505 * Frees any resources used while unmarshalling parameters that need
6506 * correlation validity checking.
6508 * PARAMS
6509 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6511 * RETURNS
6512 * Nothing.
6514 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6516 FIXME("(%p): stub\n", pStubMsg);