push e263afdf8dbf9f9408e8594e045d25c4af1d55cd
[wine/hacks.git] / dlls / rpcrt4 / ndr_marshall.c
blob836410b5816cc331dc834567a01dff09316b5cf3
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 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2257 if (*pPointer != RPC_FC_RP)
2258 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2259 saved_buffer = pStubMsg->Buffer;
2260 if (pStubMsg->PointerBufferMark)
2262 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2263 pStubMsg->PointerBufferMark = NULL;
2264 pointer_buffer_mark_set = 1;
2266 else if (*pPointer != RPC_FC_RP)
2267 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2268 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2269 if (pointer_buffer_mark_set)
2271 STD_OVERFLOW_CHECK(pStubMsg);
2272 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2273 pStubMsg->Buffer = saved_buffer;
2274 if (*pPointer != RPC_FC_RP)
2275 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2277 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2278 pPointer += 4;
2279 pMemory += 4;
2280 break;
2282 case RPC_FC_ALIGNM4:
2283 ALIGN_POINTER(pMemory, 4);
2284 break;
2285 case RPC_FC_ALIGNM8:
2286 ALIGN_POINTER(pMemory, 8);
2287 break;
2288 case RPC_FC_STRUCTPAD1:
2289 case RPC_FC_STRUCTPAD2:
2290 case RPC_FC_STRUCTPAD3:
2291 case RPC_FC_STRUCTPAD4:
2292 case RPC_FC_STRUCTPAD5:
2293 case RPC_FC_STRUCTPAD6:
2294 case RPC_FC_STRUCTPAD7:
2295 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2296 break;
2297 case RPC_FC_EMBEDDED_COMPLEX:
2298 pMemory += pFormat[1];
2299 pFormat += 2;
2300 desc = pFormat + *(const SHORT*)pFormat;
2301 size = EmbeddedComplexSize(pStubMsg, desc);
2302 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2303 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2304 if (m)
2306 /* for some reason interface pointers aren't generated as
2307 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2308 * they still need the derefencing treatment that pointers are
2309 * given */
2310 if (*desc == RPC_FC_IP)
2311 m(pStubMsg, *(unsigned char **)pMemory, desc);
2312 else
2313 m(pStubMsg, pMemory, desc);
2315 else FIXME("no marshaller for embedded type %02x\n", *desc);
2316 pMemory += size;
2317 pFormat += 2;
2318 continue;
2319 case RPC_FC_PAD:
2320 break;
2321 default:
2322 FIXME("unhandled format 0x%02x\n", *pFormat);
2324 pFormat++;
2327 return pMemory;
2330 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2331 unsigned char *pMemory,
2332 PFORMAT_STRING pFormat,
2333 PFORMAT_STRING pPointer,
2334 unsigned char fMustAlloc)
2336 PFORMAT_STRING desc;
2337 NDR_UNMARSHALL m;
2338 unsigned long size;
2340 while (*pFormat != RPC_FC_END) {
2341 switch (*pFormat) {
2342 case RPC_FC_BYTE:
2343 case RPC_FC_CHAR:
2344 case RPC_FC_SMALL:
2345 case RPC_FC_USMALL:
2346 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2347 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2348 pMemory += 1;
2349 break;
2350 case RPC_FC_WCHAR:
2351 case RPC_FC_SHORT:
2352 case RPC_FC_USHORT:
2353 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2354 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2355 pMemory += 2;
2356 break;
2357 case RPC_FC_ENUM16:
2358 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2359 *(DWORD*)pMemory &= 0xffff;
2360 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2361 if (32767 < *(DWORD*)pMemory)
2362 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2363 pMemory += 4;
2364 break;
2365 case RPC_FC_LONG:
2366 case RPC_FC_ULONG:
2367 case RPC_FC_ENUM32:
2368 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2369 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2370 pMemory += 4;
2371 break;
2372 case RPC_FC_HYPER:
2373 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2374 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2375 pMemory += 8;
2376 break;
2377 case RPC_FC_POINTER:
2379 unsigned char *saved_buffer;
2380 int pointer_buffer_mark_set = 0;
2381 TRACE("pointer => %p\n", pMemory);
2382 if (*pPointer != RPC_FC_RP)
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 if (*pPointer != RPC_FC_RP)
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 pStubMsg->Buffer = saved_buffer;
2400 if (*pPointer != RPC_FC_RP)
2401 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2403 pPointer += 4;
2404 pMemory += 4;
2405 break;
2407 case RPC_FC_ALIGNM4:
2408 ALIGN_POINTER_CLEAR(pMemory, 4);
2409 break;
2410 case RPC_FC_ALIGNM8:
2411 ALIGN_POINTER_CLEAR(pMemory, 8);
2412 break;
2413 case RPC_FC_STRUCTPAD1:
2414 case RPC_FC_STRUCTPAD2:
2415 case RPC_FC_STRUCTPAD3:
2416 case RPC_FC_STRUCTPAD4:
2417 case RPC_FC_STRUCTPAD5:
2418 case RPC_FC_STRUCTPAD6:
2419 case RPC_FC_STRUCTPAD7:
2420 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2421 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2422 break;
2423 case RPC_FC_EMBEDDED_COMPLEX:
2424 pMemory += pFormat[1];
2425 pFormat += 2;
2426 desc = pFormat + *(const SHORT*)pFormat;
2427 size = EmbeddedComplexSize(pStubMsg, desc);
2428 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2429 if (fMustAlloc)
2430 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2431 * since the type is part of the memory block that is encompassed by
2432 * the whole complex type. Memory is forced to allocate when pointers
2433 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2434 * clearing the memory we pass in to the unmarshaller */
2435 memset(pMemory, 0, size);
2436 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2437 if (m)
2439 /* for some reason interface pointers aren't generated as
2440 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2441 * they still need the derefencing treatment that pointers are
2442 * given */
2443 if (*desc == RPC_FC_IP)
2444 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2445 else
2446 m(pStubMsg, &pMemory, desc, FALSE);
2448 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2449 pMemory += size;
2450 pFormat += 2;
2451 continue;
2452 case RPC_FC_PAD:
2453 break;
2454 default:
2455 FIXME("unhandled format %d\n", *pFormat);
2457 pFormat++;
2460 return pMemory;
2463 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2464 unsigned char *pMemory,
2465 PFORMAT_STRING pFormat,
2466 PFORMAT_STRING pPointer)
2468 PFORMAT_STRING desc;
2469 NDR_BUFFERSIZE m;
2470 unsigned long size;
2472 while (*pFormat != RPC_FC_END) {
2473 switch (*pFormat) {
2474 case RPC_FC_BYTE:
2475 case RPC_FC_CHAR:
2476 case RPC_FC_SMALL:
2477 case RPC_FC_USMALL:
2478 safe_buffer_length_increment(pStubMsg, 1);
2479 pMemory += 1;
2480 break;
2481 case RPC_FC_WCHAR:
2482 case RPC_FC_SHORT:
2483 case RPC_FC_USHORT:
2484 safe_buffer_length_increment(pStubMsg, 2);
2485 pMemory += 2;
2486 break;
2487 case RPC_FC_ENUM16:
2488 safe_buffer_length_increment(pStubMsg, 2);
2489 pMemory += 4;
2490 break;
2491 case RPC_FC_LONG:
2492 case RPC_FC_ULONG:
2493 case RPC_FC_ENUM32:
2494 safe_buffer_length_increment(pStubMsg, 4);
2495 pMemory += 4;
2496 break;
2497 case RPC_FC_HYPER:
2498 safe_buffer_length_increment(pStubMsg, 8);
2499 pMemory += 8;
2500 break;
2501 case RPC_FC_POINTER:
2502 if (!pStubMsg->IgnoreEmbeddedPointers)
2504 int saved_buffer_length = pStubMsg->BufferLength;
2505 pStubMsg->BufferLength = pStubMsg->PointerLength;
2506 pStubMsg->PointerLength = 0;
2507 if(!pStubMsg->BufferLength)
2508 ERR("BufferLength == 0??\n");
2509 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2510 pStubMsg->PointerLength = pStubMsg->BufferLength;
2511 pStubMsg->BufferLength = saved_buffer_length;
2513 if (*pPointer != RPC_FC_RP)
2515 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2516 safe_buffer_length_increment(pStubMsg, 4);
2518 pPointer += 4;
2519 pMemory += 4;
2520 break;
2521 case RPC_FC_ALIGNM4:
2522 ALIGN_POINTER(pMemory, 4);
2523 break;
2524 case RPC_FC_ALIGNM8:
2525 ALIGN_POINTER(pMemory, 8);
2526 break;
2527 case RPC_FC_STRUCTPAD1:
2528 case RPC_FC_STRUCTPAD2:
2529 case RPC_FC_STRUCTPAD3:
2530 case RPC_FC_STRUCTPAD4:
2531 case RPC_FC_STRUCTPAD5:
2532 case RPC_FC_STRUCTPAD6:
2533 case RPC_FC_STRUCTPAD7:
2534 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2535 break;
2536 case RPC_FC_EMBEDDED_COMPLEX:
2537 pMemory += pFormat[1];
2538 pFormat += 2;
2539 desc = pFormat + *(const SHORT*)pFormat;
2540 size = EmbeddedComplexSize(pStubMsg, desc);
2541 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2542 if (m)
2544 /* for some reason interface pointers aren't generated as
2545 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2546 * they still need the derefencing treatment that pointers are
2547 * given */
2548 if (*desc == RPC_FC_IP)
2549 m(pStubMsg, *(unsigned char **)pMemory, desc);
2550 else
2551 m(pStubMsg, pMemory, desc);
2553 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2554 pMemory += size;
2555 pFormat += 2;
2556 continue;
2557 case RPC_FC_PAD:
2558 break;
2559 default:
2560 FIXME("unhandled format 0x%02x\n", *pFormat);
2562 pFormat++;
2565 return pMemory;
2568 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2569 unsigned char *pMemory,
2570 PFORMAT_STRING pFormat,
2571 PFORMAT_STRING pPointer)
2573 PFORMAT_STRING desc;
2574 NDR_FREE m;
2575 unsigned long size;
2577 while (*pFormat != RPC_FC_END) {
2578 switch (*pFormat) {
2579 case RPC_FC_BYTE:
2580 case RPC_FC_CHAR:
2581 case RPC_FC_SMALL:
2582 case RPC_FC_USMALL:
2583 pMemory += 1;
2584 break;
2585 case RPC_FC_WCHAR:
2586 case RPC_FC_SHORT:
2587 case RPC_FC_USHORT:
2588 pMemory += 2;
2589 break;
2590 case RPC_FC_LONG:
2591 case RPC_FC_ULONG:
2592 case RPC_FC_ENUM16:
2593 case RPC_FC_ENUM32:
2594 pMemory += 4;
2595 break;
2596 case RPC_FC_HYPER:
2597 pMemory += 8;
2598 break;
2599 case RPC_FC_POINTER:
2600 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2601 pPointer += 4;
2602 pMemory += 4;
2603 break;
2604 case RPC_FC_ALIGNM4:
2605 ALIGN_POINTER(pMemory, 4);
2606 break;
2607 case RPC_FC_ALIGNM8:
2608 ALIGN_POINTER(pMemory, 8);
2609 break;
2610 case RPC_FC_STRUCTPAD1:
2611 case RPC_FC_STRUCTPAD2:
2612 case RPC_FC_STRUCTPAD3:
2613 case RPC_FC_STRUCTPAD4:
2614 case RPC_FC_STRUCTPAD5:
2615 case RPC_FC_STRUCTPAD6:
2616 case RPC_FC_STRUCTPAD7:
2617 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2618 break;
2619 case RPC_FC_EMBEDDED_COMPLEX:
2620 pMemory += pFormat[1];
2621 pFormat += 2;
2622 desc = pFormat + *(const SHORT*)pFormat;
2623 size = EmbeddedComplexSize(pStubMsg, desc);
2624 m = NdrFreer[*desc & NDR_TABLE_MASK];
2625 if (m)
2627 /* for some reason interface pointers aren't generated as
2628 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2629 * they still need the derefencing treatment that pointers are
2630 * given */
2631 if (*desc == RPC_FC_IP)
2632 m(pStubMsg, *(unsigned char **)pMemory, desc);
2633 else
2634 m(pStubMsg, pMemory, desc);
2636 pMemory += size;
2637 pFormat += 2;
2638 continue;
2639 case RPC_FC_PAD:
2640 break;
2641 default:
2642 FIXME("unhandled format 0x%02x\n", *pFormat);
2644 pFormat++;
2647 return pMemory;
2650 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2651 PFORMAT_STRING pFormat,
2652 PFORMAT_STRING pPointer)
2654 PFORMAT_STRING desc;
2655 unsigned long size = 0;
2657 while (*pFormat != RPC_FC_END) {
2658 switch (*pFormat) {
2659 case RPC_FC_BYTE:
2660 case RPC_FC_CHAR:
2661 case RPC_FC_SMALL:
2662 case RPC_FC_USMALL:
2663 size += 1;
2664 safe_buffer_increment(pStubMsg, 1);
2665 break;
2666 case RPC_FC_WCHAR:
2667 case RPC_FC_SHORT:
2668 case RPC_FC_USHORT:
2669 size += 2;
2670 safe_buffer_increment(pStubMsg, 2);
2671 break;
2672 case RPC_FC_ENUM16:
2673 size += 4;
2674 safe_buffer_increment(pStubMsg, 2);
2675 break;
2676 case RPC_FC_LONG:
2677 case RPC_FC_ULONG:
2678 case RPC_FC_ENUM32:
2679 size += 4;
2680 safe_buffer_increment(pStubMsg, 4);
2681 break;
2682 case RPC_FC_HYPER:
2683 size += 8;
2684 safe_buffer_increment(pStubMsg, 8);
2685 break;
2686 case RPC_FC_POINTER:
2688 unsigned char *saved_buffer;
2689 int pointer_buffer_mark_set = 0;
2690 if (*pPointer != RPC_FC_RP)
2691 ALIGN_POINTER(pStubMsg->Buffer, 4);
2692 saved_buffer = pStubMsg->Buffer;
2693 if (pStubMsg->PointerBufferMark)
2695 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2696 pStubMsg->PointerBufferMark = NULL;
2697 pointer_buffer_mark_set = 1;
2699 else if (*pPointer != RPC_FC_RP)
2700 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2702 if (!pStubMsg->IgnoreEmbeddedPointers)
2703 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
2704 if (pointer_buffer_mark_set)
2706 STD_OVERFLOW_CHECK(pStubMsg);
2707 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2708 pStubMsg->Buffer = saved_buffer;
2709 if (*pPointer != RPC_FC_RP)
2710 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2712 pPointer += 4;
2713 size += 4;
2714 break;
2716 case RPC_FC_ALIGNM4:
2717 ALIGN_LENGTH(size, 4);
2718 ALIGN_POINTER(pStubMsg->Buffer, 4);
2719 break;
2720 case RPC_FC_ALIGNM8:
2721 ALIGN_LENGTH(size, 8);
2722 ALIGN_POINTER(pStubMsg->Buffer, 8);
2723 break;
2724 case RPC_FC_STRUCTPAD1:
2725 case RPC_FC_STRUCTPAD2:
2726 case RPC_FC_STRUCTPAD3:
2727 case RPC_FC_STRUCTPAD4:
2728 case RPC_FC_STRUCTPAD5:
2729 case RPC_FC_STRUCTPAD6:
2730 case RPC_FC_STRUCTPAD7:
2731 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2732 break;
2733 case RPC_FC_EMBEDDED_COMPLEX:
2734 size += pFormat[1];
2735 pFormat += 2;
2736 desc = pFormat + *(const SHORT*)pFormat;
2737 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2738 pFormat += 2;
2739 continue;
2740 case RPC_FC_PAD:
2741 break;
2742 default:
2743 FIXME("unhandled format 0x%02x\n", *pFormat);
2745 pFormat++;
2748 return size;
2751 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
2752 PFORMAT_STRING pFormat)
2754 PFORMAT_STRING desc;
2755 unsigned long size = 0;
2757 while (*pFormat != RPC_FC_END) {
2758 switch (*pFormat) {
2759 case RPC_FC_BYTE:
2760 case RPC_FC_CHAR:
2761 case RPC_FC_SMALL:
2762 case RPC_FC_USMALL:
2763 size += 1;
2764 break;
2765 case RPC_FC_WCHAR:
2766 case RPC_FC_SHORT:
2767 case RPC_FC_USHORT:
2768 size += 2;
2769 break;
2770 case RPC_FC_LONG:
2771 case RPC_FC_ULONG:
2772 case RPC_FC_ENUM16:
2773 case RPC_FC_ENUM32:
2774 size += 4;
2775 break;
2776 case RPC_FC_HYPER:
2777 size += 8;
2778 break;
2779 case RPC_FC_POINTER:
2780 size += sizeof(void *);
2781 break;
2782 case RPC_FC_ALIGNM4:
2783 ALIGN_LENGTH(size, 4);
2784 break;
2785 case RPC_FC_ALIGNM8:
2786 ALIGN_LENGTH(size, 8);
2787 break;
2788 case RPC_FC_STRUCTPAD1:
2789 case RPC_FC_STRUCTPAD2:
2790 case RPC_FC_STRUCTPAD3:
2791 case RPC_FC_STRUCTPAD4:
2792 case RPC_FC_STRUCTPAD5:
2793 case RPC_FC_STRUCTPAD6:
2794 case RPC_FC_STRUCTPAD7:
2795 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2796 break;
2797 case RPC_FC_EMBEDDED_COMPLEX:
2798 size += pFormat[1];
2799 pFormat += 2;
2800 desc = pFormat + *(const SHORT*)pFormat;
2801 size += EmbeddedComplexSize(pStubMsg, desc);
2802 pFormat += 2;
2803 continue;
2804 case RPC_FC_PAD:
2805 break;
2806 default:
2807 FIXME("unhandled format 0x%02x\n", *pFormat);
2809 pFormat++;
2812 return size;
2815 /***********************************************************************
2816 * NdrComplexStructMarshall [RPCRT4.@]
2818 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2819 unsigned char *pMemory,
2820 PFORMAT_STRING pFormat)
2822 PFORMAT_STRING conf_array = NULL;
2823 PFORMAT_STRING pointer_desc = NULL;
2824 unsigned char *OldMemory = pStubMsg->Memory;
2825 int pointer_buffer_mark_set = 0;
2827 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2829 if (!pStubMsg->PointerBufferMark)
2831 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2832 /* save buffer length */
2833 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2835 /* get the buffer pointer after complex array data, but before
2836 * pointer data */
2837 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2838 pStubMsg->IgnoreEmbeddedPointers = 1;
2839 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2840 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2842 /* save it for use by embedded pointer code later */
2843 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2844 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2845 pointer_buffer_mark_set = 1;
2847 /* restore the original buffer length */
2848 pStubMsg->BufferLength = saved_buffer_length;
2851 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2853 pFormat += 4;
2854 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
2855 pFormat += 2;
2856 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2857 pFormat += 2;
2859 pStubMsg->Memory = pMemory;
2861 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2863 if (conf_array)
2864 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2866 pStubMsg->Memory = OldMemory;
2868 if (pointer_buffer_mark_set)
2870 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2871 pStubMsg->PointerBufferMark = NULL;
2874 STD_OVERFLOW_CHECK(pStubMsg);
2876 return NULL;
2879 /***********************************************************************
2880 * NdrComplexStructUnmarshall [RPCRT4.@]
2882 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2883 unsigned char **ppMemory,
2884 PFORMAT_STRING pFormat,
2885 unsigned char fMustAlloc)
2887 unsigned size = *(const WORD*)(pFormat+2);
2888 PFORMAT_STRING conf_array = NULL;
2889 PFORMAT_STRING pointer_desc = NULL;
2890 unsigned char *pMemory;
2891 int pointer_buffer_mark_set = 0;
2893 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2895 if (!pStubMsg->PointerBufferMark)
2897 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2898 /* save buffer pointer */
2899 unsigned char *saved_buffer = pStubMsg->Buffer;
2901 /* get the buffer pointer after complex array data, but before
2902 * pointer data */
2903 pStubMsg->IgnoreEmbeddedPointers = 1;
2904 NdrComplexStructMemorySize(pStubMsg, pFormat);
2905 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2907 /* save it for use by embedded pointer code later */
2908 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2909 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2910 pointer_buffer_mark_set = 1;
2912 /* restore the original buffer */
2913 pStubMsg->Buffer = saved_buffer;
2916 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2918 if (fMustAlloc || !*ppMemory)
2919 *ppMemory = NdrAllocate(pStubMsg, size);
2921 pFormat += 4;
2922 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
2923 pFormat += 2;
2924 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2925 pFormat += 2;
2927 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
2929 if (conf_array)
2930 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2932 if (pointer_buffer_mark_set)
2934 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2935 pStubMsg->PointerBufferMark = NULL;
2938 return NULL;
2941 /***********************************************************************
2942 * NdrComplexStructBufferSize [RPCRT4.@]
2944 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2945 unsigned char *pMemory,
2946 PFORMAT_STRING pFormat)
2948 PFORMAT_STRING conf_array = NULL;
2949 PFORMAT_STRING pointer_desc = NULL;
2950 unsigned char *OldMemory = pStubMsg->Memory;
2951 int pointer_length_set = 0;
2953 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2955 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2957 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2959 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2960 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2962 /* get the buffer length after complex struct data, but before
2963 * pointer data */
2964 pStubMsg->IgnoreEmbeddedPointers = 1;
2965 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2966 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2968 /* save it for use by embedded pointer code later */
2969 pStubMsg->PointerLength = pStubMsg->BufferLength;
2970 pointer_length_set = 1;
2971 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2973 /* restore the original buffer length */
2974 pStubMsg->BufferLength = saved_buffer_length;
2977 pFormat += 4;
2978 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
2979 pFormat += 2;
2980 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2981 pFormat += 2;
2983 pStubMsg->Memory = pMemory;
2985 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2987 if (conf_array)
2988 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2990 pStubMsg->Memory = OldMemory;
2992 if(pointer_length_set)
2994 pStubMsg->BufferLength = pStubMsg->PointerLength;
2995 pStubMsg->PointerLength = 0;
3000 /***********************************************************************
3001 * NdrComplexStructMemorySize [RPCRT4.@]
3003 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3004 PFORMAT_STRING pFormat)
3006 unsigned size = *(const WORD*)(pFormat+2);
3007 PFORMAT_STRING conf_array = NULL;
3008 PFORMAT_STRING pointer_desc = NULL;
3010 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3012 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3014 pFormat += 4;
3015 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3016 pFormat += 2;
3017 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3018 pFormat += 2;
3020 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3022 if (conf_array)
3023 NdrConformantArrayMemorySize(pStubMsg, conf_array);
3025 return size;
3028 /***********************************************************************
3029 * NdrComplexStructFree [RPCRT4.@]
3031 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3032 unsigned char *pMemory,
3033 PFORMAT_STRING pFormat)
3035 PFORMAT_STRING conf_array = NULL;
3036 PFORMAT_STRING pointer_desc = NULL;
3037 unsigned char *OldMemory = pStubMsg->Memory;
3039 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3041 pFormat += 4;
3042 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3043 pFormat += 2;
3044 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3045 pFormat += 2;
3047 pStubMsg->Memory = pMemory;
3049 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3051 if (conf_array)
3052 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
3054 pStubMsg->Memory = OldMemory;
3057 /***********************************************************************
3058 * NdrConformantArrayMarshall [RPCRT4.@]
3060 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3061 unsigned char *pMemory,
3062 PFORMAT_STRING pFormat)
3064 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3065 unsigned char alignment = pFormat[1] + 1;
3067 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3068 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3070 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3072 WriteConformance(pStubMsg);
3074 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3076 size = safe_multiply(esize, pStubMsg->MaxCount);
3077 pStubMsg->BufferMark = pStubMsg->Buffer;
3078 safe_copy_to_buffer(pStubMsg, pMemory, size);
3080 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3082 return NULL;
3085 /***********************************************************************
3086 * NdrConformantArrayUnmarshall [RPCRT4.@]
3088 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3089 unsigned char **ppMemory,
3090 PFORMAT_STRING pFormat,
3091 unsigned char fMustAlloc)
3093 DWORD size, esize = *(const WORD*)(pFormat+2);
3094 unsigned char alignment = pFormat[1] + 1;
3095 unsigned char *saved_buffer;
3097 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3098 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3100 pFormat = ReadConformance(pStubMsg, pFormat+4);
3102 size = safe_multiply(esize, pStubMsg->MaxCount);
3103 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3105 if (fMustAlloc)
3106 *ppMemory = NdrAllocate(pStubMsg, size);
3107 else
3109 if (!pStubMsg->IsClient && !*ppMemory)
3110 /* for servers, we just point straight into the RPC buffer */
3111 *ppMemory = pStubMsg->Buffer;
3114 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3115 safe_buffer_increment(pStubMsg, size);
3116 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3118 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3119 if (*ppMemory != saved_buffer)
3120 memcpy(*ppMemory, saved_buffer, size);
3122 return NULL;
3125 /***********************************************************************
3126 * NdrConformantArrayBufferSize [RPCRT4.@]
3128 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3129 unsigned char *pMemory,
3130 PFORMAT_STRING pFormat)
3132 DWORD size, esize = *(const WORD*)(pFormat+2);
3133 unsigned char alignment = pFormat[1] + 1;
3135 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3136 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3138 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3140 SizeConformance(pStubMsg);
3142 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3144 size = safe_multiply(esize, pStubMsg->MaxCount);
3145 /* conformance value plus array */
3146 safe_buffer_length_increment(pStubMsg, size);
3148 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3151 /***********************************************************************
3152 * NdrConformantArrayMemorySize [RPCRT4.@]
3154 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3155 PFORMAT_STRING pFormat)
3157 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3158 unsigned char alignment = pFormat[1] + 1;
3160 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3161 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3163 pFormat = ReadConformance(pStubMsg, pFormat+4);
3164 size = safe_multiply(esize, pStubMsg->MaxCount);
3165 pStubMsg->MemorySize += size;
3167 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3168 pStubMsg->BufferMark = pStubMsg->Buffer;
3169 safe_buffer_increment(pStubMsg, size);
3171 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3173 return pStubMsg->MemorySize;
3176 /***********************************************************************
3177 * NdrConformantArrayFree [RPCRT4.@]
3179 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3180 unsigned char *pMemory,
3181 PFORMAT_STRING pFormat)
3183 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3184 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3186 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3188 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3192 /***********************************************************************
3193 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3195 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3196 unsigned char* pMemory,
3197 PFORMAT_STRING pFormat )
3199 ULONG bufsize;
3200 unsigned char alignment = pFormat[1] + 1;
3201 DWORD esize = *(const WORD*)(pFormat+2);
3203 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3205 if (pFormat[0] != RPC_FC_CVARRAY)
3207 ERR("invalid format type %x\n", pFormat[0]);
3208 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3209 return NULL;
3212 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3213 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3215 WriteConformance(pStubMsg);
3216 WriteVariance(pStubMsg);
3218 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3220 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3222 pStubMsg->BufferMark = pStubMsg->Buffer;
3223 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
3225 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3227 return NULL;
3231 /***********************************************************************
3232 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3234 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3235 unsigned char** ppMemory,
3236 PFORMAT_STRING pFormat,
3237 unsigned char fMustAlloc )
3239 ULONG bufsize, memsize;
3240 unsigned char alignment = pFormat[1] + 1;
3241 DWORD esize = *(const WORD*)(pFormat+2);
3242 unsigned char *saved_buffer;
3243 ULONG offset;
3245 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3247 if (pFormat[0] != RPC_FC_CVARRAY)
3249 ERR("invalid format type %x\n", pFormat[0]);
3250 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3251 return NULL;
3254 pFormat = ReadConformance(pStubMsg, pFormat+4);
3255 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3257 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3259 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3260 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3261 offset = pStubMsg->Offset;
3263 if (!*ppMemory || fMustAlloc)
3264 *ppMemory = NdrAllocate(pStubMsg, memsize);
3265 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3266 safe_buffer_increment(pStubMsg, bufsize);
3268 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3270 memcpy(*ppMemory + offset, saved_buffer, bufsize);
3272 return NULL;
3276 /***********************************************************************
3277 * NdrConformantVaryingArrayFree [RPCRT4.@]
3279 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3280 unsigned char* pMemory,
3281 PFORMAT_STRING pFormat )
3283 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3285 if (pFormat[0] != RPC_FC_CVARRAY)
3287 ERR("invalid format type %x\n", pFormat[0]);
3288 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3289 return;
3292 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3293 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3295 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3299 /***********************************************************************
3300 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3302 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3303 unsigned char* pMemory, PFORMAT_STRING pFormat )
3305 unsigned char alignment = pFormat[1] + 1;
3306 DWORD esize = *(const WORD*)(pFormat+2);
3308 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, 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;
3317 /* compute size */
3318 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3319 /* compute length */
3320 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3322 SizeConformance(pStubMsg);
3323 SizeVariance(pStubMsg);
3325 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3327 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3329 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3333 /***********************************************************************
3334 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3336 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3337 PFORMAT_STRING pFormat )
3339 ULONG bufsize, memsize;
3340 unsigned char alignment = pFormat[1] + 1;
3341 DWORD esize = *(const WORD*)(pFormat+2);
3343 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3345 if (pFormat[0] != RPC_FC_CVARRAY)
3347 ERR("invalid format type %x\n", pFormat[0]);
3348 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3349 return pStubMsg->MemorySize;
3352 pFormat = ReadConformance(pStubMsg, pFormat+4);
3353 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3355 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3357 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3358 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3360 safe_buffer_increment(pStubMsg, bufsize);
3361 pStubMsg->MemorySize += memsize;
3363 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3365 return pStubMsg->MemorySize;
3369 /***********************************************************************
3370 * NdrComplexArrayMarshall [RPCRT4.@]
3372 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3373 unsigned char *pMemory,
3374 PFORMAT_STRING pFormat)
3376 ULONG i, count, def;
3377 BOOL variance_present;
3378 unsigned char alignment;
3379 int pointer_buffer_mark_set = 0;
3381 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3383 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3385 ERR("invalid format type %x\n", pFormat[0]);
3386 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3387 return NULL;
3390 alignment = pFormat[1] + 1;
3392 if (!pStubMsg->PointerBufferMark)
3394 /* save buffer fields that may be changed by buffer sizer functions
3395 * and that may be needed later on */
3396 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3397 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3398 unsigned long saved_max_count = pStubMsg->MaxCount;
3399 unsigned long saved_offset = pStubMsg->Offset;
3400 unsigned long saved_actual_count = pStubMsg->ActualCount;
3402 /* get the buffer pointer after complex array data, but before
3403 * pointer data */
3404 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3405 pStubMsg->IgnoreEmbeddedPointers = 1;
3406 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3407 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3409 /* save it for use by embedded pointer code later */
3410 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3411 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3412 pointer_buffer_mark_set = 1;
3414 /* restore fields */
3415 pStubMsg->ActualCount = saved_actual_count;
3416 pStubMsg->Offset = saved_offset;
3417 pStubMsg->MaxCount = saved_max_count;
3418 pStubMsg->BufferLength = saved_buffer_length;
3421 def = *(const WORD*)&pFormat[2];
3422 pFormat += 4;
3424 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3425 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3427 variance_present = IsConformanceOrVariancePresent(pFormat);
3428 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3429 TRACE("variance = %d\n", pStubMsg->ActualCount);
3431 WriteConformance(pStubMsg);
3432 if (variance_present)
3433 WriteVariance(pStubMsg);
3435 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3437 count = pStubMsg->ActualCount;
3438 for (i = 0; i < count; i++)
3439 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3441 STD_OVERFLOW_CHECK(pStubMsg);
3443 if (pointer_buffer_mark_set)
3445 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3446 pStubMsg->PointerBufferMark = NULL;
3449 return NULL;
3452 /***********************************************************************
3453 * NdrComplexArrayUnmarshall [RPCRT4.@]
3455 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3456 unsigned char **ppMemory,
3457 PFORMAT_STRING pFormat,
3458 unsigned char fMustAlloc)
3460 ULONG i, count, size;
3461 unsigned char alignment;
3462 unsigned char *pMemory;
3463 unsigned char *saved_buffer;
3464 int pointer_buffer_mark_set = 0;
3465 int saved_ignore_embedded;
3467 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3469 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3471 ERR("invalid format type %x\n", pFormat[0]);
3472 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3473 return NULL;
3476 alignment = pFormat[1] + 1;
3478 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3479 /* save buffer pointer */
3480 saved_buffer = pStubMsg->Buffer;
3481 /* get the buffer pointer after complex array data, but before
3482 * pointer data */
3483 pStubMsg->IgnoreEmbeddedPointers = 1;
3484 pStubMsg->MemorySize = 0;
3485 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3486 size = pStubMsg->MemorySize;
3487 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3489 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3490 if (!pStubMsg->PointerBufferMark)
3492 /* save it for use by embedded pointer code later */
3493 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3494 pointer_buffer_mark_set = 1;
3496 /* restore the original buffer */
3497 pStubMsg->Buffer = saved_buffer;
3499 pFormat += 4;
3501 pFormat = ReadConformance(pStubMsg, pFormat);
3502 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3504 if (fMustAlloc || !*ppMemory)
3505 *ppMemory = NdrAllocate(pStubMsg, size);
3507 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3509 pMemory = *ppMemory;
3510 count = pStubMsg->ActualCount;
3511 for (i = 0; i < count; i++)
3512 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3514 if (pointer_buffer_mark_set)
3516 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3517 pStubMsg->PointerBufferMark = NULL;
3520 return NULL;
3523 /***********************************************************************
3524 * NdrComplexArrayBufferSize [RPCRT4.@]
3526 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3527 unsigned char *pMemory,
3528 PFORMAT_STRING pFormat)
3530 ULONG i, count, def;
3531 unsigned char alignment;
3532 BOOL variance_present;
3533 int pointer_length_set = 0;
3535 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3537 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3539 ERR("invalid format type %x\n", pFormat[0]);
3540 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3541 return;
3544 alignment = pFormat[1] + 1;
3546 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3548 /* save buffer fields that may be changed by buffer sizer functions
3549 * and that may be needed later on */
3550 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3551 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3552 unsigned long saved_max_count = pStubMsg->MaxCount;
3553 unsigned long saved_offset = pStubMsg->Offset;
3554 unsigned long saved_actual_count = pStubMsg->ActualCount;
3556 /* get the buffer pointer after complex array data, but before
3557 * pointer data */
3558 pStubMsg->IgnoreEmbeddedPointers = 1;
3559 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3560 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3562 /* save it for use by embedded pointer code later */
3563 pStubMsg->PointerLength = pStubMsg->BufferLength;
3564 pointer_length_set = 1;
3566 /* restore fields */
3567 pStubMsg->ActualCount = saved_actual_count;
3568 pStubMsg->Offset = saved_offset;
3569 pStubMsg->MaxCount = saved_max_count;
3570 pStubMsg->BufferLength = saved_buffer_length;
3572 def = *(const WORD*)&pFormat[2];
3573 pFormat += 4;
3575 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3576 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3577 SizeConformance(pStubMsg);
3579 variance_present = IsConformanceOrVariancePresent(pFormat);
3580 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3581 TRACE("variance = %d\n", pStubMsg->ActualCount);
3583 if (variance_present)
3584 SizeVariance(pStubMsg);
3586 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3588 count = pStubMsg->ActualCount;
3589 for (i = 0; i < count; i++)
3590 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3592 if(pointer_length_set)
3594 pStubMsg->BufferLength = pStubMsg->PointerLength;
3595 pStubMsg->PointerLength = 0;
3599 /***********************************************************************
3600 * NdrComplexArrayMemorySize [RPCRT4.@]
3602 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3603 PFORMAT_STRING pFormat)
3605 ULONG i, count, esize, SavedMemorySize, MemorySize;
3606 unsigned char alignment;
3608 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3610 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3612 ERR("invalid format type %x\n", pFormat[0]);
3613 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3614 return 0;
3617 alignment = pFormat[1] + 1;
3619 pFormat += 4;
3621 pFormat = ReadConformance(pStubMsg, pFormat);
3622 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3624 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3626 SavedMemorySize = pStubMsg->MemorySize;
3628 esize = ComplexStructSize(pStubMsg, pFormat);
3630 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3632 count = pStubMsg->ActualCount;
3633 for (i = 0; i < count; i++)
3634 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
3636 pStubMsg->MemorySize = SavedMemorySize;
3638 pStubMsg->MemorySize += MemorySize;
3639 return MemorySize;
3642 /***********************************************************************
3643 * NdrComplexArrayFree [RPCRT4.@]
3645 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3646 unsigned char *pMemory,
3647 PFORMAT_STRING pFormat)
3649 ULONG i, count, def;
3651 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3653 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3655 ERR("invalid format type %x\n", pFormat[0]);
3656 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3657 return;
3660 def = *(const WORD*)&pFormat[2];
3661 pFormat += 4;
3663 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3664 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3666 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3667 TRACE("variance = %d\n", pStubMsg->ActualCount);
3669 count = pStubMsg->ActualCount;
3670 for (i = 0; i < count; i++)
3671 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3674 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3675 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3676 USER_MARSHAL_CB *umcb)
3678 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3679 pStubMsg->RpcMsg->DataRepresentation);
3680 umcb->pStubMsg = pStubMsg;
3681 umcb->pReserve = NULL;
3682 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3683 umcb->CBType = cbtype;
3684 umcb->pFormat = pFormat;
3685 umcb->pTypeFormat = NULL /* FIXME */;
3688 #define USER_MARSHAL_PTR_PREFIX \
3689 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3690 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3692 /***********************************************************************
3693 * NdrUserMarshalMarshall [RPCRT4.@]
3695 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3696 unsigned char *pMemory,
3697 PFORMAT_STRING pFormat)
3699 unsigned flags = pFormat[1];
3700 unsigned index = *(const WORD*)&pFormat[2];
3701 unsigned char *saved_buffer = NULL;
3702 USER_MARSHAL_CB umcb;
3704 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3705 TRACE("index=%d\n", index);
3707 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3709 if (flags & USER_MARSHAL_POINTER)
3711 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3712 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3713 pStubMsg->Buffer += 4;
3714 if (pStubMsg->PointerBufferMark)
3716 saved_buffer = pStubMsg->Buffer;
3717 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3718 pStubMsg->PointerBufferMark = NULL;
3720 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3722 else
3723 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3725 pStubMsg->Buffer =
3726 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3727 &umcb.Flags, pStubMsg->Buffer, pMemory);
3729 if (saved_buffer)
3731 STD_OVERFLOW_CHECK(pStubMsg);
3732 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3733 pStubMsg->Buffer = saved_buffer;
3736 STD_OVERFLOW_CHECK(pStubMsg);
3738 return NULL;
3741 /***********************************************************************
3742 * NdrUserMarshalUnmarshall [RPCRT4.@]
3744 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3745 unsigned char **ppMemory,
3746 PFORMAT_STRING pFormat,
3747 unsigned char fMustAlloc)
3749 unsigned flags = pFormat[1];
3750 unsigned index = *(const WORD*)&pFormat[2];
3751 DWORD memsize = *(const WORD*)&pFormat[4];
3752 unsigned char *saved_buffer = NULL;
3753 USER_MARSHAL_CB umcb;
3755 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3756 TRACE("index=%d\n", index);
3758 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3760 if (flags & USER_MARSHAL_POINTER)
3762 ALIGN_POINTER(pStubMsg->Buffer, 4);
3763 /* skip pointer prefix */
3764 pStubMsg->Buffer += 4;
3765 if (pStubMsg->PointerBufferMark)
3767 saved_buffer = pStubMsg->Buffer;
3768 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3769 pStubMsg->PointerBufferMark = NULL;
3771 ALIGN_POINTER(pStubMsg->Buffer, 8);
3773 else
3774 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3776 if (fMustAlloc || !*ppMemory)
3777 *ppMemory = NdrAllocate(pStubMsg, memsize);
3779 pStubMsg->Buffer =
3780 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3781 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3783 if (saved_buffer)
3785 STD_OVERFLOW_CHECK(pStubMsg);
3786 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3787 pStubMsg->Buffer = saved_buffer;
3790 return NULL;
3793 /***********************************************************************
3794 * NdrUserMarshalBufferSize [RPCRT4.@]
3796 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3797 unsigned char *pMemory,
3798 PFORMAT_STRING pFormat)
3800 unsigned flags = pFormat[1];
3801 unsigned index = *(const WORD*)&pFormat[2];
3802 DWORD bufsize = *(const WORD*)&pFormat[6];
3803 USER_MARSHAL_CB umcb;
3804 unsigned long saved_buffer_length = 0;
3806 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3807 TRACE("index=%d\n", index);
3809 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3811 if (flags & USER_MARSHAL_POINTER)
3813 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3814 /* skip pointer prefix */
3815 safe_buffer_length_increment(pStubMsg, 4);
3816 if (pStubMsg->IgnoreEmbeddedPointers)
3817 return;
3818 if (pStubMsg->PointerLength)
3820 saved_buffer_length = pStubMsg->BufferLength;
3821 pStubMsg->BufferLength = pStubMsg->PointerLength;
3822 pStubMsg->PointerLength = 0;
3824 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3826 else
3827 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3829 if (bufsize) {
3830 TRACE("size=%d\n", bufsize);
3831 safe_buffer_length_increment(pStubMsg, bufsize);
3833 else
3834 pStubMsg->BufferLength =
3835 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3836 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3838 if (saved_buffer_length)
3840 pStubMsg->PointerLength = pStubMsg->BufferLength;
3841 pStubMsg->BufferLength = saved_buffer_length;
3846 /***********************************************************************
3847 * NdrUserMarshalMemorySize [RPCRT4.@]
3849 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3850 PFORMAT_STRING pFormat)
3852 unsigned flags = pFormat[1];
3853 unsigned index = *(const WORD*)&pFormat[2];
3854 DWORD memsize = *(const WORD*)&pFormat[4];
3855 DWORD bufsize = *(const WORD*)&pFormat[6];
3857 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3858 TRACE("index=%d\n", index);
3860 pStubMsg->MemorySize += memsize;
3862 if (flags & USER_MARSHAL_POINTER)
3864 ALIGN_POINTER(pStubMsg->Buffer, 4);
3865 /* skip pointer prefix */
3866 pStubMsg->Buffer += 4;
3867 if (pStubMsg->IgnoreEmbeddedPointers)
3868 return pStubMsg->MemorySize;
3869 ALIGN_POINTER(pStubMsg->Buffer, 8);
3871 else
3872 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3874 if (!bufsize)
3875 FIXME("not implemented for varying buffer size\n");
3877 pStubMsg->Buffer += bufsize;
3879 return pStubMsg->MemorySize;
3882 /***********************************************************************
3883 * NdrUserMarshalFree [RPCRT4.@]
3885 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3886 unsigned char *pMemory,
3887 PFORMAT_STRING pFormat)
3889 /* unsigned flags = pFormat[1]; */
3890 unsigned index = *(const WORD*)&pFormat[2];
3891 USER_MARSHAL_CB umcb;
3893 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3894 TRACE("index=%d\n", index);
3896 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3898 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3899 &umcb.Flags, pMemory);
3902 /***********************************************************************
3903 * NdrClearOutParameters [RPCRT4.@]
3905 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3906 PFORMAT_STRING pFormat,
3907 void *ArgAddr)
3909 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3912 /***********************************************************************
3913 * NdrConvert [RPCRT4.@]
3915 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3917 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3918 /* FIXME: since this stub doesn't do any converting, the proper behavior
3919 is to raise an exception */
3922 /***********************************************************************
3923 * NdrConvert2 [RPCRT4.@]
3925 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3927 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3928 pStubMsg, pFormat, NumberParams);
3929 /* FIXME: since this stub doesn't do any converting, the proper behavior
3930 is to raise an exception */
3933 #include "pshpack1.h"
3934 typedef struct _NDR_CSTRUCT_FORMAT
3936 unsigned char type;
3937 unsigned char alignment;
3938 unsigned short memory_size;
3939 short offset_to_array_description;
3940 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3941 #include "poppack.h"
3943 /***********************************************************************
3944 * NdrConformantStructMarshall [RPCRT4.@]
3946 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3947 unsigned char *pMemory,
3948 PFORMAT_STRING pFormat)
3950 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3951 PFORMAT_STRING pCArrayFormat;
3952 ULONG esize, bufsize;
3954 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3956 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3957 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3959 ERR("invalid format type %x\n", pCStructFormat->type);
3960 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3961 return NULL;
3964 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3965 pCStructFormat->offset_to_array_description;
3966 if (*pCArrayFormat != RPC_FC_CARRAY)
3968 ERR("invalid array format type %x\n", pCStructFormat->type);
3969 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3970 return NULL;
3972 esize = *(const WORD*)(pCArrayFormat+2);
3974 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3975 pCArrayFormat + 4, 0);
3977 WriteConformance(pStubMsg);
3979 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3981 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3983 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3984 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3986 ERR("integer overflow of memory_size %u with bufsize %u\n",
3987 pCStructFormat->memory_size, bufsize);
3988 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3990 /* copy constant sized part of struct */
3991 pStubMsg->BufferMark = pStubMsg->Buffer;
3992 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3994 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3995 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3997 return NULL;
4000 /***********************************************************************
4001 * NdrConformantStructUnmarshall [RPCRT4.@]
4003 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4004 unsigned char **ppMemory,
4005 PFORMAT_STRING pFormat,
4006 unsigned char fMustAlloc)
4008 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4009 PFORMAT_STRING pCArrayFormat;
4010 ULONG esize, bufsize;
4011 unsigned char *saved_buffer;
4013 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4015 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4016 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4018 ERR("invalid format type %x\n", pCStructFormat->type);
4019 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4020 return NULL;
4022 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4023 pCStructFormat->offset_to_array_description;
4024 if (*pCArrayFormat != RPC_FC_CARRAY)
4026 ERR("invalid array format type %x\n", pCStructFormat->type);
4027 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4028 return NULL;
4030 esize = *(const WORD*)(pCArrayFormat+2);
4032 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4034 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4036 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4038 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4039 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4041 ERR("integer overflow of memory_size %u with bufsize %u\n",
4042 pCStructFormat->memory_size, bufsize);
4043 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4046 if (fMustAlloc)
4048 SIZE_T size = pCStructFormat->memory_size + bufsize;
4049 *ppMemory = NdrAllocate(pStubMsg, size);
4051 else
4053 if (!pStubMsg->IsClient && !*ppMemory)
4054 /* for servers, we just point straight into the RPC buffer */
4055 *ppMemory = pStubMsg->Buffer;
4058 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4059 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4060 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4061 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4063 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4064 if (*ppMemory != saved_buffer)
4065 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4067 return NULL;
4070 /***********************************************************************
4071 * NdrConformantStructBufferSize [RPCRT4.@]
4073 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4074 unsigned char *pMemory,
4075 PFORMAT_STRING pFormat)
4077 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4078 PFORMAT_STRING pCArrayFormat;
4079 ULONG esize;
4081 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4083 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4084 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4086 ERR("invalid format type %x\n", pCStructFormat->type);
4087 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4088 return;
4090 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4091 pCStructFormat->offset_to_array_description;
4092 if (*pCArrayFormat != RPC_FC_CARRAY)
4094 ERR("invalid array format type %x\n", pCStructFormat->type);
4095 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4096 return;
4098 esize = *(const WORD*)(pCArrayFormat+2);
4100 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4101 SizeConformance(pStubMsg);
4103 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4105 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4107 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4108 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4110 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4111 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4114 /***********************************************************************
4115 * NdrConformantStructMemorySize [RPCRT4.@]
4117 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4118 PFORMAT_STRING pFormat)
4120 FIXME("stub\n");
4121 return 0;
4124 /***********************************************************************
4125 * NdrConformantStructFree [RPCRT4.@]
4127 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4128 unsigned char *pMemory,
4129 PFORMAT_STRING pFormat)
4131 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4132 PFORMAT_STRING pCArrayFormat;
4134 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4136 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4137 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4139 ERR("invalid format type %x\n", pCStructFormat->type);
4140 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4141 return;
4144 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4145 pCStructFormat->offset_to_array_description;
4146 if (*pCArrayFormat != RPC_FC_CARRAY)
4148 ERR("invalid array format type %x\n", pCStructFormat->type);
4149 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4150 return;
4153 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4154 pCArrayFormat + 4, 0);
4156 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4158 /* copy constant sized part of struct */
4159 pStubMsg->BufferMark = pStubMsg->Buffer;
4161 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4162 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4165 /***********************************************************************
4166 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4168 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4169 unsigned char *pMemory,
4170 PFORMAT_STRING pFormat)
4172 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4173 PFORMAT_STRING pCVArrayFormat;
4174 ULONG esize, bufsize;
4176 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4178 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4179 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4181 ERR("invalid format type %x\n", pCVStructFormat->type);
4182 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4183 return NULL;
4186 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4187 pCVStructFormat->offset_to_array_description;
4188 switch (*pCVArrayFormat)
4190 case RPC_FC_CVARRAY:
4191 esize = *(const WORD*)(pCVArrayFormat+2);
4193 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4194 pCVArrayFormat + 4, 0);
4195 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4196 pCVArrayFormat, 0);
4197 break;
4198 case RPC_FC_C_CSTRING:
4199 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4200 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4201 esize = sizeof(char);
4202 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4203 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4204 pCVArrayFormat + 2, 0);
4205 else
4206 pStubMsg->MaxCount = pStubMsg->ActualCount;
4207 break;
4208 case RPC_FC_C_WSTRING:
4209 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4210 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4211 esize = sizeof(WCHAR);
4212 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4213 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4214 pCVArrayFormat + 2, 0);
4215 else
4216 pStubMsg->MaxCount = pStubMsg->ActualCount;
4217 break;
4218 default:
4219 ERR("invalid array format type %x\n", *pCVArrayFormat);
4220 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4221 return NULL;
4224 WriteConformance(pStubMsg);
4226 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4228 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4230 /* write constant sized part */
4231 pStubMsg->BufferMark = pStubMsg->Buffer;
4232 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4234 WriteVariance(pStubMsg);
4236 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4238 /* write array part */
4239 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
4241 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4243 return NULL;
4246 /***********************************************************************
4247 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4249 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4250 unsigned char **ppMemory,
4251 PFORMAT_STRING pFormat,
4252 unsigned char fMustAlloc)
4254 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4255 PFORMAT_STRING pCVArrayFormat;
4256 ULONG esize, bufsize;
4257 unsigned char cvarray_type;
4258 unsigned char *saved_buffer, *saved_array_buffer;
4260 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4262 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4263 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4265 ERR("invalid format type %x\n", pCVStructFormat->type);
4266 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4267 return NULL;
4270 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4271 pCVStructFormat->offset_to_array_description;
4272 cvarray_type = *pCVArrayFormat;
4273 switch (cvarray_type)
4275 case RPC_FC_CVARRAY:
4276 esize = *(const WORD*)(pCVArrayFormat+2);
4277 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4278 break;
4279 case RPC_FC_C_CSTRING:
4280 esize = sizeof(char);
4281 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4282 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4283 else
4284 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4285 break;
4286 case RPC_FC_C_WSTRING:
4287 esize = sizeof(WCHAR);
4288 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4289 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4290 else
4291 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4292 break;
4293 default:
4294 ERR("invalid array format type %x\n", *pCVArrayFormat);
4295 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4296 return NULL;
4299 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4301 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4303 /* work out how much memory to allocate if we need to do so */
4304 if (!*ppMemory || fMustAlloc)
4306 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4307 *ppMemory = NdrAllocate(pStubMsg, size);
4310 /* mark the start of the constant data */
4311 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4312 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4314 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4316 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4318 if ((cvarray_type == RPC_FC_C_CSTRING) ||
4319 (cvarray_type == RPC_FC_C_WSTRING))
4320 validate_string_data(pStubMsg, bufsize, esize);
4322 /* mark the start of the array data */
4323 saved_array_buffer = pStubMsg->Buffer;
4324 safe_buffer_increment(pStubMsg, bufsize);
4326 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4328 /* copy the constant data */
4329 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4330 /* copy the array data */
4331 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4332 memcpy(*ppMemory + pCVStructFormat->memory_size, saved_array_buffer, bufsize);
4334 if (cvarray_type == RPC_FC_C_CSTRING)
4335 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4336 else if (cvarray_type == RPC_FC_C_WSTRING)
4337 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4339 return NULL;
4342 /***********************************************************************
4343 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4345 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4346 unsigned char *pMemory,
4347 PFORMAT_STRING pFormat)
4349 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4350 PFORMAT_STRING pCVArrayFormat;
4351 ULONG esize;
4353 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4355 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4356 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4358 ERR("invalid format type %x\n", pCVStructFormat->type);
4359 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4360 return;
4363 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4364 pCVStructFormat->offset_to_array_description;
4365 switch (*pCVArrayFormat)
4367 case RPC_FC_CVARRAY:
4368 esize = *(const WORD*)(pCVArrayFormat+2);
4370 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4371 pCVArrayFormat + 4, 0);
4372 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4373 pCVArrayFormat, 0);
4374 break;
4375 case RPC_FC_C_CSTRING:
4376 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4377 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4378 esize = sizeof(char);
4379 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4380 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4381 pCVArrayFormat + 2, 0);
4382 else
4383 pStubMsg->MaxCount = pStubMsg->ActualCount;
4384 break;
4385 case RPC_FC_C_WSTRING:
4386 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4387 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4388 esize = sizeof(WCHAR);
4389 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4390 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4391 pCVArrayFormat + 2, 0);
4392 else
4393 pStubMsg->MaxCount = pStubMsg->ActualCount;
4394 break;
4395 default:
4396 ERR("invalid array format type %x\n", *pCVArrayFormat);
4397 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4398 return;
4401 SizeConformance(pStubMsg);
4403 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4405 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4407 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4408 SizeVariance(pStubMsg);
4409 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4411 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4414 /***********************************************************************
4415 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4417 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4418 PFORMAT_STRING pFormat)
4420 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4421 PFORMAT_STRING pCVArrayFormat;
4422 ULONG esize;
4423 unsigned char cvarray_type;
4425 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4427 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4428 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4430 ERR("invalid format type %x\n", pCVStructFormat->type);
4431 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4432 return 0;
4435 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4436 pCVStructFormat->offset_to_array_description;
4437 cvarray_type = *pCVArrayFormat;
4438 switch (cvarray_type)
4440 case RPC_FC_CVARRAY:
4441 esize = *(const WORD*)(pCVArrayFormat+2);
4442 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4443 break;
4444 case RPC_FC_C_CSTRING:
4445 esize = sizeof(char);
4446 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4447 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4448 else
4449 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4450 break;
4451 case RPC_FC_C_WSTRING:
4452 esize = sizeof(WCHAR);
4453 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4454 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4455 else
4456 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4457 break;
4458 default:
4459 ERR("invalid array format type %x\n", *pCVArrayFormat);
4460 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4461 return 0;
4464 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4466 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4468 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4469 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4470 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4472 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4474 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4476 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4479 /***********************************************************************
4480 * NdrConformantVaryingStructFree [RPCRT4.@]
4482 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4483 unsigned char *pMemory,
4484 PFORMAT_STRING pFormat)
4486 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4487 PFORMAT_STRING pCVArrayFormat;
4489 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4491 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4492 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4494 ERR("invalid format type %x\n", pCVStructFormat->type);
4495 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4496 return;
4499 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4500 pCVStructFormat->offset_to_array_description;
4501 switch (*pCVArrayFormat)
4503 case RPC_FC_CVARRAY:
4504 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4505 pCVArrayFormat + 4, 0);
4506 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4507 pCVArrayFormat, 0);
4508 break;
4509 case RPC_FC_C_CSTRING:
4510 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4511 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4512 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4513 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4514 pCVArrayFormat + 2, 0);
4515 else
4516 pStubMsg->MaxCount = pStubMsg->ActualCount;
4517 break;
4518 case RPC_FC_C_WSTRING:
4519 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4520 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4521 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4522 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4523 pCVArrayFormat + 2, 0);
4524 else
4525 pStubMsg->MaxCount = pStubMsg->ActualCount;
4526 break;
4527 default:
4528 ERR("invalid array format type %x\n", *pCVArrayFormat);
4529 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4530 return;
4533 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4535 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4538 #include "pshpack1.h"
4539 typedef struct
4541 unsigned char type;
4542 unsigned char alignment;
4543 unsigned short total_size;
4544 } NDR_SMFARRAY_FORMAT;
4546 typedef struct
4548 unsigned char type;
4549 unsigned char alignment;
4550 unsigned long total_size;
4551 } NDR_LGFARRAY_FORMAT;
4552 #include "poppack.h"
4554 /***********************************************************************
4555 * NdrFixedArrayMarshall [RPCRT4.@]
4557 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4558 unsigned char *pMemory,
4559 PFORMAT_STRING pFormat)
4561 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4562 unsigned long total_size;
4564 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4566 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4567 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4569 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4570 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4571 return NULL;
4574 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4576 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4578 total_size = pSmFArrayFormat->total_size;
4579 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4581 else
4583 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4584 total_size = pLgFArrayFormat->total_size;
4585 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4588 pStubMsg->BufferMark = pStubMsg->Buffer;
4589 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4591 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4593 return NULL;
4596 /***********************************************************************
4597 * NdrFixedArrayUnmarshall [RPCRT4.@]
4599 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4600 unsigned char **ppMemory,
4601 PFORMAT_STRING pFormat,
4602 unsigned char fMustAlloc)
4604 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4605 unsigned long total_size;
4606 unsigned char *saved_buffer;
4608 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4610 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4611 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4613 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4614 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4615 return NULL;
4618 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4620 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4622 total_size = pSmFArrayFormat->total_size;
4623 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4625 else
4627 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4628 total_size = pLgFArrayFormat->total_size;
4629 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4632 if (fMustAlloc)
4633 *ppMemory = NdrAllocate(pStubMsg, total_size);
4634 else
4636 if (!pStubMsg->IsClient && !*ppMemory)
4637 /* for servers, we just point straight into the RPC buffer */
4638 *ppMemory = pStubMsg->Buffer;
4641 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4642 safe_buffer_increment(pStubMsg, total_size);
4643 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4645 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4646 if (*ppMemory != saved_buffer)
4647 memcpy(*ppMemory, saved_buffer, total_size);
4649 return NULL;
4652 /***********************************************************************
4653 * NdrFixedArrayBufferSize [RPCRT4.@]
4655 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4656 unsigned char *pMemory,
4657 PFORMAT_STRING pFormat)
4659 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4660 unsigned long total_size;
4662 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4664 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4665 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4667 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4668 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4669 return;
4672 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4674 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4676 total_size = pSmFArrayFormat->total_size;
4677 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4679 else
4681 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4682 total_size = pLgFArrayFormat->total_size;
4683 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4685 safe_buffer_length_increment(pStubMsg, total_size);
4687 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4690 /***********************************************************************
4691 * NdrFixedArrayMemorySize [RPCRT4.@]
4693 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4694 PFORMAT_STRING pFormat)
4696 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4697 ULONG total_size;
4699 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4701 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4702 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4704 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4705 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4706 return 0;
4709 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4711 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4713 total_size = pSmFArrayFormat->total_size;
4714 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4716 else
4718 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4719 total_size = pLgFArrayFormat->total_size;
4720 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4722 pStubMsg->BufferMark = pStubMsg->Buffer;
4723 safe_buffer_increment(pStubMsg, total_size);
4724 pStubMsg->MemorySize += total_size;
4726 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4728 return total_size;
4731 /***********************************************************************
4732 * NdrFixedArrayFree [RPCRT4.@]
4734 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4735 unsigned char *pMemory,
4736 PFORMAT_STRING pFormat)
4738 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4740 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4742 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4743 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4745 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4746 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4747 return;
4750 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4751 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4752 else
4754 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4755 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4758 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4761 /***********************************************************************
4762 * NdrVaryingArrayMarshall [RPCRT4.@]
4764 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4765 unsigned char *pMemory,
4766 PFORMAT_STRING pFormat)
4768 unsigned char alignment;
4769 DWORD elements, esize;
4770 ULONG bufsize;
4772 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4774 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4775 (pFormat[0] != RPC_FC_LGVARRAY))
4777 ERR("invalid format type %x\n", pFormat[0]);
4778 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4779 return NULL;
4782 alignment = pFormat[1] + 1;
4784 if (pFormat[0] == RPC_FC_SMVARRAY)
4786 pFormat += 2;
4787 pFormat += sizeof(WORD);
4788 elements = *(const WORD*)pFormat;
4789 pFormat += sizeof(WORD);
4791 else
4793 pFormat += 2;
4794 pFormat += sizeof(DWORD);
4795 elements = *(const DWORD*)pFormat;
4796 pFormat += sizeof(DWORD);
4799 esize = *(const WORD*)pFormat;
4800 pFormat += sizeof(WORD);
4802 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4803 if ((pStubMsg->ActualCount > elements) ||
4804 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4806 RpcRaiseException(RPC_S_INVALID_BOUND);
4807 return NULL;
4810 WriteVariance(pStubMsg);
4812 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4814 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4815 pStubMsg->BufferMark = pStubMsg->Buffer;
4816 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4818 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4820 return NULL;
4823 /***********************************************************************
4824 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4826 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4827 unsigned char **ppMemory,
4828 PFORMAT_STRING pFormat,
4829 unsigned char fMustAlloc)
4831 unsigned char alignment;
4832 DWORD size, elements, esize;
4833 ULONG bufsize;
4834 unsigned char *saved_buffer;
4835 ULONG offset;
4837 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4839 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4840 (pFormat[0] != RPC_FC_LGVARRAY))
4842 ERR("invalid format type %x\n", pFormat[0]);
4843 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4844 return NULL;
4847 alignment = pFormat[1] + 1;
4849 if (pFormat[0] == RPC_FC_SMVARRAY)
4851 pFormat += 2;
4852 size = *(const WORD*)pFormat;
4853 pFormat += sizeof(WORD);
4854 elements = *(const WORD*)pFormat;
4855 pFormat += sizeof(WORD);
4857 else
4859 pFormat += 2;
4860 size = *(const DWORD*)pFormat;
4861 pFormat += sizeof(DWORD);
4862 elements = *(const DWORD*)pFormat;
4863 pFormat += sizeof(DWORD);
4866 esize = *(const WORD*)pFormat;
4867 pFormat += sizeof(WORD);
4869 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4871 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4873 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4874 offset = pStubMsg->Offset;
4876 if (!*ppMemory || fMustAlloc)
4877 *ppMemory = NdrAllocate(pStubMsg, size);
4878 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4879 safe_buffer_increment(pStubMsg, bufsize);
4881 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4883 memcpy(*ppMemory + offset, saved_buffer, bufsize);
4885 return NULL;
4888 /***********************************************************************
4889 * NdrVaryingArrayBufferSize [RPCRT4.@]
4891 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4892 unsigned char *pMemory,
4893 PFORMAT_STRING pFormat)
4895 unsigned char alignment;
4896 DWORD elements, esize;
4898 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4900 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4901 (pFormat[0] != RPC_FC_LGVARRAY))
4903 ERR("invalid format type %x\n", pFormat[0]);
4904 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4905 return;
4908 alignment = pFormat[1] + 1;
4910 if (pFormat[0] == RPC_FC_SMVARRAY)
4912 pFormat += 2;
4913 pFormat += sizeof(WORD);
4914 elements = *(const WORD*)pFormat;
4915 pFormat += sizeof(WORD);
4917 else
4919 pFormat += 2;
4920 pFormat += sizeof(DWORD);
4921 elements = *(const DWORD*)pFormat;
4922 pFormat += sizeof(DWORD);
4925 esize = *(const WORD*)pFormat;
4926 pFormat += sizeof(WORD);
4928 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4929 if ((pStubMsg->ActualCount > elements) ||
4930 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4932 RpcRaiseException(RPC_S_INVALID_BOUND);
4933 return;
4936 SizeVariance(pStubMsg);
4938 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4940 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4942 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4945 /***********************************************************************
4946 * NdrVaryingArrayMemorySize [RPCRT4.@]
4948 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4949 PFORMAT_STRING pFormat)
4951 unsigned char alignment;
4952 DWORD size, elements, esize;
4954 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4956 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4957 (pFormat[0] != RPC_FC_LGVARRAY))
4959 ERR("invalid format type %x\n", pFormat[0]);
4960 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4961 return 0;
4964 alignment = pFormat[1] + 1;
4966 if (pFormat[0] == RPC_FC_SMVARRAY)
4968 pFormat += 2;
4969 size = *(const WORD*)pFormat;
4970 pFormat += sizeof(WORD);
4971 elements = *(const WORD*)pFormat;
4972 pFormat += sizeof(WORD);
4974 else
4976 pFormat += 2;
4977 size = *(const DWORD*)pFormat;
4978 pFormat += sizeof(DWORD);
4979 elements = *(const DWORD*)pFormat;
4980 pFormat += sizeof(DWORD);
4983 esize = *(const WORD*)pFormat;
4984 pFormat += sizeof(WORD);
4986 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4988 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4990 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4991 pStubMsg->MemorySize += size;
4993 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4995 return pStubMsg->MemorySize;
4998 /***********************************************************************
4999 * NdrVaryingArrayFree [RPCRT4.@]
5001 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5002 unsigned char *pMemory,
5003 PFORMAT_STRING pFormat)
5005 DWORD elements;
5007 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5009 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5010 (pFormat[0] != RPC_FC_LGVARRAY))
5012 ERR("invalid format type %x\n", pFormat[0]);
5013 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5014 return;
5017 if (pFormat[0] == RPC_FC_SMVARRAY)
5019 pFormat += 2;
5020 pFormat += sizeof(WORD);
5021 elements = *(const WORD*)pFormat;
5022 pFormat += sizeof(WORD);
5024 else
5026 pFormat += 2;
5027 pFormat += sizeof(DWORD);
5028 elements = *(const DWORD*)pFormat;
5029 pFormat += sizeof(DWORD);
5032 pFormat += sizeof(WORD);
5034 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5035 if ((pStubMsg->ActualCount > elements) ||
5036 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5038 RpcRaiseException(RPC_S_INVALID_BOUND);
5039 return;
5042 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5045 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5047 switch (fc)
5049 case RPC_FC_BYTE:
5050 case RPC_FC_CHAR:
5051 case RPC_FC_SMALL:
5052 case RPC_FC_USMALL:
5053 return *pMemory;
5054 case RPC_FC_WCHAR:
5055 case RPC_FC_SHORT:
5056 case RPC_FC_USHORT:
5057 case RPC_FC_ENUM16:
5058 return *(const USHORT *)pMemory;
5059 case RPC_FC_LONG:
5060 case RPC_FC_ULONG:
5061 case RPC_FC_ENUM32:
5062 return *(const ULONG *)pMemory;
5063 default:
5064 FIXME("Unhandled base type: 0x%02x\n", fc);
5065 return 0;
5069 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5070 unsigned long discriminant,
5071 PFORMAT_STRING pFormat)
5073 unsigned short num_arms, arm, type;
5075 num_arms = *(const SHORT*)pFormat & 0x0fff;
5076 pFormat += 2;
5077 for(arm = 0; arm < num_arms; arm++)
5079 if(discriminant == *(const ULONG*)pFormat)
5081 pFormat += 4;
5082 break;
5084 pFormat += 6;
5087 type = *(const unsigned short*)pFormat;
5088 TRACE("type %04x\n", type);
5089 if(arm == num_arms) /* default arm extras */
5091 if(type == 0xffff)
5093 ERR("no arm for 0x%lx and no default case\n", discriminant);
5094 RpcRaiseException(RPC_S_INVALID_TAG);
5095 return NULL;
5097 if(type == 0)
5099 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5100 return NULL;
5103 return pFormat;
5106 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5108 unsigned short type;
5110 pFormat += 2;
5112 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5113 if(!pFormat)
5114 return NULL;
5116 type = *(const unsigned short*)pFormat;
5117 if((type & 0xff00) == 0x8000)
5119 unsigned char basetype = LOBYTE(type);
5120 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5122 else
5124 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5125 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5126 if (m)
5128 unsigned char *saved_buffer = NULL;
5129 int pointer_buffer_mark_set = 0;
5130 switch(*desc)
5132 case RPC_FC_RP:
5133 case RPC_FC_UP:
5134 case RPC_FC_OP:
5135 case RPC_FC_FP:
5136 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5137 saved_buffer = pStubMsg->Buffer;
5138 if (pStubMsg->PointerBufferMark)
5140 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5141 pStubMsg->PointerBufferMark = NULL;
5142 pointer_buffer_mark_set = 1;
5144 else
5145 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5147 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5148 if (pointer_buffer_mark_set)
5150 STD_OVERFLOW_CHECK(pStubMsg);
5151 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5152 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5154 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5155 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5156 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5158 pStubMsg->Buffer = saved_buffer + 4;
5160 break;
5161 default:
5162 m(pStubMsg, pMemory, desc);
5165 else FIXME("no marshaller for embedded type %02x\n", *desc);
5167 return NULL;
5170 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5171 unsigned char **ppMemory,
5172 ULONG discriminant,
5173 PFORMAT_STRING pFormat,
5174 unsigned char fMustAlloc)
5176 unsigned short type;
5178 pFormat += 2;
5180 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5181 if(!pFormat)
5182 return NULL;
5184 type = *(const unsigned short*)pFormat;
5185 if((type & 0xff00) == 0x8000)
5187 unsigned char basetype = LOBYTE(type);
5188 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5190 else
5192 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5193 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5194 if (m)
5196 unsigned char *saved_buffer = NULL;
5197 int pointer_buffer_mark_set = 0;
5198 switch(*desc)
5200 case RPC_FC_RP:
5201 case RPC_FC_UP:
5202 case RPC_FC_OP:
5203 case RPC_FC_FP:
5204 **(void***)ppMemory = NULL;
5205 ALIGN_POINTER(pStubMsg->Buffer, 4);
5206 saved_buffer = pStubMsg->Buffer;
5207 if (pStubMsg->PointerBufferMark)
5209 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5210 pStubMsg->PointerBufferMark = NULL;
5211 pointer_buffer_mark_set = 1;
5213 else
5214 pStubMsg->Buffer += 4; /* for pointer ID */
5216 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5218 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5219 saved_buffer, pStubMsg->BufferEnd);
5220 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5223 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5224 if (pointer_buffer_mark_set)
5226 STD_OVERFLOW_CHECK(pStubMsg);
5227 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5228 pStubMsg->Buffer = saved_buffer + 4;
5230 break;
5231 default:
5232 m(pStubMsg, ppMemory, desc, fMustAlloc);
5235 else FIXME("no marshaller for embedded type %02x\n", *desc);
5237 return NULL;
5240 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5241 unsigned char *pMemory,
5242 ULONG discriminant,
5243 PFORMAT_STRING pFormat)
5245 unsigned short type;
5247 pFormat += 2;
5249 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5250 if(!pFormat)
5251 return;
5253 type = *(const unsigned short*)pFormat;
5254 if((type & 0xff00) == 0x8000)
5256 unsigned char basetype = LOBYTE(type);
5257 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5259 else
5261 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5262 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5263 if (m)
5265 switch(*desc)
5267 case RPC_FC_RP:
5268 case RPC_FC_UP:
5269 case RPC_FC_OP:
5270 case RPC_FC_FP:
5271 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5272 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5273 if (!pStubMsg->IgnoreEmbeddedPointers)
5275 int saved_buffer_length = pStubMsg->BufferLength;
5276 pStubMsg->BufferLength = pStubMsg->PointerLength;
5277 pStubMsg->PointerLength = 0;
5278 if(!pStubMsg->BufferLength)
5279 ERR("BufferLength == 0??\n");
5280 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5281 pStubMsg->PointerLength = pStubMsg->BufferLength;
5282 pStubMsg->BufferLength = saved_buffer_length;
5284 break;
5285 default:
5286 m(pStubMsg, pMemory, desc);
5289 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5293 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5294 ULONG discriminant,
5295 PFORMAT_STRING pFormat)
5297 unsigned short type, size;
5299 size = *(const unsigned short*)pFormat;
5300 pStubMsg->Memory += size;
5301 pFormat += 2;
5303 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5304 if(!pFormat)
5305 return 0;
5307 type = *(const unsigned short*)pFormat;
5308 if((type & 0xff00) == 0x8000)
5310 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5312 else
5314 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5315 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5316 unsigned char *saved_buffer;
5317 if (m)
5319 switch(*desc)
5321 case RPC_FC_RP:
5322 case RPC_FC_UP:
5323 case RPC_FC_OP:
5324 case RPC_FC_FP:
5325 ALIGN_POINTER(pStubMsg->Buffer, 4);
5326 saved_buffer = pStubMsg->Buffer;
5327 safe_buffer_increment(pStubMsg, 4);
5328 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5329 pStubMsg->MemorySize += 4;
5330 if (!pStubMsg->IgnoreEmbeddedPointers)
5331 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5332 break;
5333 default:
5334 return m(pStubMsg, desc);
5337 else FIXME("no marshaller for embedded type %02x\n", *desc);
5340 TRACE("size %d\n", size);
5341 return size;
5344 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5345 unsigned char *pMemory,
5346 ULONG discriminant,
5347 PFORMAT_STRING pFormat)
5349 unsigned short type;
5351 pFormat += 2;
5353 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5354 if(!pFormat)
5355 return;
5357 type = *(const unsigned short*)pFormat;
5358 if((type & 0xff00) != 0x8000)
5360 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5361 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5362 if (m)
5364 switch(*desc)
5366 case RPC_FC_RP:
5367 case RPC_FC_UP:
5368 case RPC_FC_OP:
5369 case RPC_FC_FP:
5370 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5371 break;
5372 default:
5373 m(pStubMsg, pMemory, desc);
5379 /***********************************************************************
5380 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5382 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5383 unsigned char *pMemory,
5384 PFORMAT_STRING pFormat)
5386 unsigned char switch_type;
5387 unsigned char increment;
5388 ULONG switch_value;
5390 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5391 pFormat++;
5393 switch_type = *pFormat & 0xf;
5394 increment = (*pFormat & 0xf0) >> 4;
5395 pFormat++;
5397 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5399 switch_value = get_discriminant(switch_type, pMemory);
5400 TRACE("got switch value 0x%x\n", switch_value);
5402 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5403 pMemory += increment;
5405 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5408 /***********************************************************************
5409 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5411 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5412 unsigned char **ppMemory,
5413 PFORMAT_STRING pFormat,
5414 unsigned char fMustAlloc)
5416 unsigned char switch_type;
5417 unsigned char increment;
5418 ULONG switch_value;
5419 unsigned short size;
5420 unsigned char *pMemoryArm;
5422 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5423 pFormat++;
5425 switch_type = *pFormat & 0xf;
5426 increment = (*pFormat & 0xf0) >> 4;
5427 pFormat++;
5429 ALIGN_POINTER(pStubMsg->Buffer, increment);
5430 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5431 TRACE("got switch value 0x%x\n", switch_value);
5433 size = *(const unsigned short*)pFormat + increment;
5434 if(!*ppMemory || fMustAlloc)
5435 *ppMemory = NdrAllocate(pStubMsg, size);
5437 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5438 pMemoryArm = *ppMemory + increment;
5440 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5443 /***********************************************************************
5444 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5446 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5447 unsigned char *pMemory,
5448 PFORMAT_STRING pFormat)
5450 unsigned char switch_type;
5451 unsigned char increment;
5452 ULONG switch_value;
5454 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5455 pFormat++;
5457 switch_type = *pFormat & 0xf;
5458 increment = (*pFormat & 0xf0) >> 4;
5459 pFormat++;
5461 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5462 switch_value = get_discriminant(switch_type, pMemory);
5463 TRACE("got switch value 0x%x\n", switch_value);
5465 /* Add discriminant size */
5466 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5467 pMemory += increment;
5469 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5472 /***********************************************************************
5473 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5475 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5476 PFORMAT_STRING pFormat)
5478 unsigned char switch_type;
5479 unsigned char increment;
5480 ULONG switch_value;
5482 switch_type = *pFormat & 0xf;
5483 increment = (*pFormat & 0xf0) >> 4;
5484 pFormat++;
5486 ALIGN_POINTER(pStubMsg->Buffer, increment);
5487 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5488 TRACE("got switch value 0x%x\n", switch_value);
5490 pStubMsg->Memory += increment;
5492 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5495 /***********************************************************************
5496 * NdrEncapsulatedUnionFree [RPCRT4.@]
5498 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5499 unsigned char *pMemory,
5500 PFORMAT_STRING pFormat)
5502 unsigned char switch_type;
5503 unsigned char increment;
5504 ULONG switch_value;
5506 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5507 pFormat++;
5509 switch_type = *pFormat & 0xf;
5510 increment = (*pFormat & 0xf0) >> 4;
5511 pFormat++;
5513 switch_value = get_discriminant(switch_type, pMemory);
5514 TRACE("got switch value 0x%x\n", switch_value);
5516 pMemory += increment;
5518 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5521 /***********************************************************************
5522 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5524 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5525 unsigned char *pMemory,
5526 PFORMAT_STRING pFormat)
5528 unsigned char switch_type;
5530 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5531 pFormat++;
5533 switch_type = *pFormat;
5534 pFormat++;
5536 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5537 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5538 /* Marshall discriminant */
5539 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5541 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5544 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5545 PFORMAT_STRING *ppFormat)
5547 long discriminant = 0;
5549 switch(**ppFormat)
5551 case RPC_FC_BYTE:
5552 case RPC_FC_CHAR:
5553 case RPC_FC_SMALL:
5554 case RPC_FC_USMALL:
5556 UCHAR d;
5557 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5558 discriminant = d;
5559 break;
5561 case RPC_FC_WCHAR:
5562 case RPC_FC_SHORT:
5563 case RPC_FC_USHORT:
5565 USHORT d;
5566 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5567 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5568 discriminant = d;
5569 break;
5571 case RPC_FC_LONG:
5572 case RPC_FC_ULONG:
5574 ULONG d;
5575 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5576 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5577 discriminant = d;
5578 break;
5580 default:
5581 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5583 (*ppFormat)++;
5585 if (pStubMsg->fHasNewCorrDesc)
5586 *ppFormat += 6;
5587 else
5588 *ppFormat += 4;
5589 return discriminant;
5592 /**********************************************************************
5593 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5595 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5596 unsigned char **ppMemory,
5597 PFORMAT_STRING pFormat,
5598 unsigned char fMustAlloc)
5600 long discriminant;
5601 unsigned short size;
5603 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5604 pFormat++;
5606 /* Unmarshall discriminant */
5607 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5608 TRACE("unmarshalled discriminant %lx\n", discriminant);
5610 pFormat += *(const SHORT*)pFormat;
5612 size = *(const unsigned short*)pFormat;
5614 if(!*ppMemory || fMustAlloc)
5615 *ppMemory = NdrAllocate(pStubMsg, size);
5617 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5620 /***********************************************************************
5621 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5623 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5624 unsigned char *pMemory,
5625 PFORMAT_STRING pFormat)
5627 unsigned char switch_type;
5629 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5630 pFormat++;
5632 switch_type = *pFormat;
5633 pFormat++;
5635 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5636 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5637 /* Add discriminant size */
5638 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5640 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5643 /***********************************************************************
5644 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5646 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5647 PFORMAT_STRING pFormat)
5649 ULONG discriminant;
5651 pFormat++;
5652 /* Unmarshall discriminant */
5653 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5654 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5656 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5659 /***********************************************************************
5660 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5662 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5663 unsigned char *pMemory,
5664 PFORMAT_STRING pFormat)
5666 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5667 pFormat++;
5668 pFormat++;
5670 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5671 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5673 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5676 /***********************************************************************
5677 * NdrByteCountPointerMarshall [RPCRT4.@]
5679 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5680 unsigned char *pMemory,
5681 PFORMAT_STRING pFormat)
5683 FIXME("stub\n");
5684 return NULL;
5687 /***********************************************************************
5688 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5690 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5691 unsigned char **ppMemory,
5692 PFORMAT_STRING pFormat,
5693 unsigned char fMustAlloc)
5695 FIXME("stub\n");
5696 return NULL;
5699 /***********************************************************************
5700 * NdrByteCountPointerBufferSize [RPCRT4.@]
5702 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5703 unsigned char *pMemory,
5704 PFORMAT_STRING pFormat)
5706 FIXME("stub\n");
5709 /***********************************************************************
5710 * NdrByteCountPointerMemorySize [RPCRT4.@]
5712 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5713 PFORMAT_STRING pFormat)
5715 FIXME("stub\n");
5716 return 0;
5719 /***********************************************************************
5720 * NdrByteCountPointerFree [RPCRT4.@]
5722 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5723 unsigned char *pMemory,
5724 PFORMAT_STRING pFormat)
5726 FIXME("stub\n");
5729 /***********************************************************************
5730 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5732 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5733 unsigned char *pMemory,
5734 PFORMAT_STRING pFormat)
5736 FIXME("stub\n");
5737 return NULL;
5740 /***********************************************************************
5741 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5743 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5744 unsigned char **ppMemory,
5745 PFORMAT_STRING pFormat,
5746 unsigned char fMustAlloc)
5748 FIXME("stub\n");
5749 return NULL;
5752 /***********************************************************************
5753 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5755 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5756 unsigned char *pMemory,
5757 PFORMAT_STRING pFormat)
5759 FIXME("stub\n");
5762 /***********************************************************************
5763 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5765 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5766 PFORMAT_STRING pFormat)
5768 FIXME("stub\n");
5769 return 0;
5772 /***********************************************************************
5773 * NdrXmitOrRepAsFree [RPCRT4.@]
5775 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5776 unsigned char *pMemory,
5777 PFORMAT_STRING pFormat)
5779 FIXME("stub\n");
5782 /***********************************************************************
5783 * NdrRangeMarshall [internal]
5785 unsigned char *WINAPI NdrRangeMarshall(
5786 PMIDL_STUB_MESSAGE pStubMsg,
5787 unsigned char *pMemory,
5788 PFORMAT_STRING pFormat)
5790 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5791 unsigned char base_type;
5793 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5795 if (pRange->type != RPC_FC_RANGE)
5797 ERR("invalid format type %x\n", pRange->type);
5798 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5799 return NULL;
5802 base_type = pRange->flags_type & 0xf;
5804 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5807 /***********************************************************************
5808 * NdrRangeUnmarshall
5810 unsigned char *WINAPI NdrRangeUnmarshall(
5811 PMIDL_STUB_MESSAGE pStubMsg,
5812 unsigned char **ppMemory,
5813 PFORMAT_STRING pFormat,
5814 unsigned char fMustAlloc)
5816 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5817 unsigned char base_type;
5819 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5821 if (pRange->type != RPC_FC_RANGE)
5823 ERR("invalid format type %x\n", pRange->type);
5824 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5825 return NULL;
5827 base_type = pRange->flags_type & 0xf;
5829 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5830 base_type, pRange->low_value, pRange->high_value);
5832 #define RANGE_UNMARSHALL(type, format_spec) \
5833 do \
5835 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5836 if (fMustAlloc || !*ppMemory) \
5837 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5838 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5840 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5841 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5842 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5844 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5845 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5847 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5848 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5849 (type)pRange->high_value); \
5850 RpcRaiseException(RPC_S_INVALID_BOUND); \
5851 return NULL; \
5853 TRACE("*ppMemory: %p\n", *ppMemory); \
5854 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5855 pStubMsg->Buffer += sizeof(type); \
5856 } while (0)
5858 switch(base_type)
5860 case RPC_FC_CHAR:
5861 case RPC_FC_SMALL:
5862 RANGE_UNMARSHALL(UCHAR, "%d");
5863 TRACE("value: 0x%02x\n", **ppMemory);
5864 break;
5865 case RPC_FC_BYTE:
5866 case RPC_FC_USMALL:
5867 RANGE_UNMARSHALL(CHAR, "%u");
5868 TRACE("value: 0x%02x\n", **ppMemory);
5869 break;
5870 case RPC_FC_WCHAR: /* FIXME: valid? */
5871 case RPC_FC_USHORT:
5872 RANGE_UNMARSHALL(USHORT, "%u");
5873 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5874 break;
5875 case RPC_FC_SHORT:
5876 RANGE_UNMARSHALL(SHORT, "%d");
5877 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5878 break;
5879 case RPC_FC_LONG:
5880 RANGE_UNMARSHALL(LONG, "%d");
5881 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5882 break;
5883 case RPC_FC_ULONG:
5884 RANGE_UNMARSHALL(ULONG, "%u");
5885 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5886 break;
5887 case RPC_FC_ENUM16:
5888 case RPC_FC_ENUM32:
5889 FIXME("Unhandled enum type\n");
5890 break;
5891 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5892 case RPC_FC_FLOAT:
5893 case RPC_FC_DOUBLE:
5894 case RPC_FC_HYPER:
5895 default:
5896 ERR("invalid range base type: 0x%02x\n", base_type);
5897 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5900 return NULL;
5903 /***********************************************************************
5904 * NdrRangeBufferSize [internal]
5906 void WINAPI NdrRangeBufferSize(
5907 PMIDL_STUB_MESSAGE pStubMsg,
5908 unsigned char *pMemory,
5909 PFORMAT_STRING pFormat)
5911 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5912 unsigned char base_type;
5914 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5916 if (pRange->type != RPC_FC_RANGE)
5918 ERR("invalid format type %x\n", pRange->type);
5919 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5921 base_type = pRange->flags_type & 0xf;
5923 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5926 /***********************************************************************
5927 * NdrRangeMemorySize [internal]
5929 ULONG WINAPI NdrRangeMemorySize(
5930 PMIDL_STUB_MESSAGE pStubMsg,
5931 PFORMAT_STRING pFormat)
5933 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5934 unsigned char base_type;
5936 if (pRange->type != RPC_FC_RANGE)
5938 ERR("invalid format type %x\n", pRange->type);
5939 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5940 return 0;
5942 base_type = pRange->flags_type & 0xf;
5944 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5947 /***********************************************************************
5948 * NdrRangeFree [internal]
5950 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5951 unsigned char *pMemory,
5952 PFORMAT_STRING pFormat)
5954 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5956 /* nothing to do */
5959 /***********************************************************************
5960 * NdrBaseTypeMarshall [internal]
5962 static unsigned char *WINAPI NdrBaseTypeMarshall(
5963 PMIDL_STUB_MESSAGE pStubMsg,
5964 unsigned char *pMemory,
5965 PFORMAT_STRING pFormat)
5967 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5969 switch(*pFormat)
5971 case RPC_FC_BYTE:
5972 case RPC_FC_CHAR:
5973 case RPC_FC_SMALL:
5974 case RPC_FC_USMALL:
5975 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5976 TRACE("value: 0x%02x\n", *pMemory);
5977 break;
5978 case RPC_FC_WCHAR:
5979 case RPC_FC_SHORT:
5980 case RPC_FC_USHORT:
5981 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5982 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5983 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5984 break;
5985 case RPC_FC_LONG:
5986 case RPC_FC_ULONG:
5987 case RPC_FC_ERROR_STATUS_T:
5988 case RPC_FC_ENUM32:
5989 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
5990 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5991 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5992 break;
5993 case RPC_FC_FLOAT:
5994 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
5995 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5996 break;
5997 case RPC_FC_DOUBLE:
5998 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
5999 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6000 break;
6001 case RPC_FC_HYPER:
6002 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6003 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6004 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6005 break;
6006 case RPC_FC_ENUM16:
6007 /* only 16-bits on the wire, so do a sanity check */
6008 if (*(UINT *)pMemory > SHRT_MAX)
6009 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6010 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6011 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6012 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6013 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6014 pStubMsg->Buffer += sizeof(USHORT);
6015 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6016 break;
6017 case RPC_FC_IGNORE:
6018 break;
6019 default:
6020 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6023 /* FIXME: what is the correct return value? */
6024 return NULL;
6027 /***********************************************************************
6028 * NdrBaseTypeUnmarshall [internal]
6030 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6031 PMIDL_STUB_MESSAGE pStubMsg,
6032 unsigned char **ppMemory,
6033 PFORMAT_STRING pFormat,
6034 unsigned char fMustAlloc)
6036 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6038 #define BASE_TYPE_UNMARSHALL(type) \
6039 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6040 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6042 *ppMemory = pStubMsg->Buffer; \
6043 TRACE("*ppMemory: %p\n", *ppMemory); \
6044 safe_buffer_increment(pStubMsg, sizeof(type)); \
6046 else \
6048 if (fMustAlloc) \
6049 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6050 TRACE("*ppMemory: %p\n", *ppMemory); \
6051 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6054 switch(*pFormat)
6056 case RPC_FC_BYTE:
6057 case RPC_FC_CHAR:
6058 case RPC_FC_SMALL:
6059 case RPC_FC_USMALL:
6060 BASE_TYPE_UNMARSHALL(UCHAR);
6061 TRACE("value: 0x%02x\n", **ppMemory);
6062 break;
6063 case RPC_FC_WCHAR:
6064 case RPC_FC_SHORT:
6065 case RPC_FC_USHORT:
6066 BASE_TYPE_UNMARSHALL(USHORT);
6067 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6068 break;
6069 case RPC_FC_LONG:
6070 case RPC_FC_ULONG:
6071 case RPC_FC_ERROR_STATUS_T:
6072 case RPC_FC_ENUM32:
6073 BASE_TYPE_UNMARSHALL(ULONG);
6074 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6075 break;
6076 case RPC_FC_FLOAT:
6077 BASE_TYPE_UNMARSHALL(float);
6078 TRACE("value: %f\n", **(float **)ppMemory);
6079 break;
6080 case RPC_FC_DOUBLE:
6081 BASE_TYPE_UNMARSHALL(double);
6082 TRACE("value: %f\n", **(double **)ppMemory);
6083 break;
6084 case RPC_FC_HYPER:
6085 BASE_TYPE_UNMARSHALL(ULONGLONG);
6086 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6087 break;
6088 case RPC_FC_ENUM16:
6089 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6090 if (fMustAlloc || !*ppMemory)
6091 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6092 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6093 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6094 TRACE("*ppMemory: %p\n", *ppMemory);
6095 /* 16-bits on the wire, but int in memory */
6096 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6097 pStubMsg->Buffer += sizeof(USHORT);
6098 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6099 break;
6100 case RPC_FC_IGNORE:
6101 break;
6102 default:
6103 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6105 #undef BASE_TYPE_UNMARSHALL
6107 /* FIXME: what is the correct return value? */
6109 return NULL;
6112 /***********************************************************************
6113 * NdrBaseTypeBufferSize [internal]
6115 static void WINAPI NdrBaseTypeBufferSize(
6116 PMIDL_STUB_MESSAGE pStubMsg,
6117 unsigned char *pMemory,
6118 PFORMAT_STRING pFormat)
6120 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6122 switch(*pFormat)
6124 case RPC_FC_BYTE:
6125 case RPC_FC_CHAR:
6126 case RPC_FC_SMALL:
6127 case RPC_FC_USMALL:
6128 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6129 break;
6130 case RPC_FC_WCHAR:
6131 case RPC_FC_SHORT:
6132 case RPC_FC_USHORT:
6133 case RPC_FC_ENUM16:
6134 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6135 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6136 break;
6137 case RPC_FC_LONG:
6138 case RPC_FC_ULONG:
6139 case RPC_FC_ENUM32:
6140 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6141 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6142 break;
6143 case RPC_FC_FLOAT:
6144 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6145 safe_buffer_length_increment(pStubMsg, sizeof(float));
6146 break;
6147 case RPC_FC_DOUBLE:
6148 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6149 safe_buffer_length_increment(pStubMsg, sizeof(double));
6150 break;
6151 case RPC_FC_HYPER:
6152 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6153 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6154 break;
6155 case RPC_FC_ERROR_STATUS_T:
6156 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6157 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6158 break;
6159 case RPC_FC_IGNORE:
6160 break;
6161 default:
6162 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6166 /***********************************************************************
6167 * NdrBaseTypeMemorySize [internal]
6169 static ULONG WINAPI NdrBaseTypeMemorySize(
6170 PMIDL_STUB_MESSAGE pStubMsg,
6171 PFORMAT_STRING pFormat)
6173 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6175 switch(*pFormat)
6177 case RPC_FC_BYTE:
6178 case RPC_FC_CHAR:
6179 case RPC_FC_SMALL:
6180 case RPC_FC_USMALL:
6181 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6182 pStubMsg->MemorySize += sizeof(UCHAR);
6183 return sizeof(UCHAR);
6184 case RPC_FC_WCHAR:
6185 case RPC_FC_SHORT:
6186 case RPC_FC_USHORT:
6187 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6188 pStubMsg->MemorySize += sizeof(USHORT);
6189 return sizeof(USHORT);
6190 case RPC_FC_LONG:
6191 case RPC_FC_ULONG:
6192 case RPC_FC_ENUM32:
6193 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6194 pStubMsg->MemorySize += sizeof(ULONG);
6195 return sizeof(ULONG);
6196 case RPC_FC_FLOAT:
6197 safe_buffer_increment(pStubMsg, sizeof(float));
6198 pStubMsg->MemorySize += sizeof(float);
6199 return sizeof(float);
6200 case RPC_FC_DOUBLE:
6201 safe_buffer_increment(pStubMsg, sizeof(double));
6202 pStubMsg->MemorySize += sizeof(double);
6203 return sizeof(double);
6204 case RPC_FC_HYPER:
6205 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6206 pStubMsg->MemorySize += sizeof(ULONGLONG);
6207 return sizeof(ULONGLONG);
6208 case RPC_FC_ERROR_STATUS_T:
6209 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6210 pStubMsg->MemorySize += sizeof(error_status_t);
6211 return sizeof(error_status_t);
6212 case RPC_FC_ENUM16:
6213 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6214 pStubMsg->MemorySize += sizeof(UINT);
6215 return sizeof(UINT);
6216 case RPC_FC_IGNORE:
6217 pStubMsg->MemorySize += sizeof(void *);
6218 return sizeof(void *);
6219 default:
6220 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6221 return 0;
6225 /***********************************************************************
6226 * NdrBaseTypeFree [internal]
6228 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6229 unsigned char *pMemory,
6230 PFORMAT_STRING pFormat)
6232 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6234 /* nothing to do */
6237 /***********************************************************************
6238 * NdrContextHandleBufferSize [internal]
6240 static void WINAPI NdrContextHandleBufferSize(
6241 PMIDL_STUB_MESSAGE pStubMsg,
6242 unsigned char *pMemory,
6243 PFORMAT_STRING pFormat)
6245 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6247 if (*pFormat != RPC_FC_BIND_CONTEXT)
6249 ERR("invalid format type %x\n", *pFormat);
6250 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6252 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6253 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6256 /***********************************************************************
6257 * NdrContextHandleMarshall [internal]
6259 static unsigned char *WINAPI NdrContextHandleMarshall(
6260 PMIDL_STUB_MESSAGE pStubMsg,
6261 unsigned char *pMemory,
6262 PFORMAT_STRING pFormat)
6264 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6266 if (*pFormat != RPC_FC_BIND_CONTEXT)
6268 ERR("invalid format type %x\n", *pFormat);
6269 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6271 TRACE("flags: 0x%02x\n", pFormat[1]);
6273 if (pFormat[1] & 0x80)
6274 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6275 else
6276 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6278 return NULL;
6281 /***********************************************************************
6282 * NdrContextHandleUnmarshall [internal]
6284 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6285 PMIDL_STUB_MESSAGE pStubMsg,
6286 unsigned char **ppMemory,
6287 PFORMAT_STRING pFormat,
6288 unsigned char fMustAlloc)
6290 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6291 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6293 if (*pFormat != RPC_FC_BIND_CONTEXT)
6295 ERR("invalid format type %x\n", *pFormat);
6296 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6298 TRACE("flags: 0x%02x\n", pFormat[1]);
6300 /* [out]-only or [ret] param */
6301 if ((pFormat[1] & 0x60) == 0x20)
6302 **(NDR_CCONTEXT **)ppMemory = NULL;
6303 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6305 return NULL;
6308 /***********************************************************************
6309 * NdrClientContextMarshall [RPCRT4.@]
6311 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6312 NDR_CCONTEXT ContextHandle,
6313 int fCheck)
6315 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6317 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6319 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6321 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6322 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6323 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6326 /* FIXME: what does fCheck do? */
6327 NDRCContextMarshall(ContextHandle,
6328 pStubMsg->Buffer);
6330 pStubMsg->Buffer += cbNDRContext;
6333 /***********************************************************************
6334 * NdrClientContextUnmarshall [RPCRT4.@]
6336 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6337 NDR_CCONTEXT * pContextHandle,
6338 RPC_BINDING_HANDLE BindHandle)
6340 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6342 ALIGN_POINTER(pStubMsg->Buffer, 4);
6344 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6345 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6347 NDRCContextUnmarshall(pContextHandle,
6348 BindHandle,
6349 pStubMsg->Buffer,
6350 pStubMsg->RpcMsg->DataRepresentation);
6352 pStubMsg->Buffer += cbNDRContext;
6355 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6356 NDR_SCONTEXT ContextHandle,
6357 NDR_RUNDOWN RundownRoutine )
6359 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6361 ALIGN_POINTER(pStubMsg->Buffer, 4);
6363 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6365 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6366 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6367 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6370 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6371 pStubMsg->Buffer, RundownRoutine, NULL,
6372 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6373 pStubMsg->Buffer += cbNDRContext;
6376 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6378 NDR_SCONTEXT ContextHandle;
6380 TRACE("(%p)\n", pStubMsg);
6382 ALIGN_POINTER(pStubMsg->Buffer, 4);
6384 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6386 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6387 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6388 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6391 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6392 pStubMsg->Buffer,
6393 pStubMsg->RpcMsg->DataRepresentation,
6394 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6395 pStubMsg->Buffer += cbNDRContext;
6397 return ContextHandle;
6400 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6401 unsigned char* pMemory,
6402 PFORMAT_STRING pFormat)
6404 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6407 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6408 PFORMAT_STRING pFormat)
6410 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6411 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6413 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6415 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6416 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6417 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6418 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6419 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6421 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6422 if_id = &sif->InterfaceId;
6425 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6426 pStubMsg->RpcMsg->DataRepresentation, if_id,
6427 flags);
6430 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6431 NDR_SCONTEXT ContextHandle,
6432 NDR_RUNDOWN RundownRoutine,
6433 PFORMAT_STRING pFormat)
6435 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6436 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6438 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6440 ALIGN_POINTER(pStubMsg->Buffer, 4);
6442 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6444 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6445 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6446 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6449 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6450 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6451 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6452 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6453 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6455 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6456 if_id = &sif->InterfaceId;
6459 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6460 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6461 pStubMsg->Buffer += cbNDRContext;
6464 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6465 PFORMAT_STRING pFormat)
6467 NDR_SCONTEXT ContextHandle;
6468 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6469 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6471 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6473 ALIGN_POINTER(pStubMsg->Buffer, 4);
6475 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6477 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6478 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6479 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6482 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6483 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6484 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6485 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6486 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6488 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6489 if_id = &sif->InterfaceId;
6492 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6493 pStubMsg->Buffer,
6494 pStubMsg->RpcMsg->DataRepresentation,
6495 if_id, flags);
6496 pStubMsg->Buffer += cbNDRContext;
6498 return ContextHandle;
6501 /***********************************************************************
6502 * NdrCorrelationInitialize [RPCRT4.@]
6504 * Initializes correlation validity checking.
6506 * PARAMS
6507 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6508 * pMemory [I] Pointer to memory to use as a cache.
6509 * CacheSize [I] Size of the memory pointed to by pMemory.
6510 * Flags [I] Reserved. Set to zero.
6512 * RETURNS
6513 * Nothing.
6515 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6517 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6518 pStubMsg->fHasNewCorrDesc = TRUE;
6521 /***********************************************************************
6522 * NdrCorrelationPass [RPCRT4.@]
6524 * Performs correlation validity checking.
6526 * PARAMS
6527 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6529 * RETURNS
6530 * Nothing.
6532 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6534 FIXME("(%p): stub\n", pStubMsg);
6537 /***********************************************************************
6538 * NdrCorrelationFree [RPCRT4.@]
6540 * Frees any resources used while unmarshalling parameters that need
6541 * correlation validity checking.
6543 * PARAMS
6544 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6546 * RETURNS
6547 * Nothing.
6549 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6551 FIXME("(%p): stub\n", pStubMsg);