push 6fe5edf8439c19d3885814583531c2f2b1495177
[wine/hacks.git] / dlls / rpcrt4 / ndr_marshall.c
blob5841dc91a3c9e4a78318549be2ae0f03fe58bd35
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_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
118 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
122 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
123 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
124 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
126 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
128 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
132 /* 0x10 */
133 NdrBaseTypeMarshall,
134 /* 0x11 */
135 NdrPointerMarshall, NdrPointerMarshall,
136 NdrPointerMarshall, NdrPointerMarshall,
137 /* 0x15 */
138 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
139 NdrConformantStructMarshall, NdrConformantStructMarshall,
140 NdrConformantVaryingStructMarshall,
141 NdrComplexStructMarshall,
142 /* 0x1b */
143 NdrConformantArrayMarshall,
144 NdrConformantVaryingArrayMarshall,
145 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
146 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
147 NdrComplexArrayMarshall,
148 /* 0x22 */
149 NdrConformantStringMarshall, 0, 0,
150 NdrConformantStringMarshall,
151 NdrNonConformantStringMarshall, 0, 0, 0,
152 /* 0x2a */
153 NdrEncapsulatedUnionMarshall,
154 NdrNonEncapsulatedUnionMarshall,
155 NdrByteCountPointerMarshall,
156 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
157 /* 0x2f */
158 NdrInterfacePointerMarshall,
159 /* 0x30 */
160 NdrContextHandleMarshall,
161 /* 0xb1 */
162 0, 0, 0,
163 NdrUserMarshalMarshall,
164 0, 0,
165 /* 0xb7 */
166 NdrRangeMarshall
168 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
170 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
174 /* 0x10 */
175 NdrBaseTypeUnmarshall,
176 /* 0x11 */
177 NdrPointerUnmarshall, NdrPointerUnmarshall,
178 NdrPointerUnmarshall, NdrPointerUnmarshall,
179 /* 0x15 */
180 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
181 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
182 NdrConformantVaryingStructUnmarshall,
183 NdrComplexStructUnmarshall,
184 /* 0x1b */
185 NdrConformantArrayUnmarshall,
186 NdrConformantVaryingArrayUnmarshall,
187 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
188 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
189 NdrComplexArrayUnmarshall,
190 /* 0x22 */
191 NdrConformantStringUnmarshall, 0, 0,
192 NdrConformantStringUnmarshall,
193 NdrNonConformantStringUnmarshall, 0, 0, 0,
194 /* 0x2a */
195 NdrEncapsulatedUnionUnmarshall,
196 NdrNonEncapsulatedUnionUnmarshall,
197 NdrByteCountPointerUnmarshall,
198 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
199 /* 0x2f */
200 NdrInterfacePointerUnmarshall,
201 /* 0x30 */
202 NdrContextHandleUnmarshall,
203 /* 0xb1 */
204 0, 0, 0,
205 NdrUserMarshalUnmarshall,
206 0, 0,
207 /* 0xb7 */
208 NdrRangeUnmarshall
210 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
212 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
216 /* 0x10 */
217 NdrBaseTypeBufferSize,
218 /* 0x11 */
219 NdrPointerBufferSize, NdrPointerBufferSize,
220 NdrPointerBufferSize, NdrPointerBufferSize,
221 /* 0x15 */
222 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
223 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
224 NdrConformantVaryingStructBufferSize,
225 NdrComplexStructBufferSize,
226 /* 0x1b */
227 NdrConformantArrayBufferSize,
228 NdrConformantVaryingArrayBufferSize,
229 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
230 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
231 NdrComplexArrayBufferSize,
232 /* 0x22 */
233 NdrConformantStringBufferSize, 0, 0,
234 NdrConformantStringBufferSize,
235 NdrNonConformantStringBufferSize, 0, 0, 0,
236 /* 0x2a */
237 NdrEncapsulatedUnionBufferSize,
238 NdrNonEncapsulatedUnionBufferSize,
239 NdrByteCountPointerBufferSize,
240 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
241 /* 0x2f */
242 NdrInterfacePointerBufferSize,
243 /* 0x30 */
244 NdrContextHandleBufferSize,
245 /* 0xb1 */
246 0, 0, 0,
247 NdrUserMarshalBufferSize,
248 0, 0,
249 /* 0xb7 */
250 NdrRangeBufferSize
252 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
254 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
258 /* 0x10 */
259 NdrBaseTypeMemorySize,
260 /* 0x11 */
261 NdrPointerMemorySize, NdrPointerMemorySize,
262 NdrPointerMemorySize, NdrPointerMemorySize,
263 /* 0x15 */
264 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
265 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
266 NdrConformantVaryingStructMemorySize,
267 NdrComplexStructMemorySize,
268 /* 0x1b */
269 NdrConformantArrayMemorySize,
270 NdrConformantVaryingArrayMemorySize,
271 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
272 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
273 NdrComplexArrayMemorySize,
274 /* 0x22 */
275 NdrConformantStringMemorySize, 0, 0,
276 NdrConformantStringMemorySize,
277 NdrNonConformantStringMemorySize, 0, 0, 0,
278 /* 0x2a */
279 NdrEncapsulatedUnionMemorySize,
280 NdrNonEncapsulatedUnionMemorySize,
281 NdrByteCountPointerMemorySize,
282 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
283 /* 0x2f */
284 NdrInterfacePointerMemorySize,
285 /* 0x30 */
287 /* 0xb1 */
288 0, 0, 0,
289 NdrUserMarshalMemorySize,
290 0, 0,
291 /* 0xb7 */
292 NdrRangeMemorySize
294 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
296 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
298 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
299 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
300 /* 0x10 */
301 NdrBaseTypeFree,
302 /* 0x11 */
303 NdrPointerFree, NdrPointerFree,
304 NdrPointerFree, NdrPointerFree,
305 /* 0x15 */
306 NdrSimpleStructFree, NdrSimpleStructFree,
307 NdrConformantStructFree, NdrConformantStructFree,
308 NdrConformantVaryingStructFree,
309 NdrComplexStructFree,
310 /* 0x1b */
311 NdrConformantArrayFree,
312 NdrConformantVaryingArrayFree,
313 NdrFixedArrayFree, NdrFixedArrayFree,
314 NdrVaryingArrayFree, NdrVaryingArrayFree,
315 NdrComplexArrayFree,
316 /* 0x22 */
317 0, 0, 0,
318 0, 0, 0, 0, 0,
319 /* 0x2a */
320 NdrEncapsulatedUnionFree,
321 NdrNonEncapsulatedUnionFree,
323 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
324 /* 0x2f */
325 NdrInterfacePointerFree,
326 /* 0x30 */
328 /* 0xb1 */
329 0, 0, 0,
330 NdrUserMarshalFree,
331 0, 0,
332 /* 0xb7 */
333 NdrRangeFree
336 typedef struct _NDR_MEMORY_LIST
338 ULONG magic;
339 ULONG size;
340 ULONG reserved;
341 struct _NDR_MEMORY_LIST *next;
342 } NDR_MEMORY_LIST;
344 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
346 /***********************************************************************
347 * NdrAllocate [RPCRT4.@]
349 * Allocates a block of memory using pStubMsg->pfnAllocate.
351 * PARAMS
352 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
353 * len [I] Size of memory block to allocate.
355 * RETURNS
356 * The memory block of size len that was allocated.
358 * NOTES
359 * The memory block is always 8-byte aligned.
360 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
361 * exception is raised.
363 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
365 size_t aligned_len;
366 size_t adjusted_len;
367 void *p;
368 NDR_MEMORY_LIST *mem_list;
370 aligned_len = ALIGNED_LENGTH(len, 8);
371 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
372 /* check for overflow */
373 if (adjusted_len < len)
375 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len);
376 RpcRaiseException(RPC_X_BAD_STUB_DATA);
379 p = pStubMsg->pfnAllocate(adjusted_len);
380 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
382 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
383 mem_list->magic = MEML_MAGIC;
384 mem_list->size = aligned_len;
385 mem_list->reserved = 0;
386 mem_list->next = pStubMsg->pMemoryList;
387 pStubMsg->pMemoryList = mem_list;
389 TRACE("-- %p\n", p);
390 return p;
393 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
395 TRACE("(%p, %p)\n", pStubMsg, Pointer);
397 pStubMsg->pfnFree(Pointer);
400 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
402 return (*(const ULONG *)pFormat != -1);
405 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
407 ALIGN_POINTER(pStubMsg->Buffer, 4);
408 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
409 RpcRaiseException(RPC_X_BAD_STUB_DATA);
410 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
411 pStubMsg->Buffer += 4;
412 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
413 if (pStubMsg->fHasNewCorrDesc)
414 return pFormat+6;
415 else
416 return pFormat+4;
419 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
421 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
423 pStubMsg->Offset = 0;
424 pStubMsg->ActualCount = pStubMsg->MaxCount;
425 goto done;
428 ALIGN_POINTER(pStubMsg->Buffer, 4);
429 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
430 RpcRaiseException(RPC_X_BAD_STUB_DATA);
431 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
432 pStubMsg->Buffer += 4;
433 TRACE("offset is %d\n", pStubMsg->Offset);
434 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
435 pStubMsg->Buffer += 4;
436 TRACE("variance is %d\n", pStubMsg->ActualCount);
438 if ((pStubMsg->ActualCount > MaxValue) ||
439 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
441 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
442 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
443 RpcRaiseException(RPC_S_INVALID_BOUND);
444 return NULL;
447 done:
448 if (pStubMsg->fHasNewCorrDesc)
449 return pFormat+6;
450 else
451 return pFormat+4;
454 /* writes the conformance value to the buffer */
455 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
457 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
458 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
459 RpcRaiseException(RPC_X_BAD_STUB_DATA);
460 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
461 pStubMsg->Buffer += 4;
464 /* writes the variance values to the buffer */
465 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
467 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
468 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
469 RpcRaiseException(RPC_X_BAD_STUB_DATA);
470 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
471 pStubMsg->Buffer += 4;
472 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
473 pStubMsg->Buffer += 4;
476 /* requests buffer space for the conformance value */
477 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
479 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
480 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
481 RpcRaiseException(RPC_X_BAD_STUB_DATA);
482 pStubMsg->BufferLength += 4;
485 /* requests buffer space for the variance values */
486 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
488 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
489 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
490 RpcRaiseException(RPC_X_BAD_STUB_DATA);
491 pStubMsg->BufferLength += 8;
494 PFORMAT_STRING ComputeConformanceOrVariance(
495 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
496 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
498 BYTE dtype = pFormat[0] & 0xf;
499 short ofs = *(const short *)&pFormat[2];
500 LPVOID ptr = NULL;
501 DWORD data = 0;
503 if (!IsConformanceOrVariancePresent(pFormat)) {
504 /* null descriptor */
505 *pCount = def;
506 goto finish_conf;
509 switch (pFormat[0] & 0xf0) {
510 case RPC_FC_NORMAL_CONFORMANCE:
511 TRACE("normal conformance, ofs=%d\n", ofs);
512 ptr = pMemory;
513 break;
514 case RPC_FC_POINTER_CONFORMANCE:
515 TRACE("pointer conformance, ofs=%d\n", ofs);
516 ptr = pStubMsg->Memory;
517 break;
518 case RPC_FC_TOP_LEVEL_CONFORMANCE:
519 TRACE("toplevel conformance, ofs=%d\n", ofs);
520 if (pStubMsg->StackTop) {
521 ptr = pStubMsg->StackTop;
523 else {
524 /* -Os mode, *pCount is already set */
525 goto finish_conf;
527 break;
528 case RPC_FC_CONSTANT_CONFORMANCE:
529 data = ofs | ((DWORD)pFormat[1] << 16);
530 TRACE("constant conformance, val=%d\n", data);
531 *pCount = data;
532 goto finish_conf;
533 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
534 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
535 if (pStubMsg->StackTop) {
536 ptr = pStubMsg->StackTop;
538 else {
539 /* ? */
540 goto done_conf_grab;
542 break;
543 default:
544 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
547 switch (pFormat[1]) {
548 case RPC_FC_DEREFERENCE:
549 ptr = *(LPVOID*)((char *)ptr + ofs);
550 break;
551 case RPC_FC_CALLBACK:
553 unsigned char *old_stack_top = pStubMsg->StackTop;
554 pStubMsg->StackTop = ptr;
556 /* ofs is index into StubDesc->apfnExprEval */
557 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
558 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
560 pStubMsg->StackTop = old_stack_top;
562 /* the callback function always stores the computed value in MaxCount */
563 *pCount = pStubMsg->MaxCount;
564 goto finish_conf;
566 default:
567 ptr = (char *)ptr + ofs;
568 break;
571 switch (dtype) {
572 case RPC_FC_LONG:
573 case RPC_FC_ULONG:
574 data = *(DWORD*)ptr;
575 break;
576 case RPC_FC_SHORT:
577 data = *(SHORT*)ptr;
578 break;
579 case RPC_FC_USHORT:
580 data = *(USHORT*)ptr;
581 break;
582 case RPC_FC_CHAR:
583 case RPC_FC_SMALL:
584 data = *(CHAR*)ptr;
585 break;
586 case RPC_FC_BYTE:
587 case RPC_FC_USMALL:
588 data = *(UCHAR*)ptr;
589 break;
590 default:
591 FIXME("unknown conformance data type %x\n", dtype);
592 goto done_conf_grab;
594 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
596 done_conf_grab:
597 switch (pFormat[1]) {
598 case RPC_FC_DEREFERENCE: /* already handled */
599 case 0: /* no op */
600 *pCount = data;
601 break;
602 case RPC_FC_ADD_1:
603 *pCount = data + 1;
604 break;
605 case RPC_FC_SUB_1:
606 *pCount = data - 1;
607 break;
608 case RPC_FC_MULT_2:
609 *pCount = data * 2;
610 break;
611 case RPC_FC_DIV_2:
612 *pCount = data / 2;
613 break;
614 default:
615 FIXME("unknown conformance op %d\n", pFormat[1]);
616 goto finish_conf;
619 finish_conf:
620 TRACE("resulting conformance is %ld\n", *pCount);
621 if (pStubMsg->fHasNewCorrDesc)
622 return pFormat+6;
623 else
624 return pFormat+4;
627 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
628 * the result overflows 32-bits */
629 static inline ULONG safe_multiply(ULONG a, ULONG b)
631 ULONGLONG ret = (ULONGLONG)a * b;
632 if (ret > 0xffffffff)
634 RpcRaiseException(RPC_S_INVALID_BOUND);
635 return 0;
637 return ret;
640 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
642 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
643 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
644 RpcRaiseException(RPC_X_BAD_STUB_DATA);
645 pStubMsg->Buffer += size;
648 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
650 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
652 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
653 pStubMsg->BufferLength, size);
654 RpcRaiseException(RPC_X_BAD_STUB_DATA);
656 pStubMsg->BufferLength += size;
659 /* copies data from the buffer, checking that there is enough data in the buffer
660 * to do so */
661 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
663 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
664 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
666 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
667 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
668 RpcRaiseException(RPC_X_BAD_STUB_DATA);
670 if (p == pStubMsg->Buffer)
671 ERR("pointer is the same as the buffer\n");
672 memcpy(p, pStubMsg->Buffer, size);
673 pStubMsg->Buffer += size;
676 /* copies data to the buffer, checking that there is enough space to do so */
677 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
679 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
680 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
682 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
683 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
684 size);
685 RpcRaiseException(RPC_X_BAD_STUB_DATA);
687 memcpy(pStubMsg->Buffer, p, size);
688 pStubMsg->Buffer += size;
692 * NdrConformantString:
694 * What MS calls a ConformantString is, in DCE terminology,
695 * a Varying-Conformant String.
697 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
698 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
699 * into unmarshalled string)
700 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
701 * [
702 * data: CHARTYPE[maxlen]
703 * ]
704 * ], where CHARTYPE is the appropriate character type (specified externally)
708 /***********************************************************************
709 * NdrConformantStringMarshall [RPCRT4.@]
711 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
712 unsigned char *pszMessage, PFORMAT_STRING pFormat)
714 ULONG esize, size;
716 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
718 if (*pFormat == RPC_FC_C_CSTRING) {
719 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
720 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
721 esize = 1;
723 else if (*pFormat == RPC_FC_C_WSTRING) {
724 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
725 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
726 esize = 2;
728 else {
729 ERR("Unhandled string type: %#x\n", *pFormat);
730 /* FIXME: raise an exception. */
731 return NULL;
734 if (pFormat[1] == RPC_FC_STRING_SIZED)
735 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
736 else
737 pStubMsg->MaxCount = pStubMsg->ActualCount;
738 pStubMsg->Offset = 0;
739 WriteConformance(pStubMsg);
740 WriteVariance(pStubMsg);
742 size = safe_multiply(esize, pStubMsg->ActualCount);
743 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
745 /* success */
746 return NULL; /* is this always right? */
749 /***********************************************************************
750 * NdrConformantStringBufferSize [RPCRT4.@]
752 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
753 unsigned char* pMemory, PFORMAT_STRING pFormat)
755 ULONG esize;
757 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
759 SizeConformance(pStubMsg);
760 SizeVariance(pStubMsg);
762 if (*pFormat == RPC_FC_C_CSTRING) {
763 TRACE("string=%s\n", debugstr_a((char*)pMemory));
764 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
765 esize = 1;
767 else if (*pFormat == RPC_FC_C_WSTRING) {
768 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
769 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
770 esize = 2;
772 else {
773 ERR("Unhandled string type: %#x\n", *pFormat);
774 /* FIXME: raise an exception */
775 return;
778 if (pFormat[1] == RPC_FC_STRING_SIZED)
779 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
780 else
781 pStubMsg->MaxCount = pStubMsg->ActualCount;
783 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
786 /************************************************************************
787 * NdrConformantStringMemorySize [RPCRT4.@]
789 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
790 PFORMAT_STRING pFormat )
792 ULONG bufsize, memsize, esize, i;
794 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
796 ReadConformance(pStubMsg, NULL);
797 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
799 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
801 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
802 pStubMsg->ActualCount, pStubMsg->MaxCount);
803 RpcRaiseException(RPC_S_INVALID_BOUND);
805 if (pStubMsg->Offset)
807 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
808 RpcRaiseException(RPC_S_INVALID_BOUND);
811 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
812 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
813 else {
814 ERR("Unhandled string type: %#x\n", *pFormat);
815 /* FIXME: raise an exception */
816 esize = 0;
819 memsize = safe_multiply(esize, pStubMsg->MaxCount);
820 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
822 /* strings must always have null terminating bytes */
823 if (bufsize < esize)
825 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
826 RpcRaiseException(RPC_S_INVALID_BOUND);
829 /* verify the buffer is safe to access */
830 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
831 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
833 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
834 pStubMsg->BufferEnd, pStubMsg->Buffer);
835 RpcRaiseException(RPC_X_BAD_STUB_DATA);
838 for (i = bufsize - esize; i < bufsize; i++)
839 if (pStubMsg->Buffer[i] != 0)
841 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
842 i, pStubMsg->Buffer[i]);
843 RpcRaiseException(RPC_S_INVALID_BOUND);
846 safe_buffer_increment(pStubMsg, bufsize);
847 pStubMsg->MemorySize += memsize;
849 return pStubMsg->MemorySize;
852 /************************************************************************
853 * NdrConformantStringUnmarshall [RPCRT4.@]
855 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
856 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
858 ULONG bufsize, memsize, esize, i;
860 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
861 pStubMsg, *ppMemory, pFormat, fMustAlloc);
863 assert(pFormat && ppMemory && pStubMsg);
865 ReadConformance(pStubMsg, NULL);
866 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
868 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
870 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
871 pStubMsg->ActualCount, pStubMsg->MaxCount);
872 RpcRaiseException(RPC_S_INVALID_BOUND);
873 return NULL;
875 if (pStubMsg->Offset)
877 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
878 RpcRaiseException(RPC_S_INVALID_BOUND);
879 return NULL;
882 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
883 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
884 else {
885 ERR("Unhandled string type: %#x\n", *pFormat);
886 /* FIXME: raise an exception */
887 esize = 0;
890 memsize = safe_multiply(esize, pStubMsg->MaxCount);
891 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
893 /* strings must always have null terminating bytes */
894 if (bufsize < esize)
896 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
897 RpcRaiseException(RPC_S_INVALID_BOUND);
898 return NULL;
901 /* verify the buffer is safe to access */
902 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
903 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
905 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
906 pStubMsg->BufferEnd, pStubMsg->Buffer);
907 RpcRaiseException(RPC_X_BAD_STUB_DATA);
908 return NULL;
911 for (i = bufsize - esize; i < bufsize; i++)
912 if (pStubMsg->Buffer[i] != 0)
914 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
915 i, pStubMsg->Buffer[i]);
916 RpcRaiseException(RPC_S_INVALID_BOUND);
917 return NULL;
920 if (fMustAlloc)
921 *ppMemory = NdrAllocate(pStubMsg, memsize);
922 else
924 if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
925 /* if the data in the RPC buffer is big enough, we just point straight
926 * into it */
927 *ppMemory = pStubMsg->Buffer;
928 else if (!*ppMemory)
929 *ppMemory = NdrAllocate(pStubMsg, memsize);
932 if (*ppMemory == pStubMsg->Buffer)
933 safe_buffer_increment(pStubMsg, bufsize);
934 else
935 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
937 if (*pFormat == RPC_FC_C_CSTRING) {
938 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
940 else if (*pFormat == RPC_FC_C_WSTRING) {
941 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
944 return NULL; /* FIXME: is this always right? */
947 /***********************************************************************
948 * NdrNonConformantStringMarshall [RPCRT4.@]
950 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
951 unsigned char *pMemory,
952 PFORMAT_STRING pFormat)
954 ULONG esize, size, maxsize;
956 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
958 maxsize = *(USHORT *)&pFormat[2];
960 if (*pFormat == RPC_FC_CSTRING)
962 ULONG i;
963 const char *str = (const char *)pMemory;
964 for (i = 0; i < maxsize && *str; i++, str++)
966 TRACE("string=%s\n", debugstr_an(str, i));
967 pStubMsg->ActualCount = i + 1;
968 esize = 1;
970 else if (*pFormat == RPC_FC_WSTRING)
972 ULONG i;
973 const WCHAR *str = (const WCHAR *)pMemory;
974 for (i = 0; i < maxsize && *str; i++, str++)
976 TRACE("string=%s\n", debugstr_wn(str, i));
977 pStubMsg->ActualCount = i + 1;
978 esize = 2;
980 else
982 ERR("Unhandled string type: %#x\n", *pFormat);
983 RpcRaiseException(RPC_X_BAD_STUB_DATA);
986 pStubMsg->Offset = 0;
987 WriteVariance(pStubMsg);
989 size = safe_multiply(esize, pStubMsg->ActualCount);
990 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
992 return NULL;
995 /***********************************************************************
996 * NdrNonConformantStringUnmarshall [RPCRT4.@]
998 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
999 unsigned char **ppMemory,
1000 PFORMAT_STRING pFormat,
1001 unsigned char fMustAlloc)
1003 ULONG bufsize, memsize, esize, i, maxsize;
1005 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
1006 pStubMsg, *ppMemory, pFormat, fMustAlloc);
1008 maxsize = *(USHORT *)&pFormat[2];
1010 ReadVariance(pStubMsg, NULL, maxsize);
1011 if (pStubMsg->Offset)
1013 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1014 RpcRaiseException(RPC_S_INVALID_BOUND);
1017 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1018 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1019 else
1021 ERR("Unhandled string type: %#x\n", *pFormat);
1022 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1025 memsize = esize * maxsize;
1026 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1028 if (bufsize < esize)
1030 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
1031 RpcRaiseException(RPC_S_INVALID_BOUND);
1032 return NULL;
1035 /* verify the buffer is safe to access */
1036 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
1037 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
1039 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
1040 pStubMsg->BufferEnd, pStubMsg->Buffer);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1042 return NULL;
1045 /* strings must always have null terminating bytes */
1046 for (i = bufsize - esize; i < bufsize; i++)
1047 if (pStubMsg->Buffer[i] != 0)
1049 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1050 i, pStubMsg->Buffer[i]);
1051 RpcRaiseException(RPC_S_INVALID_BOUND);
1054 if (fMustAlloc || !*ppMemory)
1055 *ppMemory = NdrAllocate(pStubMsg, memsize);
1057 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
1059 if (*pFormat == RPC_FC_CSTRING) {
1060 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
1062 else if (*pFormat == RPC_FC_WSTRING) {
1063 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
1066 return NULL;
1069 /***********************************************************************
1070 * NdrNonConformantStringBufferSize [RPCRT4.@]
1072 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1073 unsigned char *pMemory,
1074 PFORMAT_STRING pFormat)
1076 ULONG esize, maxsize;
1078 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
1080 maxsize = *(USHORT *)&pFormat[2];
1082 SizeVariance(pStubMsg);
1084 if (*pFormat == RPC_FC_CSTRING)
1086 ULONG i;
1087 const char *str = (const char *)pMemory;
1088 for (i = 0; i < maxsize && *str; i++, str++)
1090 TRACE("string=%s\n", debugstr_an(str, i));
1091 pStubMsg->ActualCount = i + 1;
1092 esize = 1;
1094 else if (*pFormat == RPC_FC_WSTRING)
1096 ULONG i;
1097 const WCHAR *str = (const WCHAR *)pMemory;
1098 for (i = 0; i < maxsize && *str; i++, str++)
1100 TRACE("string=%s\n", debugstr_wn(str, i));
1101 pStubMsg->ActualCount = i + 1;
1102 esize = 2;
1104 else
1106 ERR("Unhandled string type: %#x\n", *pFormat);
1107 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1110 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
1113 /***********************************************************************
1114 * NdrNonConformantStringMemorySize [RPCRT4.@]
1116 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1117 PFORMAT_STRING pFormat)
1119 ULONG bufsize, memsize, esize, i, maxsize;
1121 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
1123 maxsize = *(USHORT *)&pFormat[2];
1125 ReadVariance(pStubMsg, NULL, maxsize);
1127 if (pStubMsg->Offset)
1129 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1130 RpcRaiseException(RPC_S_INVALID_BOUND);
1133 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1134 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1135 else
1137 ERR("Unhandled string type: %#x\n", *pFormat);
1138 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1141 memsize = esize * maxsize;
1142 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1144 /* strings must always have null terminating bytes */
1145 if (bufsize < esize)
1147 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
1148 RpcRaiseException(RPC_S_INVALID_BOUND);
1151 /* verify the buffer is safe to access */
1152 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
1153 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
1155 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
1156 pStubMsg->BufferEnd, pStubMsg->Buffer);
1157 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1160 for (i = bufsize - esize; i < bufsize; i++)
1161 if (pStubMsg->Buffer[i] != 0)
1163 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1164 i, pStubMsg->Buffer[i]);
1165 RpcRaiseException(RPC_S_INVALID_BOUND);
1168 safe_buffer_increment(pStubMsg, bufsize);
1169 pStubMsg->MemorySize += memsize;
1171 return pStubMsg->MemorySize;
1174 static inline void dump_pointer_attr(unsigned char attr)
1176 if (attr & RPC_FC_P_ALLOCALLNODES)
1177 TRACE(" RPC_FC_P_ALLOCALLNODES");
1178 if (attr & RPC_FC_P_DONTFREE)
1179 TRACE(" RPC_FC_P_DONTFREE");
1180 if (attr & RPC_FC_P_ONSTACK)
1181 TRACE(" RPC_FC_P_ONSTACK");
1182 if (attr & RPC_FC_P_SIMPLEPOINTER)
1183 TRACE(" RPC_FC_P_SIMPLEPOINTER");
1184 if (attr & RPC_FC_P_DEREF)
1185 TRACE(" RPC_FC_P_DEREF");
1186 TRACE("\n");
1189 /***********************************************************************
1190 * PointerMarshall [internal]
1192 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1193 unsigned char *Buffer,
1194 unsigned char *Pointer,
1195 PFORMAT_STRING pFormat)
1197 unsigned type = pFormat[0], attr = pFormat[1];
1198 PFORMAT_STRING desc;
1199 NDR_MARSHALL m;
1200 ULONG pointer_id;
1201 int pointer_needs_marshaling;
1203 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
1204 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1205 pFormat += 2;
1206 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1207 else desc = pFormat + *(const SHORT*)pFormat;
1209 switch (type) {
1210 case RPC_FC_RP: /* ref pointer (always non-null) */
1211 if (!Pointer)
1213 ERR("NULL ref pointer is not allowed\n");
1214 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1216 pointer_needs_marshaling = 1;
1217 break;
1218 case RPC_FC_UP: /* unique pointer */
1219 case RPC_FC_OP: /* object pointer - same as unique here */
1220 if (Pointer)
1221 pointer_needs_marshaling = 1;
1222 else
1223 pointer_needs_marshaling = 0;
1224 pointer_id = (ULONG)Pointer;
1225 TRACE("writing 0x%08x to buffer\n", pointer_id);
1226 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1227 break;
1228 case RPC_FC_FP:
1229 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
1230 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
1231 TRACE("writing 0x%08x to buffer\n", pointer_id);
1232 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1233 break;
1234 default:
1235 FIXME("unhandled ptr type=%02x\n", type);
1236 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1237 return;
1240 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
1242 if (pointer_needs_marshaling) {
1243 if (attr & RPC_FC_P_DEREF) {
1244 Pointer = *(unsigned char**)Pointer;
1245 TRACE("deref => %p\n", Pointer);
1247 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1248 if (m) m(pStubMsg, Pointer, desc);
1249 else FIXME("no marshaller for data type=%02x\n", *desc);
1252 STD_OVERFLOW_CHECK(pStubMsg);
1255 /***********************************************************************
1256 * PointerUnmarshall [internal]
1258 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1259 unsigned char *Buffer,
1260 unsigned char **pPointer,
1261 unsigned char *pSrcPointer,
1262 PFORMAT_STRING pFormat,
1263 unsigned char fMustAlloc)
1265 unsigned type = pFormat[0], attr = pFormat[1];
1266 PFORMAT_STRING desc;
1267 NDR_UNMARSHALL m;
1268 DWORD pointer_id = 0;
1269 int pointer_needs_unmarshaling;
1271 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
1272 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1273 pFormat += 2;
1274 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1275 else desc = pFormat + *(const SHORT*)pFormat;
1277 switch (type) {
1278 case RPC_FC_RP: /* ref pointer (always non-null) */
1279 pointer_needs_unmarshaling = 1;
1280 break;
1281 case RPC_FC_UP: /* unique pointer */
1282 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1283 TRACE("pointer_id is 0x%08x\n", pointer_id);
1284 if (pointer_id)
1285 pointer_needs_unmarshaling = 1;
1286 else {
1287 *pPointer = NULL;
1288 pointer_needs_unmarshaling = 0;
1290 break;
1291 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1292 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1293 TRACE("pointer_id is 0x%08x\n", pointer_id);
1294 if (!fMustAlloc && pSrcPointer)
1296 FIXME("free object pointer %p\n", pSrcPointer);
1297 fMustAlloc = TRUE;
1299 if (pointer_id)
1300 pointer_needs_unmarshaling = 1;
1301 else
1302 pointer_needs_unmarshaling = 0;
1303 break;
1304 case RPC_FC_FP:
1305 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1306 TRACE("pointer_id is 0x%08x\n", pointer_id);
1307 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1308 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1309 break;
1310 default:
1311 FIXME("unhandled ptr type=%02x\n", type);
1312 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1313 return;
1316 if (pointer_needs_unmarshaling) {
1317 unsigned char *base_ptr_val = *pPointer;
1318 unsigned char **current_ptr = pPointer;
1319 if (pStubMsg->IsClient) {
1320 TRACE("client\n");
1321 /* if we aren't forcing allocation of memory then try to use the existing
1322 * (source) pointer to unmarshall the data into so that [in,out]
1323 * parameters behave correctly. it doesn't matter if the parameter is
1324 * [out] only since in that case the pointer will be NULL. we force
1325 * allocation when the source pointer is NULL here instead of in the type
1326 * unmarshalling routine for the benefit of the deref code below */
1327 if (!fMustAlloc) {
1328 if (pSrcPointer) {
1329 TRACE("setting *pPointer to %p\n", pSrcPointer);
1330 *pPointer = base_ptr_val = pSrcPointer;
1331 } else
1332 fMustAlloc = TRUE;
1334 } else {
1335 TRACE("server\n");
1336 /* the memory in a stub is never initialised, so we have to work out here
1337 * whether we have to initialise it so we can use the optimisation of
1338 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1339 * TRUE. */
1340 if (attr & RPC_FC_P_DEREF) {
1341 fMustAlloc = TRUE;
1342 } else {
1343 base_ptr_val = NULL;
1344 *current_ptr = NULL;
1348 if (attr & RPC_FC_P_ALLOCALLNODES)
1349 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1351 if (attr & RPC_FC_P_DEREF) {
1352 if (fMustAlloc) {
1353 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1354 *pPointer = base_ptr_val;
1355 current_ptr = (unsigned char **)base_ptr_val;
1356 } else
1357 current_ptr = *(unsigned char***)current_ptr;
1358 TRACE("deref => %p\n", current_ptr);
1359 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1361 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1362 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1363 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1365 if (type == RPC_FC_FP)
1366 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1367 base_ptr_val);
1370 TRACE("pointer=%p\n", *pPointer);
1373 /***********************************************************************
1374 * PointerBufferSize [internal]
1376 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1377 unsigned char *Pointer,
1378 PFORMAT_STRING pFormat)
1380 unsigned type = pFormat[0], attr = pFormat[1];
1381 PFORMAT_STRING desc;
1382 NDR_BUFFERSIZE m;
1383 int pointer_needs_sizing;
1384 ULONG pointer_id;
1386 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1387 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1388 pFormat += 2;
1389 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1390 else desc = pFormat + *(const SHORT*)pFormat;
1392 switch (type) {
1393 case RPC_FC_RP: /* ref pointer (always non-null) */
1394 if (!Pointer)
1396 ERR("NULL ref pointer is not allowed\n");
1397 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1399 break;
1400 case RPC_FC_OP:
1401 case RPC_FC_UP:
1402 /* NULL pointer has no further representation */
1403 if (!Pointer)
1404 return;
1405 break;
1406 case RPC_FC_FP:
1407 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1408 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1409 if (!pointer_needs_sizing)
1410 return;
1411 break;
1412 default:
1413 FIXME("unhandled ptr type=%02x\n", type);
1414 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1415 return;
1418 if (attr & RPC_FC_P_DEREF) {
1419 Pointer = *(unsigned char**)Pointer;
1420 TRACE("deref => %p\n", Pointer);
1423 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1424 if (m) m(pStubMsg, Pointer, desc);
1425 else FIXME("no buffersizer for data type=%02x\n", *desc);
1428 /***********************************************************************
1429 * PointerMemorySize [internal]
1431 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1432 unsigned char *Buffer,
1433 PFORMAT_STRING pFormat)
1435 unsigned type = pFormat[0], attr = pFormat[1];
1436 PFORMAT_STRING desc;
1437 NDR_MEMORYSIZE m;
1438 DWORD pointer_id = 0;
1439 int pointer_needs_sizing;
1441 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1442 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1443 pFormat += 2;
1444 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1445 else desc = pFormat + *(const SHORT*)pFormat;
1447 switch (type) {
1448 case RPC_FC_RP: /* ref pointer (always non-null) */
1449 pointer_needs_sizing = 1;
1450 break;
1451 case RPC_FC_UP: /* unique pointer */
1452 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1453 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1454 TRACE("pointer_id is 0x%08x\n", pointer_id);
1455 if (pointer_id)
1456 pointer_needs_sizing = 1;
1457 else
1458 pointer_needs_sizing = 0;
1459 break;
1460 case RPC_FC_FP:
1462 void *pointer;
1463 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1464 TRACE("pointer_id is 0x%08x\n", pointer_id);
1465 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1466 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1467 break;
1469 default:
1470 FIXME("unhandled ptr type=%02x\n", type);
1471 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1472 return 0;
1475 if (attr & RPC_FC_P_DEREF) {
1476 TRACE("deref\n");
1479 if (pointer_needs_sizing) {
1480 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1481 if (m) m(pStubMsg, desc);
1482 else FIXME("no memorysizer for data type=%02x\n", *desc);
1485 return pStubMsg->MemorySize;
1488 /***********************************************************************
1489 * PointerFree [internal]
1491 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1492 unsigned char *Pointer,
1493 PFORMAT_STRING pFormat)
1495 unsigned type = pFormat[0], attr = pFormat[1];
1496 PFORMAT_STRING desc;
1497 NDR_FREE m;
1498 unsigned char *current_pointer = Pointer;
1500 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1501 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1502 if (attr & RPC_FC_P_DONTFREE) return;
1503 pFormat += 2;
1504 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1505 else desc = pFormat + *(const SHORT*)pFormat;
1507 if (!Pointer) return;
1509 if (type == RPC_FC_FP) {
1510 int pointer_needs_freeing = NdrFullPointerFree(
1511 pStubMsg->FullPtrXlatTables, Pointer);
1512 if (!pointer_needs_freeing)
1513 return;
1516 if (attr & RPC_FC_P_DEREF) {
1517 current_pointer = *(unsigned char**)Pointer;
1518 TRACE("deref => %p\n", current_pointer);
1521 m = NdrFreer[*desc & NDR_TABLE_MASK];
1522 if (m) m(pStubMsg, current_pointer, desc);
1524 /* this check stops us from trying to free buffer memory. we don't have to
1525 * worry about clients, since they won't call this function.
1526 * we don't have to check for the buffer being reallocated because
1527 * BufferStart and BufferEnd won't be reset when allocating memory for
1528 * sending the response. we don't have to check for the new buffer here as
1529 * it won't be used a type memory, only for buffer memory */
1530 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1531 goto notfree;
1533 if (attr & RPC_FC_P_ONSTACK) {
1534 TRACE("not freeing stack ptr %p\n", Pointer);
1535 return;
1537 TRACE("freeing %p\n", Pointer);
1538 NdrFree(pStubMsg, Pointer);
1539 return;
1540 notfree:
1541 TRACE("not freeing %p\n", Pointer);
1544 /***********************************************************************
1545 * EmbeddedPointerMarshall
1547 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1548 unsigned char *pMemory,
1549 PFORMAT_STRING pFormat)
1551 unsigned char *Mark = pStubMsg->BufferMark;
1552 unsigned rep, count, stride;
1553 unsigned i;
1554 unsigned char *saved_buffer = NULL;
1556 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1558 if (*pFormat != RPC_FC_PP) return NULL;
1559 pFormat += 2;
1561 if (pStubMsg->PointerBufferMark)
1563 saved_buffer = pStubMsg->Buffer;
1564 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1565 pStubMsg->PointerBufferMark = NULL;
1568 while (pFormat[0] != RPC_FC_END) {
1569 switch (pFormat[0]) {
1570 default:
1571 FIXME("unknown repeat type %d\n", pFormat[0]);
1572 case RPC_FC_NO_REPEAT:
1573 rep = 1;
1574 stride = 0;
1575 count = 1;
1576 pFormat += 2;
1577 break;
1578 case RPC_FC_FIXED_REPEAT:
1579 rep = *(const WORD*)&pFormat[2];
1580 stride = *(const WORD*)&pFormat[4];
1581 count = *(const WORD*)&pFormat[8];
1582 pFormat += 10;
1583 break;
1584 case RPC_FC_VARIABLE_REPEAT:
1585 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1586 stride = *(const WORD*)&pFormat[2];
1587 count = *(const WORD*)&pFormat[6];
1588 pFormat += 8;
1589 break;
1591 for (i = 0; i < rep; i++) {
1592 PFORMAT_STRING info = pFormat;
1593 unsigned char *membase = pMemory + (i * stride);
1594 unsigned char *bufbase = Mark + (i * stride);
1595 unsigned u;
1597 for (u=0; u<count; u++,info+=8) {
1598 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1599 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1600 unsigned char *saved_memory = pStubMsg->Memory;
1602 pStubMsg->Memory = pMemory;
1603 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1604 pStubMsg->Memory = saved_memory;
1607 pFormat += 8 * count;
1610 if (saved_buffer)
1612 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1613 pStubMsg->Buffer = saved_buffer;
1616 STD_OVERFLOW_CHECK(pStubMsg);
1618 return NULL;
1621 /***********************************************************************
1622 * EmbeddedPointerUnmarshall
1624 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1625 unsigned char *pDstMemoryPtrs,
1626 unsigned char *pSrcMemoryPtrs,
1627 PFORMAT_STRING pFormat,
1628 unsigned char fMustAlloc)
1630 unsigned char *Mark = pStubMsg->BufferMark;
1631 unsigned rep, count, stride;
1632 unsigned i;
1633 unsigned char *saved_buffer = NULL;
1635 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1637 if (*pFormat != RPC_FC_PP) return NULL;
1638 pFormat += 2;
1640 if (pStubMsg->PointerBufferMark)
1642 saved_buffer = pStubMsg->Buffer;
1643 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1644 pStubMsg->PointerBufferMark = NULL;
1647 while (pFormat[0] != RPC_FC_END) {
1648 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1649 switch (pFormat[0]) {
1650 default:
1651 FIXME("unknown repeat type %d\n", pFormat[0]);
1652 case RPC_FC_NO_REPEAT:
1653 rep = 1;
1654 stride = 0;
1655 count = 1;
1656 pFormat += 2;
1657 break;
1658 case RPC_FC_FIXED_REPEAT:
1659 rep = *(const WORD*)&pFormat[2];
1660 stride = *(const WORD*)&pFormat[4];
1661 count = *(const WORD*)&pFormat[8];
1662 pFormat += 10;
1663 break;
1664 case RPC_FC_VARIABLE_REPEAT:
1665 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1666 stride = *(const WORD*)&pFormat[2];
1667 count = *(const WORD*)&pFormat[6];
1668 pFormat += 8;
1669 break;
1671 for (i = 0; i < rep; i++) {
1672 PFORMAT_STRING info = pFormat;
1673 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1674 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1675 unsigned char *bufbase = Mark + (i * stride);
1676 unsigned u;
1678 for (u=0; u<count; u++,info+=8) {
1679 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1680 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1681 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1682 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1685 pFormat += 8 * count;
1688 if (saved_buffer)
1690 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1691 pStubMsg->Buffer = saved_buffer;
1694 return NULL;
1697 /***********************************************************************
1698 * EmbeddedPointerBufferSize
1700 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1701 unsigned char *pMemory,
1702 PFORMAT_STRING pFormat)
1704 unsigned rep, count, stride;
1705 unsigned i;
1706 ULONG saved_buffer_length = 0;
1708 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1710 if (pStubMsg->IgnoreEmbeddedPointers) return;
1712 if (*pFormat != RPC_FC_PP) return;
1713 pFormat += 2;
1715 if (pStubMsg->PointerLength)
1717 saved_buffer_length = pStubMsg->BufferLength;
1718 pStubMsg->BufferLength = pStubMsg->PointerLength;
1719 pStubMsg->PointerLength = 0;
1722 while (pFormat[0] != RPC_FC_END) {
1723 switch (pFormat[0]) {
1724 default:
1725 FIXME("unknown repeat type %d\n", pFormat[0]);
1726 case RPC_FC_NO_REPEAT:
1727 rep = 1;
1728 stride = 0;
1729 count = 1;
1730 pFormat += 2;
1731 break;
1732 case RPC_FC_FIXED_REPEAT:
1733 rep = *(const WORD*)&pFormat[2];
1734 stride = *(const WORD*)&pFormat[4];
1735 count = *(const WORD*)&pFormat[8];
1736 pFormat += 10;
1737 break;
1738 case RPC_FC_VARIABLE_REPEAT:
1739 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1740 stride = *(const WORD*)&pFormat[2];
1741 count = *(const WORD*)&pFormat[6];
1742 pFormat += 8;
1743 break;
1745 for (i = 0; i < rep; i++) {
1746 PFORMAT_STRING info = pFormat;
1747 unsigned char *membase = pMemory + (i * stride);
1748 unsigned u;
1750 for (u=0; u<count; u++,info+=8) {
1751 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1752 unsigned char *saved_memory = pStubMsg->Memory;
1754 pStubMsg->Memory = pMemory;
1755 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1756 pStubMsg->Memory = saved_memory;
1759 pFormat += 8 * count;
1762 if (saved_buffer_length)
1764 pStubMsg->PointerLength = pStubMsg->BufferLength;
1765 pStubMsg->BufferLength = saved_buffer_length;
1769 /***********************************************************************
1770 * EmbeddedPointerMemorySize [internal]
1772 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1773 PFORMAT_STRING pFormat)
1775 unsigned char *Mark = pStubMsg->BufferMark;
1776 unsigned rep, count, stride;
1777 unsigned i;
1778 unsigned char *saved_buffer = NULL;
1780 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1782 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1784 if (pStubMsg->PointerBufferMark)
1786 saved_buffer = pStubMsg->Buffer;
1787 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1788 pStubMsg->PointerBufferMark = NULL;
1791 if (*pFormat != RPC_FC_PP) return 0;
1792 pFormat += 2;
1794 while (pFormat[0] != RPC_FC_END) {
1795 switch (pFormat[0]) {
1796 default:
1797 FIXME("unknown repeat type %d\n", pFormat[0]);
1798 case RPC_FC_NO_REPEAT:
1799 rep = 1;
1800 stride = 0;
1801 count = 1;
1802 pFormat += 2;
1803 break;
1804 case RPC_FC_FIXED_REPEAT:
1805 rep = *(const WORD*)&pFormat[2];
1806 stride = *(const WORD*)&pFormat[4];
1807 count = *(const WORD*)&pFormat[8];
1808 pFormat += 10;
1809 break;
1810 case RPC_FC_VARIABLE_REPEAT:
1811 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1812 stride = *(const WORD*)&pFormat[2];
1813 count = *(const WORD*)&pFormat[6];
1814 pFormat += 8;
1815 break;
1817 for (i = 0; i < rep; i++) {
1818 PFORMAT_STRING info = pFormat;
1819 unsigned char *bufbase = Mark + (i * stride);
1820 unsigned u;
1821 for (u=0; u<count; u++,info+=8) {
1822 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1823 PointerMemorySize(pStubMsg, bufptr, info+4);
1826 pFormat += 8 * count;
1829 if (saved_buffer)
1831 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1832 pStubMsg->Buffer = saved_buffer;
1835 return 0;
1838 /***********************************************************************
1839 * EmbeddedPointerFree [internal]
1841 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1842 unsigned char *pMemory,
1843 PFORMAT_STRING pFormat)
1845 unsigned rep, count, stride;
1846 unsigned i;
1848 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1849 if (*pFormat != RPC_FC_PP) return;
1850 pFormat += 2;
1852 while (pFormat[0] != RPC_FC_END) {
1853 switch (pFormat[0]) {
1854 default:
1855 FIXME("unknown repeat type %d\n", pFormat[0]);
1856 case RPC_FC_NO_REPEAT:
1857 rep = 1;
1858 stride = 0;
1859 count = 1;
1860 pFormat += 2;
1861 break;
1862 case RPC_FC_FIXED_REPEAT:
1863 rep = *(const WORD*)&pFormat[2];
1864 stride = *(const WORD*)&pFormat[4];
1865 count = *(const WORD*)&pFormat[8];
1866 pFormat += 10;
1867 break;
1868 case RPC_FC_VARIABLE_REPEAT:
1869 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1870 stride = *(const WORD*)&pFormat[2];
1871 count = *(const WORD*)&pFormat[6];
1872 pFormat += 8;
1873 break;
1875 for (i = 0; i < rep; i++) {
1876 PFORMAT_STRING info = pFormat;
1877 unsigned char *membase = pMemory + (i * stride);
1878 unsigned u;
1880 for (u=0; u<count; u++,info+=8) {
1881 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1882 unsigned char *saved_memory = pStubMsg->Memory;
1884 pStubMsg->Memory = pMemory;
1885 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1886 pStubMsg->Memory = saved_memory;
1889 pFormat += 8 * count;
1893 /***********************************************************************
1894 * NdrPointerMarshall [RPCRT4.@]
1896 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1897 unsigned char *pMemory,
1898 PFORMAT_STRING pFormat)
1900 unsigned char *Buffer;
1902 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1904 /* Increment the buffer here instead of in PointerMarshall,
1905 * as that is used by embedded pointers which already handle the incrementing
1906 * the buffer, and shouldn't write any additional pointer data to the wire */
1907 if (*pFormat != RPC_FC_RP)
1909 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1910 Buffer = pStubMsg->Buffer;
1911 safe_buffer_increment(pStubMsg, 4);
1913 else
1914 Buffer = pStubMsg->Buffer;
1916 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1918 return NULL;
1921 /***********************************************************************
1922 * NdrPointerUnmarshall [RPCRT4.@]
1924 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1925 unsigned char **ppMemory,
1926 PFORMAT_STRING pFormat,
1927 unsigned char fMustAlloc)
1929 unsigned char *Buffer;
1931 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1933 /* incremement the buffer here instead of in PointerUnmarshall,
1934 * as that is used by embedded pointers which already handle the incrementing
1935 * the buffer, and shouldn't read any additional pointer data from the
1936 * buffer */
1937 if (*pFormat != RPC_FC_RP)
1939 ALIGN_POINTER(pStubMsg->Buffer, 4);
1940 Buffer = pStubMsg->Buffer;
1941 safe_buffer_increment(pStubMsg, 4);
1943 else
1944 Buffer = pStubMsg->Buffer;
1946 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1948 return NULL;
1951 /***********************************************************************
1952 * NdrPointerBufferSize [RPCRT4.@]
1954 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1955 unsigned char *pMemory,
1956 PFORMAT_STRING pFormat)
1958 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1960 /* incremement the buffer length here instead of in PointerBufferSize,
1961 * as that is used by embedded pointers which already handle the buffer
1962 * length, and shouldn't write anything more to the wire */
1963 if (*pFormat != RPC_FC_RP)
1965 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1966 safe_buffer_length_increment(pStubMsg, 4);
1969 PointerBufferSize(pStubMsg, pMemory, pFormat);
1972 /***********************************************************************
1973 * NdrPointerMemorySize [RPCRT4.@]
1975 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1976 PFORMAT_STRING pFormat)
1978 /* unsigned size = *(LPWORD)(pFormat+2); */
1979 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1980 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1981 return 0;
1984 /***********************************************************************
1985 * NdrPointerFree [RPCRT4.@]
1987 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1988 unsigned char *pMemory,
1989 PFORMAT_STRING pFormat)
1991 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1992 PointerFree(pStubMsg, pMemory, pFormat);
1995 /***********************************************************************
1996 * NdrSimpleTypeMarshall [RPCRT4.@]
1998 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1999 unsigned char FormatChar )
2001 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
2004 /***********************************************************************
2005 * NdrSimpleTypeUnmarshall [RPCRT4.@]
2007 * Unmarshall a base type.
2009 * NOTES
2010 * Doesn't check that the buffer is long enough before copying, so the caller
2011 * should do this.
2013 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
2014 unsigned char FormatChar )
2016 #define BASE_TYPE_UNMARSHALL(type) \
2017 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
2018 TRACE("pMemory: %p\n", pMemory); \
2019 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
2020 pStubMsg->Buffer += sizeof(type);
2022 switch(FormatChar)
2024 case RPC_FC_BYTE:
2025 case RPC_FC_CHAR:
2026 case RPC_FC_SMALL:
2027 case RPC_FC_USMALL:
2028 BASE_TYPE_UNMARSHALL(UCHAR);
2029 TRACE("value: 0x%02x\n", *pMemory);
2030 break;
2031 case RPC_FC_WCHAR:
2032 case RPC_FC_SHORT:
2033 case RPC_FC_USHORT:
2034 BASE_TYPE_UNMARSHALL(USHORT);
2035 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
2036 break;
2037 case RPC_FC_LONG:
2038 case RPC_FC_ULONG:
2039 case RPC_FC_ERROR_STATUS_T:
2040 case RPC_FC_ENUM32:
2041 BASE_TYPE_UNMARSHALL(ULONG);
2042 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
2043 break;
2044 case RPC_FC_FLOAT:
2045 BASE_TYPE_UNMARSHALL(float);
2046 TRACE("value: %f\n", *(float *)pMemory);
2047 break;
2048 case RPC_FC_DOUBLE:
2049 BASE_TYPE_UNMARSHALL(double);
2050 TRACE("value: %f\n", *(double *)pMemory);
2051 break;
2052 case RPC_FC_HYPER:
2053 BASE_TYPE_UNMARSHALL(ULONGLONG);
2054 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
2055 break;
2056 case RPC_FC_ENUM16:
2057 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
2058 TRACE("pMemory: %p\n", pMemory);
2059 /* 16-bits on the wire, but int in memory */
2060 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
2061 pStubMsg->Buffer += sizeof(USHORT);
2062 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
2063 break;
2064 case RPC_FC_IGNORE:
2065 break;
2066 default:
2067 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
2069 #undef BASE_TYPE_UNMARSHALL
2072 /***********************************************************************
2073 * NdrSimpleStructMarshall [RPCRT4.@]
2075 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2076 unsigned char *pMemory,
2077 PFORMAT_STRING pFormat)
2079 unsigned size = *(const WORD*)(pFormat+2);
2080 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2082 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2084 pStubMsg->BufferMark = pStubMsg->Buffer;
2085 safe_copy_to_buffer(pStubMsg, pMemory, size);
2087 if (pFormat[0] != RPC_FC_STRUCT)
2088 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
2090 return NULL;
2093 /***********************************************************************
2094 * NdrSimpleStructUnmarshall [RPCRT4.@]
2096 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2097 unsigned char **ppMemory,
2098 PFORMAT_STRING pFormat,
2099 unsigned char fMustAlloc)
2101 unsigned size = *(const WORD*)(pFormat+2);
2102 unsigned char *saved_buffer;
2103 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2105 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2107 if (fMustAlloc)
2108 *ppMemory = NdrAllocate(pStubMsg, size);
2109 else
2111 if (!pStubMsg->IsClient && !*ppMemory)
2112 /* for servers, we just point straight into the RPC buffer */
2113 *ppMemory = pStubMsg->Buffer;
2116 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2117 safe_buffer_increment(pStubMsg, size);
2118 if (pFormat[0] == RPC_FC_PSTRUCT)
2119 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
2121 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2122 if (*ppMemory != saved_buffer)
2123 memcpy(*ppMemory, saved_buffer, size);
2125 return NULL;
2128 /***********************************************************************
2129 * NdrSimpleStructBufferSize [RPCRT4.@]
2131 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2132 unsigned char *pMemory,
2133 PFORMAT_STRING pFormat)
2135 unsigned size = *(const WORD*)(pFormat+2);
2136 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2138 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2140 safe_buffer_length_increment(pStubMsg, size);
2141 if (pFormat[0] != RPC_FC_STRUCT)
2142 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
2145 /***********************************************************************
2146 * NdrSimpleStructMemorySize [RPCRT4.@]
2148 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2149 PFORMAT_STRING pFormat)
2151 unsigned short size = *(const WORD *)(pFormat+2);
2153 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2155 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2156 pStubMsg->MemorySize += size;
2157 safe_buffer_increment(pStubMsg, size);
2159 if (pFormat[0] != RPC_FC_STRUCT)
2160 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
2161 return pStubMsg->MemorySize;
2164 /***********************************************************************
2165 * NdrSimpleStructFree [RPCRT4.@]
2167 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2168 unsigned char *pMemory,
2169 PFORMAT_STRING pFormat)
2171 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2172 if (pFormat[0] != RPC_FC_STRUCT)
2173 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
2177 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
2178 PFORMAT_STRING pFormat)
2180 switch (*pFormat) {
2181 case RPC_FC_STRUCT:
2182 case RPC_FC_PSTRUCT:
2183 case RPC_FC_CSTRUCT:
2184 case RPC_FC_BOGUS_STRUCT:
2185 case RPC_FC_SMFARRAY:
2186 case RPC_FC_SMVARRAY:
2187 case RPC_FC_CSTRING:
2188 return *(const WORD*)&pFormat[2];
2189 case RPC_FC_USER_MARSHAL:
2190 return *(const WORD*)&pFormat[4];
2191 case RPC_FC_NON_ENCAPSULATED_UNION:
2192 pFormat += 2;
2193 if (pStubMsg->fHasNewCorrDesc)
2194 pFormat += 6;
2195 else
2196 pFormat += 4;
2198 pFormat += *(const SHORT*)pFormat;
2199 return *(const SHORT*)pFormat;
2200 case RPC_FC_IP:
2201 return sizeof(void *);
2202 case RPC_FC_WSTRING:
2203 return *(const WORD*)&pFormat[2] * 2;
2204 default:
2205 FIXME("unhandled embedded type %02x\n", *pFormat);
2207 return 0;
2211 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2212 PFORMAT_STRING pFormat)
2214 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2216 if (!m)
2218 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2219 return 0;
2222 return m(pStubMsg, pFormat);
2226 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2227 unsigned char *pMemory,
2228 PFORMAT_STRING pFormat,
2229 PFORMAT_STRING pPointer)
2231 PFORMAT_STRING desc;
2232 NDR_MARSHALL m;
2233 unsigned long size;
2235 while (*pFormat != RPC_FC_END) {
2236 switch (*pFormat) {
2237 case RPC_FC_BYTE:
2238 case RPC_FC_CHAR:
2239 case RPC_FC_SMALL:
2240 case RPC_FC_USMALL:
2241 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2242 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2243 pMemory += 1;
2244 break;
2245 case RPC_FC_WCHAR:
2246 case RPC_FC_SHORT:
2247 case RPC_FC_USHORT:
2248 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2249 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2250 pMemory += 2;
2251 break;
2252 case RPC_FC_ENUM16:
2253 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2254 if (32767 < *(DWORD*)pMemory)
2255 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2256 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2257 pMemory += 4;
2258 break;
2259 case RPC_FC_LONG:
2260 case RPC_FC_ULONG:
2261 case RPC_FC_ENUM32:
2262 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2263 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2264 pMemory += 4;
2265 break;
2266 case RPC_FC_HYPER:
2267 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2268 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2269 pMemory += 8;
2270 break;
2271 case RPC_FC_POINTER:
2273 unsigned char *saved_buffer;
2274 int pointer_buffer_mark_set = 0;
2275 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2276 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2277 saved_buffer = pStubMsg->Buffer;
2278 if (pStubMsg->PointerBufferMark)
2280 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2281 pStubMsg->PointerBufferMark = NULL;
2282 pointer_buffer_mark_set = 1;
2284 else
2285 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2286 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2287 if (pointer_buffer_mark_set)
2289 STD_OVERFLOW_CHECK(pStubMsg);
2290 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2291 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2293 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2294 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2295 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2297 pStubMsg->Buffer = saved_buffer + 4;
2299 pPointer += 4;
2300 pMemory += 4;
2301 break;
2303 case RPC_FC_ALIGNM4:
2304 ALIGN_POINTER(pMemory, 4);
2305 break;
2306 case RPC_FC_ALIGNM8:
2307 ALIGN_POINTER(pMemory, 8);
2308 break;
2309 case RPC_FC_STRUCTPAD1:
2310 case RPC_FC_STRUCTPAD2:
2311 case RPC_FC_STRUCTPAD3:
2312 case RPC_FC_STRUCTPAD4:
2313 case RPC_FC_STRUCTPAD5:
2314 case RPC_FC_STRUCTPAD6:
2315 case RPC_FC_STRUCTPAD7:
2316 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2317 break;
2318 case RPC_FC_EMBEDDED_COMPLEX:
2319 pMemory += pFormat[1];
2320 pFormat += 2;
2321 desc = pFormat + *(const SHORT*)pFormat;
2322 size = EmbeddedComplexSize(pStubMsg, desc);
2323 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2324 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2325 if (m)
2327 /* for some reason interface pointers aren't generated as
2328 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2329 * they still need the derefencing treatment that pointers are
2330 * given */
2331 if (*desc == RPC_FC_IP)
2332 m(pStubMsg, *(unsigned char **)pMemory, desc);
2333 else
2334 m(pStubMsg, pMemory, desc);
2336 else FIXME("no marshaller for embedded type %02x\n", *desc);
2337 pMemory += size;
2338 pFormat += 2;
2339 continue;
2340 case RPC_FC_PAD:
2341 break;
2342 default:
2343 FIXME("unhandled format 0x%02x\n", *pFormat);
2345 pFormat++;
2348 return pMemory;
2351 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2352 unsigned char *pMemory,
2353 PFORMAT_STRING pFormat,
2354 PFORMAT_STRING pPointer)
2356 PFORMAT_STRING desc;
2357 NDR_UNMARSHALL m;
2358 unsigned long size;
2360 while (*pFormat != RPC_FC_END) {
2361 switch (*pFormat) {
2362 case RPC_FC_BYTE:
2363 case RPC_FC_CHAR:
2364 case RPC_FC_SMALL:
2365 case RPC_FC_USMALL:
2366 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2367 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2368 pMemory += 1;
2369 break;
2370 case RPC_FC_WCHAR:
2371 case RPC_FC_SHORT:
2372 case RPC_FC_USHORT:
2373 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2374 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2375 pMemory += 2;
2376 break;
2377 case RPC_FC_ENUM16:
2378 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2379 *(DWORD*)pMemory &= 0xffff;
2380 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2381 if (32767 < *(DWORD*)pMemory)
2382 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2383 pMemory += 4;
2384 break;
2385 case RPC_FC_LONG:
2386 case RPC_FC_ULONG:
2387 case RPC_FC_ENUM32:
2388 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2389 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2390 pMemory += 4;
2391 break;
2392 case RPC_FC_HYPER:
2393 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2394 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2395 pMemory += 8;
2396 break;
2397 case RPC_FC_POINTER:
2399 unsigned char *saved_buffer;
2400 int pointer_buffer_mark_set = 0;
2401 TRACE("pointer => %p\n", pMemory);
2402 ALIGN_POINTER(pStubMsg->Buffer, 4);
2403 saved_buffer = pStubMsg->Buffer;
2404 if (pStubMsg->PointerBufferMark)
2406 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2407 pStubMsg->PointerBufferMark = NULL;
2408 pointer_buffer_mark_set = 1;
2410 else
2411 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2413 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2414 if (pointer_buffer_mark_set)
2416 STD_OVERFLOW_CHECK(pStubMsg);
2417 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2418 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2420 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2421 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2422 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2424 pStubMsg->Buffer = saved_buffer + 4;
2426 pPointer += 4;
2427 pMemory += 4;
2428 break;
2430 case RPC_FC_ALIGNM4:
2431 ALIGN_POINTER_CLEAR(pMemory, 4);
2432 break;
2433 case RPC_FC_ALIGNM8:
2434 ALIGN_POINTER_CLEAR(pMemory, 8);
2435 break;
2436 case RPC_FC_STRUCTPAD1:
2437 case RPC_FC_STRUCTPAD2:
2438 case RPC_FC_STRUCTPAD3:
2439 case RPC_FC_STRUCTPAD4:
2440 case RPC_FC_STRUCTPAD5:
2441 case RPC_FC_STRUCTPAD6:
2442 case RPC_FC_STRUCTPAD7:
2443 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2444 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2445 break;
2446 case RPC_FC_EMBEDDED_COMPLEX:
2447 pMemory += pFormat[1];
2448 pFormat += 2;
2449 desc = pFormat + *(const SHORT*)pFormat;
2450 size = EmbeddedComplexSize(pStubMsg, desc);
2451 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2452 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2453 memset(pMemory, 0, size); /* just in case */
2454 if (m)
2456 /* for some reason interface pointers aren't generated as
2457 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2458 * they still need the derefencing treatment that pointers are
2459 * given */
2460 if (*desc == RPC_FC_IP)
2461 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2462 else
2463 m(pStubMsg, &pMemory, desc, FALSE);
2465 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2466 pMemory += size;
2467 pFormat += 2;
2468 continue;
2469 case RPC_FC_PAD:
2470 break;
2471 default:
2472 FIXME("unhandled format %d\n", *pFormat);
2474 pFormat++;
2477 return pMemory;
2480 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2481 unsigned char *pMemory,
2482 PFORMAT_STRING pFormat,
2483 PFORMAT_STRING pPointer)
2485 PFORMAT_STRING desc;
2486 NDR_BUFFERSIZE m;
2487 unsigned long size;
2489 while (*pFormat != RPC_FC_END) {
2490 switch (*pFormat) {
2491 case RPC_FC_BYTE:
2492 case RPC_FC_CHAR:
2493 case RPC_FC_SMALL:
2494 case RPC_FC_USMALL:
2495 safe_buffer_length_increment(pStubMsg, 1);
2496 pMemory += 1;
2497 break;
2498 case RPC_FC_WCHAR:
2499 case RPC_FC_SHORT:
2500 case RPC_FC_USHORT:
2501 safe_buffer_length_increment(pStubMsg, 2);
2502 pMemory += 2;
2503 break;
2504 case RPC_FC_ENUM16:
2505 safe_buffer_length_increment(pStubMsg, 2);
2506 pMemory += 4;
2507 break;
2508 case RPC_FC_LONG:
2509 case RPC_FC_ULONG:
2510 case RPC_FC_ENUM32:
2511 safe_buffer_length_increment(pStubMsg, 4);
2512 pMemory += 4;
2513 break;
2514 case RPC_FC_HYPER:
2515 safe_buffer_length_increment(pStubMsg, 8);
2516 pMemory += 8;
2517 break;
2518 case RPC_FC_POINTER:
2519 if (!pStubMsg->IgnoreEmbeddedPointers)
2521 int saved_buffer_length = pStubMsg->BufferLength;
2522 pStubMsg->BufferLength = pStubMsg->PointerLength;
2523 pStubMsg->PointerLength = 0;
2524 if(!pStubMsg->BufferLength)
2525 ERR("BufferLength == 0??\n");
2526 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2527 pStubMsg->PointerLength = pStubMsg->BufferLength;
2528 pStubMsg->BufferLength = saved_buffer_length;
2530 safe_buffer_length_increment(pStubMsg, 4);
2531 pPointer += 4;
2532 pMemory += 4;
2533 break;
2534 case RPC_FC_ALIGNM4:
2535 ALIGN_POINTER(pMemory, 4);
2536 break;
2537 case RPC_FC_ALIGNM8:
2538 ALIGN_POINTER(pMemory, 8);
2539 break;
2540 case RPC_FC_STRUCTPAD1:
2541 case RPC_FC_STRUCTPAD2:
2542 case RPC_FC_STRUCTPAD3:
2543 case RPC_FC_STRUCTPAD4:
2544 case RPC_FC_STRUCTPAD5:
2545 case RPC_FC_STRUCTPAD6:
2546 case RPC_FC_STRUCTPAD7:
2547 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2548 break;
2549 case RPC_FC_EMBEDDED_COMPLEX:
2550 pMemory += pFormat[1];
2551 pFormat += 2;
2552 desc = pFormat + *(const SHORT*)pFormat;
2553 size = EmbeddedComplexSize(pStubMsg, desc);
2554 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2555 if (m)
2557 /* for some reason interface pointers aren't generated as
2558 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2559 * they still need the derefencing treatment that pointers are
2560 * given */
2561 if (*desc == RPC_FC_IP)
2562 m(pStubMsg, *(unsigned char **)pMemory, desc);
2563 else
2564 m(pStubMsg, pMemory, desc);
2566 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2567 pMemory += size;
2568 pFormat += 2;
2569 continue;
2570 case RPC_FC_PAD:
2571 break;
2572 default:
2573 FIXME("unhandled format 0x%02x\n", *pFormat);
2575 pFormat++;
2578 return pMemory;
2581 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2582 unsigned char *pMemory,
2583 PFORMAT_STRING pFormat,
2584 PFORMAT_STRING pPointer)
2586 PFORMAT_STRING desc;
2587 NDR_FREE m;
2588 unsigned long size;
2590 while (*pFormat != RPC_FC_END) {
2591 switch (*pFormat) {
2592 case RPC_FC_BYTE:
2593 case RPC_FC_CHAR:
2594 case RPC_FC_SMALL:
2595 case RPC_FC_USMALL:
2596 pMemory += 1;
2597 break;
2598 case RPC_FC_WCHAR:
2599 case RPC_FC_SHORT:
2600 case RPC_FC_USHORT:
2601 pMemory += 2;
2602 break;
2603 case RPC_FC_LONG:
2604 case RPC_FC_ULONG:
2605 case RPC_FC_ENUM16:
2606 case RPC_FC_ENUM32:
2607 pMemory += 4;
2608 break;
2609 case RPC_FC_HYPER:
2610 pMemory += 8;
2611 break;
2612 case RPC_FC_POINTER:
2613 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2614 pPointer += 4;
2615 pMemory += 4;
2616 break;
2617 case RPC_FC_ALIGNM4:
2618 ALIGN_POINTER(pMemory, 4);
2619 break;
2620 case RPC_FC_ALIGNM8:
2621 ALIGN_POINTER(pMemory, 8);
2622 break;
2623 case RPC_FC_STRUCTPAD1:
2624 case RPC_FC_STRUCTPAD2:
2625 case RPC_FC_STRUCTPAD3:
2626 case RPC_FC_STRUCTPAD4:
2627 case RPC_FC_STRUCTPAD5:
2628 case RPC_FC_STRUCTPAD6:
2629 case RPC_FC_STRUCTPAD7:
2630 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2631 break;
2632 case RPC_FC_EMBEDDED_COMPLEX:
2633 pMemory += pFormat[1];
2634 pFormat += 2;
2635 desc = pFormat + *(const SHORT*)pFormat;
2636 size = EmbeddedComplexSize(pStubMsg, desc);
2637 m = NdrFreer[*desc & NDR_TABLE_MASK];
2638 if (m)
2640 /* for some reason interface pointers aren't generated as
2641 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2642 * they still need the derefencing treatment that pointers are
2643 * given */
2644 if (*desc == RPC_FC_IP)
2645 m(pStubMsg, *(unsigned char **)pMemory, desc);
2646 else
2647 m(pStubMsg, pMemory, desc);
2649 pMemory += size;
2650 pFormat += 2;
2651 continue;
2652 case RPC_FC_PAD:
2653 break;
2654 default:
2655 FIXME("unhandled format 0x%02x\n", *pFormat);
2657 pFormat++;
2660 return pMemory;
2663 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2664 PFORMAT_STRING pFormat)
2666 PFORMAT_STRING desc;
2667 unsigned long size = 0;
2669 while (*pFormat != RPC_FC_END) {
2670 switch (*pFormat) {
2671 case RPC_FC_BYTE:
2672 case RPC_FC_CHAR:
2673 case RPC_FC_SMALL:
2674 case RPC_FC_USMALL:
2675 size += 1;
2676 safe_buffer_increment(pStubMsg, 1);
2677 break;
2678 case RPC_FC_WCHAR:
2679 case RPC_FC_SHORT:
2680 case RPC_FC_USHORT:
2681 size += 2;
2682 safe_buffer_increment(pStubMsg, 2);
2683 break;
2684 case RPC_FC_ENUM16:
2685 size += 4;
2686 safe_buffer_increment(pStubMsg, 2);
2687 break;
2688 case RPC_FC_LONG:
2689 case RPC_FC_ULONG:
2690 case RPC_FC_ENUM32:
2691 size += 4;
2692 safe_buffer_increment(pStubMsg, 4);
2693 break;
2694 case RPC_FC_HYPER:
2695 size += 8;
2696 safe_buffer_increment(pStubMsg, 8);
2697 break;
2698 case RPC_FC_POINTER:
2699 size += 4;
2700 safe_buffer_increment(pStubMsg, 4);
2701 if (!pStubMsg->IgnoreEmbeddedPointers)
2702 FIXME("embedded pointers\n");
2703 break;
2704 case RPC_FC_ALIGNM4:
2705 ALIGN_LENGTH(size, 4);
2706 ALIGN_POINTER(pStubMsg->Buffer, 4);
2707 break;
2708 case RPC_FC_ALIGNM8:
2709 ALIGN_LENGTH(size, 8);
2710 ALIGN_POINTER(pStubMsg->Buffer, 8);
2711 break;
2712 case RPC_FC_STRUCTPAD1:
2713 case RPC_FC_STRUCTPAD2:
2714 case RPC_FC_STRUCTPAD3:
2715 case RPC_FC_STRUCTPAD4:
2716 case RPC_FC_STRUCTPAD5:
2717 case RPC_FC_STRUCTPAD6:
2718 case RPC_FC_STRUCTPAD7:
2719 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2720 break;
2721 case RPC_FC_EMBEDDED_COMPLEX:
2722 size += pFormat[1];
2723 pFormat += 2;
2724 desc = pFormat + *(const SHORT*)pFormat;
2725 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2726 pFormat += 2;
2727 continue;
2728 case RPC_FC_PAD:
2729 break;
2730 default:
2731 FIXME("unhandled format 0x%02x\n", *pFormat);
2733 pFormat++;
2736 return size;
2739 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
2740 PFORMAT_STRING pFormat)
2742 PFORMAT_STRING desc;
2743 unsigned long size = 0;
2745 while (*pFormat != RPC_FC_END) {
2746 switch (*pFormat) {
2747 case RPC_FC_BYTE:
2748 case RPC_FC_CHAR:
2749 case RPC_FC_SMALL:
2750 case RPC_FC_USMALL:
2751 size += 1;
2752 break;
2753 case RPC_FC_WCHAR:
2754 case RPC_FC_SHORT:
2755 case RPC_FC_USHORT:
2756 size += 2;
2757 break;
2758 case RPC_FC_LONG:
2759 case RPC_FC_ULONG:
2760 case RPC_FC_ENUM16:
2761 case RPC_FC_ENUM32:
2762 size += 4;
2763 break;
2764 case RPC_FC_HYPER:
2765 size += 8;
2766 break;
2767 case RPC_FC_POINTER:
2768 size += sizeof(void *);
2769 break;
2770 case RPC_FC_ALIGNM4:
2771 ALIGN_LENGTH(size, 4);
2772 break;
2773 case RPC_FC_ALIGNM8:
2774 ALIGN_LENGTH(size, 8);
2775 break;
2776 case RPC_FC_STRUCTPAD1:
2777 case RPC_FC_STRUCTPAD2:
2778 case RPC_FC_STRUCTPAD3:
2779 case RPC_FC_STRUCTPAD4:
2780 case RPC_FC_STRUCTPAD5:
2781 case RPC_FC_STRUCTPAD6:
2782 case RPC_FC_STRUCTPAD7:
2783 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2784 break;
2785 case RPC_FC_EMBEDDED_COMPLEX:
2786 size += pFormat[1];
2787 pFormat += 2;
2788 desc = pFormat + *(const SHORT*)pFormat;
2789 size += EmbeddedComplexSize(pStubMsg, desc);
2790 pFormat += 2;
2791 continue;
2792 case RPC_FC_PAD:
2793 break;
2794 default:
2795 FIXME("unhandled format 0x%02x\n", *pFormat);
2797 pFormat++;
2800 return size;
2803 /***********************************************************************
2804 * NdrComplexStructMarshall [RPCRT4.@]
2806 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2807 unsigned char *pMemory,
2808 PFORMAT_STRING pFormat)
2810 PFORMAT_STRING conf_array = NULL;
2811 PFORMAT_STRING pointer_desc = NULL;
2812 unsigned char *OldMemory = pStubMsg->Memory;
2813 int pointer_buffer_mark_set = 0;
2815 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2817 if (!pStubMsg->PointerBufferMark)
2819 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2820 /* save buffer length */
2821 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2823 /* get the buffer pointer after complex array data, but before
2824 * pointer data */
2825 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2826 pStubMsg->IgnoreEmbeddedPointers = 1;
2827 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2828 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2830 /* save it for use by embedded pointer code later */
2831 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2832 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2833 pointer_buffer_mark_set = 1;
2835 /* restore the original buffer length */
2836 pStubMsg->BufferLength = saved_buffer_length;
2839 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2841 pFormat += 4;
2842 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2843 pFormat += 2;
2844 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2845 pFormat += 2;
2847 pStubMsg->Memory = pMemory;
2849 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2851 if (conf_array)
2852 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2854 pStubMsg->Memory = OldMemory;
2856 if (pointer_buffer_mark_set)
2858 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2859 pStubMsg->PointerBufferMark = NULL;
2862 STD_OVERFLOW_CHECK(pStubMsg);
2864 return NULL;
2867 /***********************************************************************
2868 * NdrComplexStructUnmarshall [RPCRT4.@]
2870 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2871 unsigned char **ppMemory,
2872 PFORMAT_STRING pFormat,
2873 unsigned char fMustAlloc)
2875 unsigned size = *(const WORD*)(pFormat+2);
2876 PFORMAT_STRING conf_array = NULL;
2877 PFORMAT_STRING pointer_desc = NULL;
2878 unsigned char *pMemory;
2879 int pointer_buffer_mark_set = 0;
2881 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2883 if (!pStubMsg->PointerBufferMark)
2885 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2886 /* save buffer pointer */
2887 unsigned char *saved_buffer = pStubMsg->Buffer;
2889 /* get the buffer pointer after complex array data, but before
2890 * pointer data */
2891 pStubMsg->IgnoreEmbeddedPointers = 1;
2892 NdrComplexStructMemorySize(pStubMsg, pFormat);
2893 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2895 /* save it for use by embedded pointer code later */
2896 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2897 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2898 pointer_buffer_mark_set = 1;
2900 /* restore the original buffer */
2901 pStubMsg->Buffer = saved_buffer;
2904 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2906 if (fMustAlloc || !*ppMemory)
2908 *ppMemory = NdrAllocate(pStubMsg, size);
2909 memset(*ppMemory, 0, size);
2912 pFormat += 4;
2913 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2914 pFormat += 2;
2915 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2916 pFormat += 2;
2918 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2920 if (conf_array)
2921 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2923 if (pointer_buffer_mark_set)
2925 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2926 pStubMsg->PointerBufferMark = NULL;
2929 return NULL;
2932 /***********************************************************************
2933 * NdrComplexStructBufferSize [RPCRT4.@]
2935 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2936 unsigned char *pMemory,
2937 PFORMAT_STRING pFormat)
2939 PFORMAT_STRING conf_array = NULL;
2940 PFORMAT_STRING pointer_desc = NULL;
2941 unsigned char *OldMemory = pStubMsg->Memory;
2942 int pointer_length_set = 0;
2944 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2946 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2948 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2950 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2951 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2953 /* get the buffer length after complex struct data, but before
2954 * pointer data */
2955 pStubMsg->IgnoreEmbeddedPointers = 1;
2956 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2957 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2959 /* save it for use by embedded pointer code later */
2960 pStubMsg->PointerLength = pStubMsg->BufferLength;
2961 pointer_length_set = 1;
2962 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2964 /* restore the original buffer length */
2965 pStubMsg->BufferLength = saved_buffer_length;
2968 pFormat += 4;
2969 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2970 pFormat += 2;
2971 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2972 pFormat += 2;
2974 pStubMsg->Memory = pMemory;
2976 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2978 if (conf_array)
2979 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2981 pStubMsg->Memory = OldMemory;
2983 if(pointer_length_set)
2985 pStubMsg->BufferLength = pStubMsg->PointerLength;
2986 pStubMsg->PointerLength = 0;
2991 /***********************************************************************
2992 * NdrComplexStructMemorySize [RPCRT4.@]
2994 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2995 PFORMAT_STRING pFormat)
2997 unsigned size = *(const WORD*)(pFormat+2);
2998 PFORMAT_STRING conf_array = NULL;
2999 PFORMAT_STRING pointer_desc = NULL;
3001 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3003 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3005 pFormat += 4;
3006 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
3007 pFormat += 2;
3008 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3009 pFormat += 2;
3011 ComplexStructMemorySize(pStubMsg, pFormat);
3013 if (conf_array)
3014 NdrConformantArrayMemorySize(pStubMsg, conf_array);
3016 return size;
3019 /***********************************************************************
3020 * NdrComplexStructFree [RPCRT4.@]
3022 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3023 unsigned char *pMemory,
3024 PFORMAT_STRING pFormat)
3026 PFORMAT_STRING conf_array = NULL;
3027 PFORMAT_STRING pointer_desc = NULL;
3028 unsigned char *OldMemory = pStubMsg->Memory;
3030 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3032 pFormat += 4;
3033 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
3034 pFormat += 2;
3035 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3036 pFormat += 2;
3038 pStubMsg->Memory = pMemory;
3040 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3042 if (conf_array)
3043 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
3045 pStubMsg->Memory = OldMemory;
3048 /***********************************************************************
3049 * NdrConformantArrayMarshall [RPCRT4.@]
3051 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3052 unsigned char *pMemory,
3053 PFORMAT_STRING pFormat)
3055 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3056 unsigned char alignment = pFormat[1] + 1;
3058 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3059 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3061 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3063 WriteConformance(pStubMsg);
3065 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3067 size = safe_multiply(esize, pStubMsg->MaxCount);
3068 pStubMsg->BufferMark = pStubMsg->Buffer;
3069 safe_copy_to_buffer(pStubMsg, pMemory, size);
3071 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3073 return NULL;
3076 /***********************************************************************
3077 * NdrConformantArrayUnmarshall [RPCRT4.@]
3079 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3080 unsigned char **ppMemory,
3081 PFORMAT_STRING pFormat,
3082 unsigned char fMustAlloc)
3084 DWORD size, esize = *(const WORD*)(pFormat+2);
3085 unsigned char alignment = pFormat[1] + 1;
3086 unsigned char *saved_buffer;
3088 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3089 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3091 pFormat = ReadConformance(pStubMsg, pFormat+4);
3093 size = safe_multiply(esize, pStubMsg->MaxCount);
3094 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3096 if (fMustAlloc)
3097 *ppMemory = NdrAllocate(pStubMsg, size);
3098 else
3100 if (!pStubMsg->IsClient && !*ppMemory)
3101 /* for servers, we just point straight into the RPC buffer */
3102 *ppMemory = pStubMsg->Buffer;
3105 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3106 safe_buffer_increment(pStubMsg, size);
3107 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3109 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3110 if (*ppMemory != saved_buffer)
3111 memcpy(*ppMemory, saved_buffer, size);
3113 return NULL;
3116 /***********************************************************************
3117 * NdrConformantArrayBufferSize [RPCRT4.@]
3119 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3120 unsigned char *pMemory,
3121 PFORMAT_STRING pFormat)
3123 DWORD size, esize = *(const WORD*)(pFormat+2);
3124 unsigned char alignment = pFormat[1] + 1;
3126 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3127 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3129 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3131 SizeConformance(pStubMsg);
3133 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3135 size = safe_multiply(esize, pStubMsg->MaxCount);
3136 /* conformance value plus array */
3137 safe_buffer_length_increment(pStubMsg, size);
3139 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3142 /***********************************************************************
3143 * NdrConformantArrayMemorySize [RPCRT4.@]
3145 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3146 PFORMAT_STRING pFormat)
3148 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3149 unsigned char alignment = pFormat[1] + 1;
3151 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3152 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3154 pFormat = ReadConformance(pStubMsg, pFormat+4);
3155 size = safe_multiply(esize, pStubMsg->MaxCount);
3156 pStubMsg->MemorySize += size;
3158 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3159 pStubMsg->BufferMark = pStubMsg->Buffer;
3160 safe_buffer_increment(pStubMsg, size);
3162 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3164 return pStubMsg->MemorySize;
3167 /***********************************************************************
3168 * NdrConformantArrayFree [RPCRT4.@]
3170 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3171 unsigned char *pMemory,
3172 PFORMAT_STRING pFormat)
3174 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3175 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3177 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3179 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3183 /***********************************************************************
3184 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3186 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3187 unsigned char* pMemory,
3188 PFORMAT_STRING pFormat )
3190 ULONG bufsize;
3191 unsigned char alignment = pFormat[1] + 1;
3192 DWORD esize = *(const WORD*)(pFormat+2);
3194 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3196 if (pFormat[0] != RPC_FC_CVARRAY)
3198 ERR("invalid format type %x\n", pFormat[0]);
3199 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3200 return NULL;
3203 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3204 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3206 WriteConformance(pStubMsg);
3207 WriteVariance(pStubMsg);
3209 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3211 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3213 pStubMsg->BufferMark = pStubMsg->Buffer;
3214 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
3216 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3218 return NULL;
3222 /***********************************************************************
3223 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3225 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3226 unsigned char** ppMemory,
3227 PFORMAT_STRING pFormat,
3228 unsigned char fMustAlloc )
3230 ULONG bufsize, memsize;
3231 unsigned char alignment = pFormat[1] + 1;
3232 DWORD esize = *(const WORD*)(pFormat+2);
3233 unsigned char *saved_buffer;
3234 ULONG offset;
3236 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3238 if (pFormat[0] != RPC_FC_CVARRAY)
3240 ERR("invalid format type %x\n", pFormat[0]);
3241 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3242 return NULL;
3245 pFormat = ReadConformance(pStubMsg, pFormat+4);
3246 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3248 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3250 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3251 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3252 offset = pStubMsg->Offset;
3254 if (!*ppMemory || fMustAlloc)
3255 *ppMemory = NdrAllocate(pStubMsg, memsize);
3256 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3257 safe_buffer_increment(pStubMsg, bufsize);
3259 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3261 memcpy(*ppMemory + offset, saved_buffer, bufsize);
3263 return NULL;
3267 /***********************************************************************
3268 * NdrConformantVaryingArrayFree [RPCRT4.@]
3270 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3271 unsigned char* pMemory,
3272 PFORMAT_STRING pFormat )
3274 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3276 if (pFormat[0] != RPC_FC_CVARRAY)
3278 ERR("invalid format type %x\n", pFormat[0]);
3279 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3280 return;
3283 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3284 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3286 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3290 /***********************************************************************
3291 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3293 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3294 unsigned char* pMemory, PFORMAT_STRING pFormat )
3296 unsigned char alignment = pFormat[1] + 1;
3297 DWORD esize = *(const WORD*)(pFormat+2);
3299 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3301 if (pFormat[0] != RPC_FC_CVARRAY)
3303 ERR("invalid format type %x\n", pFormat[0]);
3304 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3305 return;
3308 /* compute size */
3309 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3310 /* compute length */
3311 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3313 SizeConformance(pStubMsg);
3314 SizeVariance(pStubMsg);
3316 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3318 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3320 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3324 /***********************************************************************
3325 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3327 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3328 PFORMAT_STRING pFormat )
3330 ULONG bufsize, memsize;
3331 unsigned char alignment = pFormat[1] + 1;
3332 DWORD esize = *(const WORD*)(pFormat+2);
3334 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3336 if (pFormat[0] != RPC_FC_CVARRAY)
3338 ERR("invalid format type %x\n", pFormat[0]);
3339 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3340 return pStubMsg->MemorySize;
3343 pFormat = ReadConformance(pStubMsg, pFormat+4);
3344 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3346 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3348 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3349 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3351 safe_buffer_increment(pStubMsg, bufsize);
3352 pStubMsg->MemorySize += memsize;
3354 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3356 return pStubMsg->MemorySize;
3360 /***********************************************************************
3361 * NdrComplexArrayMarshall [RPCRT4.@]
3363 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3364 unsigned char *pMemory,
3365 PFORMAT_STRING pFormat)
3367 ULONG i, count, def;
3368 BOOL variance_present;
3369 unsigned char alignment;
3370 int pointer_buffer_mark_set = 0;
3372 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3374 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3376 ERR("invalid format type %x\n", pFormat[0]);
3377 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3378 return NULL;
3381 alignment = pFormat[1] + 1;
3383 if (!pStubMsg->PointerBufferMark)
3385 /* save buffer fields that may be changed by buffer sizer functions
3386 * and that may be needed later on */
3387 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3388 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3389 unsigned long saved_max_count = pStubMsg->MaxCount;
3390 unsigned long saved_offset = pStubMsg->Offset;
3391 unsigned long saved_actual_count = pStubMsg->ActualCount;
3393 /* get the buffer pointer after complex array data, but before
3394 * pointer data */
3395 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3396 pStubMsg->IgnoreEmbeddedPointers = 1;
3397 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3398 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3400 /* save it for use by embedded pointer code later */
3401 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3402 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3403 pointer_buffer_mark_set = 1;
3405 /* restore fields */
3406 pStubMsg->ActualCount = saved_actual_count;
3407 pStubMsg->Offset = saved_offset;
3408 pStubMsg->MaxCount = saved_max_count;
3409 pStubMsg->BufferLength = saved_buffer_length;
3412 def = *(const WORD*)&pFormat[2];
3413 pFormat += 4;
3415 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3416 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3418 variance_present = IsConformanceOrVariancePresent(pFormat);
3419 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3420 TRACE("variance = %d\n", pStubMsg->ActualCount);
3422 WriteConformance(pStubMsg);
3423 if (variance_present)
3424 WriteVariance(pStubMsg);
3426 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3428 count = pStubMsg->ActualCount;
3429 for (i = 0; i < count; i++)
3430 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3432 STD_OVERFLOW_CHECK(pStubMsg);
3434 if (pointer_buffer_mark_set)
3436 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3437 pStubMsg->PointerBufferMark = NULL;
3440 return NULL;
3443 /***********************************************************************
3444 * NdrComplexArrayUnmarshall [RPCRT4.@]
3446 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3447 unsigned char **ppMemory,
3448 PFORMAT_STRING pFormat,
3449 unsigned char fMustAlloc)
3451 ULONG i, count, size;
3452 unsigned char alignment;
3453 unsigned char *pMemory;
3454 unsigned char *saved_buffer;
3455 int pointer_buffer_mark_set = 0;
3456 int saved_ignore_embedded;
3458 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3460 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3462 ERR("invalid format type %x\n", pFormat[0]);
3463 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3464 return NULL;
3467 alignment = pFormat[1] + 1;
3469 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3470 /* save buffer pointer */
3471 saved_buffer = pStubMsg->Buffer;
3472 /* get the buffer pointer after complex array data, but before
3473 * pointer data */
3474 pStubMsg->IgnoreEmbeddedPointers = 1;
3475 pStubMsg->MemorySize = 0;
3476 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3477 size = pStubMsg->MemorySize;
3478 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3480 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3481 if (!pStubMsg->PointerBufferMark)
3483 /* save it for use by embedded pointer code later */
3484 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3485 pointer_buffer_mark_set = 1;
3487 /* restore the original buffer */
3488 pStubMsg->Buffer = saved_buffer;
3490 pFormat += 4;
3492 pFormat = ReadConformance(pStubMsg, pFormat);
3493 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3495 if (fMustAlloc || !*ppMemory)
3497 *ppMemory = NdrAllocate(pStubMsg, size);
3498 memset(*ppMemory, 0, size);
3501 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3503 pMemory = *ppMemory;
3504 count = pStubMsg->ActualCount;
3505 for (i = 0; i < count; i++)
3506 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3508 if (pointer_buffer_mark_set)
3510 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3511 pStubMsg->PointerBufferMark = NULL;
3514 return NULL;
3517 /***********************************************************************
3518 * NdrComplexArrayBufferSize [RPCRT4.@]
3520 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3521 unsigned char *pMemory,
3522 PFORMAT_STRING pFormat)
3524 ULONG i, count, def;
3525 unsigned char alignment;
3526 BOOL variance_present;
3527 int pointer_length_set = 0;
3529 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3531 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3533 ERR("invalid format type %x\n", pFormat[0]);
3534 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3535 return;
3538 alignment = pFormat[1] + 1;
3540 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3542 /* save buffer fields that may be changed by buffer sizer functions
3543 * and that may be needed later on */
3544 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3545 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3546 unsigned long saved_max_count = pStubMsg->MaxCount;
3547 unsigned long saved_offset = pStubMsg->Offset;
3548 unsigned long saved_actual_count = pStubMsg->ActualCount;
3550 /* get the buffer pointer after complex array data, but before
3551 * pointer data */
3552 pStubMsg->IgnoreEmbeddedPointers = 1;
3553 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3554 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3556 /* save it for use by embedded pointer code later */
3557 pStubMsg->PointerLength = pStubMsg->BufferLength;
3558 pointer_length_set = 1;
3560 /* restore fields */
3561 pStubMsg->ActualCount = saved_actual_count;
3562 pStubMsg->Offset = saved_offset;
3563 pStubMsg->MaxCount = saved_max_count;
3564 pStubMsg->BufferLength = saved_buffer_length;
3566 def = *(const WORD*)&pFormat[2];
3567 pFormat += 4;
3569 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3570 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3571 SizeConformance(pStubMsg);
3573 variance_present = IsConformanceOrVariancePresent(pFormat);
3574 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3575 TRACE("variance = %d\n", pStubMsg->ActualCount);
3577 if (variance_present)
3578 SizeVariance(pStubMsg);
3580 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3582 count = pStubMsg->ActualCount;
3583 for (i = 0; i < count; i++)
3584 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3586 if(pointer_length_set)
3588 pStubMsg->BufferLength = pStubMsg->PointerLength;
3589 pStubMsg->PointerLength = 0;
3593 /***********************************************************************
3594 * NdrComplexArrayMemorySize [RPCRT4.@]
3596 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3597 PFORMAT_STRING pFormat)
3599 ULONG i, count, esize, SavedMemorySize, MemorySize;
3600 unsigned char alignment;
3602 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3604 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3606 ERR("invalid format type %x\n", pFormat[0]);
3607 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3608 return 0;
3611 alignment = pFormat[1] + 1;
3613 pFormat += 4;
3615 pFormat = ReadConformance(pStubMsg, pFormat);
3616 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3618 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3620 SavedMemorySize = pStubMsg->MemorySize;
3622 esize = ComplexStructSize(pStubMsg, pFormat);
3624 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3626 count = pStubMsg->ActualCount;
3627 for (i = 0; i < count; i++)
3628 ComplexStructMemorySize(pStubMsg, pFormat);
3630 pStubMsg->MemorySize = SavedMemorySize;
3632 pStubMsg->MemorySize += MemorySize;
3633 return MemorySize;
3636 /***********************************************************************
3637 * NdrComplexArrayFree [RPCRT4.@]
3639 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3640 unsigned char *pMemory,
3641 PFORMAT_STRING pFormat)
3643 ULONG i, count, def;
3645 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3647 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3649 ERR("invalid format type %x\n", pFormat[0]);
3650 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3651 return;
3654 def = *(const WORD*)&pFormat[2];
3655 pFormat += 4;
3657 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3658 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3660 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3661 TRACE("variance = %d\n", pStubMsg->ActualCount);
3663 count = pStubMsg->ActualCount;
3664 for (i = 0; i < count; i++)
3665 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3668 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3669 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3670 USER_MARSHAL_CB *umcb)
3672 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3673 pStubMsg->RpcMsg->DataRepresentation);
3674 umcb->pStubMsg = pStubMsg;
3675 umcb->pReserve = NULL;
3676 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3677 umcb->CBType = cbtype;
3678 umcb->pFormat = pFormat;
3679 umcb->pTypeFormat = NULL /* FIXME */;
3682 #define USER_MARSHAL_PTR_PREFIX \
3683 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3684 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3686 /***********************************************************************
3687 * NdrUserMarshalMarshall [RPCRT4.@]
3689 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3690 unsigned char *pMemory,
3691 PFORMAT_STRING pFormat)
3693 unsigned flags = pFormat[1];
3694 unsigned index = *(const WORD*)&pFormat[2];
3695 unsigned char *saved_buffer = NULL;
3696 USER_MARSHAL_CB umcb;
3698 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3699 TRACE("index=%d\n", index);
3701 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3703 if (flags & USER_MARSHAL_POINTER)
3705 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3706 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3707 pStubMsg->Buffer += 4;
3708 if (pStubMsg->PointerBufferMark)
3710 saved_buffer = pStubMsg->Buffer;
3711 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3712 pStubMsg->PointerBufferMark = NULL;
3714 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3716 else
3717 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3719 pStubMsg->Buffer =
3720 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3721 &umcb.Flags, pStubMsg->Buffer, pMemory);
3723 if (saved_buffer)
3725 STD_OVERFLOW_CHECK(pStubMsg);
3726 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3727 pStubMsg->Buffer = saved_buffer;
3730 STD_OVERFLOW_CHECK(pStubMsg);
3732 return NULL;
3735 /***********************************************************************
3736 * NdrUserMarshalUnmarshall [RPCRT4.@]
3738 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3739 unsigned char **ppMemory,
3740 PFORMAT_STRING pFormat,
3741 unsigned char fMustAlloc)
3743 unsigned flags = pFormat[1];
3744 unsigned index = *(const WORD*)&pFormat[2];
3745 DWORD memsize = *(const WORD*)&pFormat[4];
3746 unsigned char *saved_buffer = NULL;
3747 USER_MARSHAL_CB umcb;
3749 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3750 TRACE("index=%d\n", index);
3752 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3754 if (flags & USER_MARSHAL_POINTER)
3756 ALIGN_POINTER(pStubMsg->Buffer, 4);
3757 /* skip pointer prefix */
3758 pStubMsg->Buffer += 4;
3759 if (pStubMsg->PointerBufferMark)
3761 saved_buffer = pStubMsg->Buffer;
3762 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3763 pStubMsg->PointerBufferMark = NULL;
3765 ALIGN_POINTER(pStubMsg->Buffer, 8);
3767 else
3768 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3770 if (fMustAlloc || !*ppMemory)
3771 *ppMemory = NdrAllocate(pStubMsg, memsize);
3773 pStubMsg->Buffer =
3774 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3775 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3777 if (saved_buffer)
3779 STD_OVERFLOW_CHECK(pStubMsg);
3780 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3781 pStubMsg->Buffer = saved_buffer;
3784 return NULL;
3787 /***********************************************************************
3788 * NdrUserMarshalBufferSize [RPCRT4.@]
3790 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3791 unsigned char *pMemory,
3792 PFORMAT_STRING pFormat)
3794 unsigned flags = pFormat[1];
3795 unsigned index = *(const WORD*)&pFormat[2];
3796 DWORD bufsize = *(const WORD*)&pFormat[6];
3797 USER_MARSHAL_CB umcb;
3798 unsigned long saved_buffer_length = 0;
3800 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3801 TRACE("index=%d\n", index);
3803 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3805 if (flags & USER_MARSHAL_POINTER)
3807 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3808 /* skip pointer prefix */
3809 safe_buffer_length_increment(pStubMsg, 4);
3810 if (pStubMsg->IgnoreEmbeddedPointers)
3811 return;
3812 if (pStubMsg->PointerLength)
3814 saved_buffer_length = pStubMsg->BufferLength;
3815 pStubMsg->BufferLength = pStubMsg->PointerLength;
3816 pStubMsg->PointerLength = 0;
3818 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3820 else
3821 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3823 if (bufsize) {
3824 TRACE("size=%d\n", bufsize);
3825 safe_buffer_length_increment(pStubMsg, bufsize);
3827 else
3828 pStubMsg->BufferLength =
3829 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3830 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3832 if (saved_buffer_length)
3834 pStubMsg->PointerLength = pStubMsg->BufferLength;
3835 pStubMsg->BufferLength = saved_buffer_length;
3840 /***********************************************************************
3841 * NdrUserMarshalMemorySize [RPCRT4.@]
3843 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3844 PFORMAT_STRING pFormat)
3846 unsigned flags = pFormat[1];
3847 unsigned index = *(const WORD*)&pFormat[2];
3848 DWORD memsize = *(const WORD*)&pFormat[4];
3849 DWORD bufsize = *(const WORD*)&pFormat[6];
3851 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3852 TRACE("index=%d\n", index);
3854 pStubMsg->MemorySize += memsize;
3856 if (flags & USER_MARSHAL_POINTER)
3858 ALIGN_POINTER(pStubMsg->Buffer, 4);
3859 /* skip pointer prefix */
3860 pStubMsg->Buffer += 4;
3861 if (pStubMsg->IgnoreEmbeddedPointers)
3862 return pStubMsg->MemorySize;
3863 ALIGN_POINTER(pStubMsg->Buffer, 8);
3865 else
3866 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3868 if (!bufsize)
3869 FIXME("not implemented for varying buffer size\n");
3871 pStubMsg->Buffer += bufsize;
3873 return pStubMsg->MemorySize;
3876 /***********************************************************************
3877 * NdrUserMarshalFree [RPCRT4.@]
3879 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3880 unsigned char *pMemory,
3881 PFORMAT_STRING pFormat)
3883 /* unsigned flags = pFormat[1]; */
3884 unsigned index = *(const WORD*)&pFormat[2];
3885 USER_MARSHAL_CB umcb;
3887 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3888 TRACE("index=%d\n", index);
3890 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3892 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3893 &umcb.Flags, pMemory);
3896 /***********************************************************************
3897 * NdrClearOutParameters [RPCRT4.@]
3899 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3900 PFORMAT_STRING pFormat,
3901 void *ArgAddr)
3903 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3906 /***********************************************************************
3907 * NdrConvert [RPCRT4.@]
3909 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3911 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3912 /* FIXME: since this stub doesn't do any converting, the proper behavior
3913 is to raise an exception */
3916 /***********************************************************************
3917 * NdrConvert2 [RPCRT4.@]
3919 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3921 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3922 pStubMsg, pFormat, NumberParams);
3923 /* FIXME: since this stub doesn't do any converting, the proper behavior
3924 is to raise an exception */
3927 #include "pshpack1.h"
3928 typedef struct _NDR_CSTRUCT_FORMAT
3930 unsigned char type;
3931 unsigned char alignment;
3932 unsigned short memory_size;
3933 short offset_to_array_description;
3934 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3935 #include "poppack.h"
3937 /***********************************************************************
3938 * NdrConformantStructMarshall [RPCRT4.@]
3940 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3941 unsigned char *pMemory,
3942 PFORMAT_STRING pFormat)
3944 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3945 PFORMAT_STRING pCArrayFormat;
3946 ULONG esize, bufsize;
3948 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3950 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3951 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3953 ERR("invalid format type %x\n", pCStructFormat->type);
3954 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3955 return NULL;
3958 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3959 pCStructFormat->offset_to_array_description;
3960 if (*pCArrayFormat != RPC_FC_CARRAY)
3962 ERR("invalid array format type %x\n", pCStructFormat->type);
3963 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3964 return NULL;
3966 esize = *(const WORD*)(pCArrayFormat+2);
3968 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3969 pCArrayFormat + 4, 0);
3971 WriteConformance(pStubMsg);
3973 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3975 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3977 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3978 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3980 ERR("integer overflow of memory_size %u with bufsize %u\n",
3981 pCStructFormat->memory_size, bufsize);
3982 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3984 /* copy constant sized part of struct */
3985 pStubMsg->BufferMark = pStubMsg->Buffer;
3986 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3988 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3989 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3991 return NULL;
3994 /***********************************************************************
3995 * NdrConformantStructUnmarshall [RPCRT4.@]
3997 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3998 unsigned char **ppMemory,
3999 PFORMAT_STRING pFormat,
4000 unsigned char fMustAlloc)
4002 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4003 PFORMAT_STRING pCArrayFormat;
4004 ULONG esize, bufsize;
4005 unsigned char *saved_buffer;
4007 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4009 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4010 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4012 ERR("invalid format type %x\n", pCStructFormat->type);
4013 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4014 return NULL;
4016 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4017 pCStructFormat->offset_to_array_description;
4018 if (*pCArrayFormat != RPC_FC_CARRAY)
4020 ERR("invalid array format type %x\n", pCStructFormat->type);
4021 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4022 return NULL;
4024 esize = *(const WORD*)(pCArrayFormat+2);
4026 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4028 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4030 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4032 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4033 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4035 ERR("integer overflow of memory_size %u with bufsize %u\n",
4036 pCStructFormat->memory_size, bufsize);
4037 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4040 if (fMustAlloc)
4042 SIZE_T size = pCStructFormat->memory_size + bufsize;
4043 *ppMemory = NdrAllocate(pStubMsg, size);
4045 else
4047 if (!pStubMsg->IsClient && !*ppMemory)
4048 /* for servers, we just point straight into the RPC buffer */
4049 *ppMemory = pStubMsg->Buffer;
4052 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4053 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4054 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4055 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4057 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4058 if (*ppMemory != saved_buffer)
4059 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4061 return NULL;
4064 /***********************************************************************
4065 * NdrConformantStructBufferSize [RPCRT4.@]
4067 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4068 unsigned char *pMemory,
4069 PFORMAT_STRING pFormat)
4071 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4072 PFORMAT_STRING pCArrayFormat;
4073 ULONG esize;
4075 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4077 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4078 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4080 ERR("invalid format type %x\n", pCStructFormat->type);
4081 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4082 return;
4084 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4085 pCStructFormat->offset_to_array_description;
4086 if (*pCArrayFormat != RPC_FC_CARRAY)
4088 ERR("invalid array format type %x\n", pCStructFormat->type);
4089 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4090 return;
4092 esize = *(const WORD*)(pCArrayFormat+2);
4094 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4095 SizeConformance(pStubMsg);
4097 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4099 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4101 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4102 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4104 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4105 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4108 /***********************************************************************
4109 * NdrConformantStructMemorySize [RPCRT4.@]
4111 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4112 PFORMAT_STRING pFormat)
4114 FIXME("stub\n");
4115 return 0;
4118 /***********************************************************************
4119 * NdrConformantStructFree [RPCRT4.@]
4121 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4122 unsigned char *pMemory,
4123 PFORMAT_STRING pFormat)
4125 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4126 PFORMAT_STRING pCArrayFormat;
4127 ULONG esize;
4129 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4131 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4132 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4134 ERR("invalid format type %x\n", pCStructFormat->type);
4135 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4136 return;
4139 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4140 pCStructFormat->offset_to_array_description;
4141 if (*pCArrayFormat != RPC_FC_CARRAY)
4143 ERR("invalid array format type %x\n", pCStructFormat->type);
4144 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4145 return;
4147 esize = *(const WORD*)(pCArrayFormat+2);
4149 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4150 pCArrayFormat + 4, 0);
4152 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4154 /* copy constant sized part of struct */
4155 pStubMsg->BufferMark = pStubMsg->Buffer;
4157 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4158 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4161 /***********************************************************************
4162 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4164 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4165 unsigned char *pMemory,
4166 PFORMAT_STRING pFormat)
4168 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4169 PFORMAT_STRING pCVArrayFormat;
4170 ULONG esize, bufsize;
4172 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4174 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4175 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4177 ERR("invalid format type %x\n", pCVStructFormat->type);
4178 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4179 return NULL;
4182 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4183 pCVStructFormat->offset_to_array_description;
4184 switch (*pCVArrayFormat)
4186 case RPC_FC_CVARRAY:
4187 esize = *(const WORD*)(pCVArrayFormat+2);
4189 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4190 pCVArrayFormat + 4, 0);
4191 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4192 pCVArrayFormat, 0);
4193 break;
4194 case RPC_FC_C_CSTRING:
4195 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4196 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4197 esize = sizeof(char);
4198 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4199 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4200 pCVArrayFormat + 2, 0);
4201 else
4202 pStubMsg->MaxCount = pStubMsg->ActualCount;
4203 break;
4204 case RPC_FC_C_WSTRING:
4205 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4206 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4207 esize = sizeof(WCHAR);
4208 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4209 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4210 pCVArrayFormat + 2, 0);
4211 else
4212 pStubMsg->MaxCount = pStubMsg->ActualCount;
4213 break;
4214 default:
4215 ERR("invalid array format type %x\n", *pCVArrayFormat);
4216 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4217 return NULL;
4220 WriteConformance(pStubMsg);
4222 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4224 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4226 /* write constant sized part */
4227 pStubMsg->BufferMark = pStubMsg->Buffer;
4228 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4230 WriteVariance(pStubMsg);
4232 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4234 /* write array part */
4235 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
4237 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4239 return NULL;
4242 /***********************************************************************
4243 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4245 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4246 unsigned char **ppMemory,
4247 PFORMAT_STRING pFormat,
4248 unsigned char fMustAlloc)
4250 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4251 PFORMAT_STRING pCVArrayFormat;
4252 ULONG esize, bufsize;
4253 unsigned char cvarray_type;
4255 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4257 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4258 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4260 ERR("invalid format type %x\n", pCVStructFormat->type);
4261 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4262 return NULL;
4265 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4266 pCVStructFormat->offset_to_array_description;
4267 cvarray_type = *pCVArrayFormat;
4268 switch (cvarray_type)
4270 case RPC_FC_CVARRAY:
4271 esize = *(const WORD*)(pCVArrayFormat+2);
4272 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4273 break;
4274 case RPC_FC_C_CSTRING:
4275 esize = sizeof(char);
4276 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4277 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4278 else
4279 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4280 break;
4281 case RPC_FC_C_WSTRING:
4282 esize = sizeof(WCHAR);
4283 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4284 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4285 else
4286 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4287 break;
4288 default:
4289 ERR("invalid array format type %x\n", *pCVArrayFormat);
4290 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4291 return NULL;
4294 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4296 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4298 /* work out how much memory to allocate if we need to do so */
4299 if (!*ppMemory || fMustAlloc)
4301 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4302 *ppMemory = NdrAllocate(pStubMsg, size);
4305 /* copy the constant data */
4306 pStubMsg->BufferMark = pStubMsg->Buffer;
4307 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
4309 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4311 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4313 if ((cvarray_type == RPC_FC_C_CSTRING) ||
4314 (cvarray_type == RPC_FC_C_WSTRING))
4316 ULONG i;
4317 /* strings must always have null terminating bytes */
4318 if (bufsize < esize)
4320 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
4321 RpcRaiseException(RPC_S_INVALID_BOUND);
4322 return NULL;
4324 for (i = bufsize - esize; i < bufsize; i++)
4325 if (pStubMsg->Buffer[i] != 0)
4327 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
4328 i, pStubMsg->Buffer[i]);
4329 RpcRaiseException(RPC_S_INVALID_BOUND);
4330 return NULL;
4334 /* copy the array data */
4335 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
4337 if (cvarray_type == RPC_FC_C_CSTRING)
4338 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4339 else if (cvarray_type == RPC_FC_C_WSTRING)
4340 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4342 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4344 return NULL;
4347 /***********************************************************************
4348 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4350 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4351 unsigned char *pMemory,
4352 PFORMAT_STRING pFormat)
4354 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4355 PFORMAT_STRING pCVArrayFormat;
4356 ULONG esize;
4358 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4360 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4361 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4363 ERR("invalid format type %x\n", pCVStructFormat->type);
4364 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4365 return;
4368 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4369 pCVStructFormat->offset_to_array_description;
4370 switch (*pCVArrayFormat)
4372 case RPC_FC_CVARRAY:
4373 esize = *(const WORD*)(pCVArrayFormat+2);
4375 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4376 pCVArrayFormat + 4, 0);
4377 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4378 pCVArrayFormat, 0);
4379 break;
4380 case RPC_FC_C_CSTRING:
4381 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4382 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4383 esize = sizeof(char);
4384 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4385 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4386 pCVArrayFormat + 2, 0);
4387 else
4388 pStubMsg->MaxCount = pStubMsg->ActualCount;
4389 break;
4390 case RPC_FC_C_WSTRING:
4391 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4392 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4393 esize = sizeof(WCHAR);
4394 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4395 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4396 pCVArrayFormat + 2, 0);
4397 else
4398 pStubMsg->MaxCount = pStubMsg->ActualCount;
4399 break;
4400 default:
4401 ERR("invalid array format type %x\n", *pCVArrayFormat);
4402 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4403 return;
4406 SizeConformance(pStubMsg);
4408 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4410 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4412 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4413 SizeVariance(pStubMsg);
4414 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4416 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4419 /***********************************************************************
4420 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4422 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4423 PFORMAT_STRING pFormat)
4425 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4426 PFORMAT_STRING pCVArrayFormat;
4427 ULONG esize;
4428 unsigned char cvarray_type;
4430 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4432 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4433 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4435 ERR("invalid format type %x\n", pCVStructFormat->type);
4436 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4437 return 0;
4440 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4441 pCVStructFormat->offset_to_array_description;
4442 cvarray_type = *pCVArrayFormat;
4443 switch (cvarray_type)
4445 case RPC_FC_CVARRAY:
4446 esize = *(const WORD*)(pCVArrayFormat+2);
4447 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4448 break;
4449 case RPC_FC_C_CSTRING:
4450 esize = sizeof(char);
4451 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4452 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4453 else
4454 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4455 break;
4456 case RPC_FC_C_WSTRING:
4457 esize = sizeof(WCHAR);
4458 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4459 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4460 else
4461 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4462 break;
4463 default:
4464 ERR("invalid array format type %x\n", *pCVArrayFormat);
4465 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4466 return 0;
4469 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4471 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4473 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4474 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4475 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4477 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4479 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4481 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4484 /***********************************************************************
4485 * NdrConformantVaryingStructFree [RPCRT4.@]
4487 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4488 unsigned char *pMemory,
4489 PFORMAT_STRING pFormat)
4491 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4492 PFORMAT_STRING pCVArrayFormat;
4493 ULONG esize;
4495 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4497 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4498 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4500 ERR("invalid format type %x\n", pCVStructFormat->type);
4501 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4502 return;
4505 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4506 pCVStructFormat->offset_to_array_description;
4507 switch (*pCVArrayFormat)
4509 case RPC_FC_CVARRAY:
4510 esize = *(const WORD*)(pCVArrayFormat+2);
4512 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4513 pCVArrayFormat + 4, 0);
4514 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4515 pCVArrayFormat, 0);
4516 break;
4517 case RPC_FC_C_CSTRING:
4518 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4519 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4520 esize = sizeof(char);
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 case RPC_FC_C_WSTRING:
4528 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4529 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4530 esize = sizeof(WCHAR);
4531 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4532 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4533 pCVArrayFormat + 2, 0);
4534 else
4535 pStubMsg->MaxCount = pStubMsg->ActualCount;
4536 break;
4537 default:
4538 ERR("invalid array format type %x\n", *pCVArrayFormat);
4539 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4540 return;
4543 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4545 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4548 #include "pshpack1.h"
4549 typedef struct
4551 unsigned char type;
4552 unsigned char alignment;
4553 unsigned short total_size;
4554 } NDR_SMFARRAY_FORMAT;
4556 typedef struct
4558 unsigned char type;
4559 unsigned char alignment;
4560 unsigned long total_size;
4561 } NDR_LGFARRAY_FORMAT;
4562 #include "poppack.h"
4564 /***********************************************************************
4565 * NdrFixedArrayMarshall [RPCRT4.@]
4567 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4568 unsigned char *pMemory,
4569 PFORMAT_STRING pFormat)
4571 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4572 unsigned long total_size;
4574 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4576 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4577 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4579 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4580 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4581 return NULL;
4584 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4586 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4588 total_size = pSmFArrayFormat->total_size;
4589 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4591 else
4593 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4594 total_size = pLgFArrayFormat->total_size;
4595 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4598 pStubMsg->BufferMark = pStubMsg->Buffer;
4599 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4601 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4603 return NULL;
4606 /***********************************************************************
4607 * NdrFixedArrayUnmarshall [RPCRT4.@]
4609 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4610 unsigned char **ppMemory,
4611 PFORMAT_STRING pFormat,
4612 unsigned char fMustAlloc)
4614 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4615 unsigned long total_size;
4616 unsigned char *saved_buffer;
4618 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4620 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4621 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4623 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4624 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4625 return NULL;
4628 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4630 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4632 total_size = pSmFArrayFormat->total_size;
4633 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4635 else
4637 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4638 total_size = pLgFArrayFormat->total_size;
4639 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4642 if (fMustAlloc)
4643 *ppMemory = NdrAllocate(pStubMsg, total_size);
4644 else
4646 if (!pStubMsg->IsClient && !*ppMemory)
4647 /* for servers, we just point straight into the RPC buffer */
4648 *ppMemory = pStubMsg->Buffer;
4651 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4652 safe_buffer_increment(pStubMsg, total_size);
4653 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4655 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4656 if (*ppMemory != saved_buffer)
4657 memcpy(*ppMemory, saved_buffer, total_size);
4659 return NULL;
4662 /***********************************************************************
4663 * NdrFixedArrayBufferSize [RPCRT4.@]
4665 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4666 unsigned char *pMemory,
4667 PFORMAT_STRING pFormat)
4669 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4670 unsigned long total_size;
4672 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4674 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4675 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4677 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4678 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4679 return;
4682 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4684 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4686 total_size = pSmFArrayFormat->total_size;
4687 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4689 else
4691 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4692 total_size = pLgFArrayFormat->total_size;
4693 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4695 safe_buffer_length_increment(pStubMsg, total_size);
4697 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4700 /***********************************************************************
4701 * NdrFixedArrayMemorySize [RPCRT4.@]
4703 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4704 PFORMAT_STRING pFormat)
4706 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4707 ULONG total_size;
4709 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4711 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4712 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4714 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4715 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4716 return 0;
4719 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4721 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4723 total_size = pSmFArrayFormat->total_size;
4724 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4726 else
4728 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4729 total_size = pLgFArrayFormat->total_size;
4730 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4732 pStubMsg->BufferMark = pStubMsg->Buffer;
4733 safe_buffer_increment(pStubMsg, total_size);
4734 pStubMsg->MemorySize += total_size;
4736 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4738 return total_size;
4741 /***********************************************************************
4742 * NdrFixedArrayFree [RPCRT4.@]
4744 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4745 unsigned char *pMemory,
4746 PFORMAT_STRING pFormat)
4748 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4750 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4752 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4753 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4755 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4756 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4757 return;
4760 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4761 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4762 else
4764 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4765 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4768 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4771 /***********************************************************************
4772 * NdrVaryingArrayMarshall [RPCRT4.@]
4774 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4775 unsigned char *pMemory,
4776 PFORMAT_STRING pFormat)
4778 unsigned char alignment;
4779 DWORD elements, esize;
4780 ULONG bufsize;
4782 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4784 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4785 (pFormat[0] != RPC_FC_LGVARRAY))
4787 ERR("invalid format type %x\n", pFormat[0]);
4788 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4789 return NULL;
4792 alignment = pFormat[1] + 1;
4794 if (pFormat[0] == RPC_FC_SMVARRAY)
4796 pFormat += 2;
4797 pFormat += sizeof(WORD);
4798 elements = *(const WORD*)pFormat;
4799 pFormat += sizeof(WORD);
4801 else
4803 pFormat += 2;
4804 pFormat += sizeof(DWORD);
4805 elements = *(const DWORD*)pFormat;
4806 pFormat += sizeof(DWORD);
4809 esize = *(const WORD*)pFormat;
4810 pFormat += sizeof(WORD);
4812 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4813 if ((pStubMsg->ActualCount > elements) ||
4814 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4816 RpcRaiseException(RPC_S_INVALID_BOUND);
4817 return NULL;
4820 WriteVariance(pStubMsg);
4822 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4824 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4825 pStubMsg->BufferMark = pStubMsg->Buffer;
4826 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4828 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4830 return NULL;
4833 /***********************************************************************
4834 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4836 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4837 unsigned char **ppMemory,
4838 PFORMAT_STRING pFormat,
4839 unsigned char fMustAlloc)
4841 unsigned char alignment;
4842 DWORD size, elements, esize;
4843 ULONG bufsize;
4844 unsigned char *saved_buffer;
4845 ULONG offset;
4847 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4849 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4850 (pFormat[0] != RPC_FC_LGVARRAY))
4852 ERR("invalid format type %x\n", pFormat[0]);
4853 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4854 return NULL;
4857 alignment = pFormat[1] + 1;
4859 if (pFormat[0] == RPC_FC_SMVARRAY)
4861 pFormat += 2;
4862 size = *(const WORD*)pFormat;
4863 pFormat += sizeof(WORD);
4864 elements = *(const WORD*)pFormat;
4865 pFormat += sizeof(WORD);
4867 else
4869 pFormat += 2;
4870 size = *(const DWORD*)pFormat;
4871 pFormat += sizeof(DWORD);
4872 elements = *(const DWORD*)pFormat;
4873 pFormat += sizeof(DWORD);
4876 esize = *(const WORD*)pFormat;
4877 pFormat += sizeof(WORD);
4879 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4881 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4883 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4884 offset = pStubMsg->Offset;
4886 if (!*ppMemory || fMustAlloc)
4887 *ppMemory = NdrAllocate(pStubMsg, size);
4888 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4889 safe_buffer_increment(pStubMsg, bufsize);
4891 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4893 memcpy(*ppMemory + offset, saved_buffer, bufsize);
4895 return NULL;
4898 /***********************************************************************
4899 * NdrVaryingArrayBufferSize [RPCRT4.@]
4901 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4902 unsigned char *pMemory,
4903 PFORMAT_STRING pFormat)
4905 unsigned char alignment;
4906 DWORD elements, esize;
4908 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4910 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4911 (pFormat[0] != RPC_FC_LGVARRAY))
4913 ERR("invalid format type %x\n", pFormat[0]);
4914 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4915 return;
4918 alignment = pFormat[1] + 1;
4920 if (pFormat[0] == RPC_FC_SMVARRAY)
4922 pFormat += 2;
4923 pFormat += sizeof(WORD);
4924 elements = *(const WORD*)pFormat;
4925 pFormat += sizeof(WORD);
4927 else
4929 pFormat += 2;
4930 pFormat += sizeof(DWORD);
4931 elements = *(const DWORD*)pFormat;
4932 pFormat += sizeof(DWORD);
4935 esize = *(const WORD*)pFormat;
4936 pFormat += sizeof(WORD);
4938 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4939 if ((pStubMsg->ActualCount > elements) ||
4940 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4942 RpcRaiseException(RPC_S_INVALID_BOUND);
4943 return;
4946 SizeVariance(pStubMsg);
4948 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4950 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4952 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4955 /***********************************************************************
4956 * NdrVaryingArrayMemorySize [RPCRT4.@]
4958 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4959 PFORMAT_STRING pFormat)
4961 unsigned char alignment;
4962 DWORD size, elements, esize;
4964 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4966 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4967 (pFormat[0] != RPC_FC_LGVARRAY))
4969 ERR("invalid format type %x\n", pFormat[0]);
4970 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4971 return 0;
4974 alignment = pFormat[1] + 1;
4976 if (pFormat[0] == RPC_FC_SMVARRAY)
4978 pFormat += 2;
4979 size = *(const WORD*)pFormat;
4980 pFormat += sizeof(WORD);
4981 elements = *(const WORD*)pFormat;
4982 pFormat += sizeof(WORD);
4984 else
4986 pFormat += 2;
4987 size = *(const DWORD*)pFormat;
4988 pFormat += sizeof(DWORD);
4989 elements = *(const DWORD*)pFormat;
4990 pFormat += sizeof(DWORD);
4993 esize = *(const WORD*)pFormat;
4994 pFormat += sizeof(WORD);
4996 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4998 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5000 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5001 pStubMsg->MemorySize += size;
5003 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5005 return pStubMsg->MemorySize;
5008 /***********************************************************************
5009 * NdrVaryingArrayFree [RPCRT4.@]
5011 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5012 unsigned char *pMemory,
5013 PFORMAT_STRING pFormat)
5015 unsigned char alignment;
5016 DWORD elements;
5018 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5020 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5021 (pFormat[0] != RPC_FC_LGVARRAY))
5023 ERR("invalid format type %x\n", pFormat[0]);
5024 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5025 return;
5028 alignment = pFormat[1] + 1;
5030 if (pFormat[0] == RPC_FC_SMVARRAY)
5032 pFormat += 2;
5033 pFormat += sizeof(WORD);
5034 elements = *(const WORD*)pFormat;
5035 pFormat += sizeof(WORD);
5037 else
5039 pFormat += 2;
5040 pFormat += sizeof(DWORD);
5041 elements = *(const DWORD*)pFormat;
5042 pFormat += sizeof(DWORD);
5045 pFormat += sizeof(WORD);
5047 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5048 if ((pStubMsg->ActualCount > elements) ||
5049 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5051 RpcRaiseException(RPC_S_INVALID_BOUND);
5052 return;
5055 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5058 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5060 switch (fc)
5062 case RPC_FC_BYTE:
5063 case RPC_FC_CHAR:
5064 case RPC_FC_SMALL:
5065 case RPC_FC_USMALL:
5066 return *pMemory;
5067 case RPC_FC_WCHAR:
5068 case RPC_FC_SHORT:
5069 case RPC_FC_USHORT:
5070 case RPC_FC_ENUM16:
5071 return *(const USHORT *)pMemory;
5072 case RPC_FC_LONG:
5073 case RPC_FC_ULONG:
5074 case RPC_FC_ENUM32:
5075 return *(const ULONG *)pMemory;
5076 default:
5077 FIXME("Unhandled base type: 0x%02x\n", fc);
5078 return 0;
5082 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5083 unsigned long discriminant,
5084 PFORMAT_STRING pFormat)
5086 unsigned short num_arms, arm, type;
5088 num_arms = *(const SHORT*)pFormat & 0x0fff;
5089 pFormat += 2;
5090 for(arm = 0; arm < num_arms; arm++)
5092 if(discriminant == *(const ULONG*)pFormat)
5094 pFormat += 4;
5095 break;
5097 pFormat += 6;
5100 type = *(const unsigned short*)pFormat;
5101 TRACE("type %04x\n", type);
5102 if(arm == num_arms) /* default arm extras */
5104 if(type == 0xffff)
5106 ERR("no arm for 0x%lx and no default case\n", discriminant);
5107 RpcRaiseException(RPC_S_INVALID_TAG);
5108 return NULL;
5110 if(type == 0)
5112 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5113 return NULL;
5116 return pFormat;
5119 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5121 unsigned short type;
5123 pFormat += 2;
5125 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5126 if(!pFormat)
5127 return NULL;
5129 type = *(const unsigned short*)pFormat;
5130 if((type & 0xff00) == 0x8000)
5132 unsigned char basetype = LOBYTE(type);
5133 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5135 else
5137 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5138 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5139 if (m)
5141 unsigned char *saved_buffer = NULL;
5142 int pointer_buffer_mark_set = 0;
5143 switch(*desc)
5145 case RPC_FC_RP:
5146 case RPC_FC_UP:
5147 case RPC_FC_OP:
5148 case RPC_FC_FP:
5149 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5150 saved_buffer = pStubMsg->Buffer;
5151 if (pStubMsg->PointerBufferMark)
5153 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5154 pStubMsg->PointerBufferMark = NULL;
5155 pointer_buffer_mark_set = 1;
5157 else
5158 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5160 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5161 if (pointer_buffer_mark_set)
5163 STD_OVERFLOW_CHECK(pStubMsg);
5164 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5165 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5167 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5168 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5169 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5171 pStubMsg->Buffer = saved_buffer + 4;
5173 break;
5174 default:
5175 m(pStubMsg, pMemory, desc);
5178 else FIXME("no marshaller for embedded type %02x\n", *desc);
5180 return NULL;
5183 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5184 unsigned char **ppMemory,
5185 ULONG discriminant,
5186 PFORMAT_STRING pFormat,
5187 unsigned char fMustAlloc)
5189 unsigned short type;
5191 pFormat += 2;
5193 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5194 if(!pFormat)
5195 return NULL;
5197 type = *(const unsigned short*)pFormat;
5198 if((type & 0xff00) == 0x8000)
5200 unsigned char basetype = LOBYTE(type);
5201 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5203 else
5205 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5206 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5207 if (m)
5209 unsigned char *saved_buffer = NULL;
5210 int pointer_buffer_mark_set = 0;
5211 switch(*desc)
5213 case RPC_FC_RP:
5214 case RPC_FC_UP:
5215 case RPC_FC_OP:
5216 case RPC_FC_FP:
5217 **(void***)ppMemory = NULL;
5218 ALIGN_POINTER(pStubMsg->Buffer, 4);
5219 saved_buffer = pStubMsg->Buffer;
5220 if (pStubMsg->PointerBufferMark)
5222 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5223 pStubMsg->PointerBufferMark = NULL;
5224 pointer_buffer_mark_set = 1;
5226 else
5227 pStubMsg->Buffer += 4; /* for pointer ID */
5229 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5231 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5232 saved_buffer, pStubMsg->BufferEnd);
5233 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5236 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5237 if (pointer_buffer_mark_set)
5239 STD_OVERFLOW_CHECK(pStubMsg);
5240 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5241 pStubMsg->Buffer = saved_buffer + 4;
5243 break;
5244 default:
5245 m(pStubMsg, ppMemory, desc, fMustAlloc);
5248 else FIXME("no marshaller for embedded type %02x\n", *desc);
5250 return NULL;
5253 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5254 unsigned char *pMemory,
5255 ULONG discriminant,
5256 PFORMAT_STRING pFormat)
5258 unsigned short type;
5260 pFormat += 2;
5262 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5263 if(!pFormat)
5264 return;
5266 type = *(const unsigned short*)pFormat;
5267 if((type & 0xff00) == 0x8000)
5269 unsigned char basetype = LOBYTE(type);
5270 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5272 else
5274 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5275 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5276 if (m)
5278 switch(*desc)
5280 case RPC_FC_RP:
5281 case RPC_FC_UP:
5282 case RPC_FC_OP:
5283 case RPC_FC_FP:
5284 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5285 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5286 if (!pStubMsg->IgnoreEmbeddedPointers)
5288 int saved_buffer_length = pStubMsg->BufferLength;
5289 pStubMsg->BufferLength = pStubMsg->PointerLength;
5290 pStubMsg->PointerLength = 0;
5291 if(!pStubMsg->BufferLength)
5292 ERR("BufferLength == 0??\n");
5293 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5294 pStubMsg->PointerLength = pStubMsg->BufferLength;
5295 pStubMsg->BufferLength = saved_buffer_length;
5297 break;
5298 default:
5299 m(pStubMsg, pMemory, desc);
5302 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5306 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5307 ULONG discriminant,
5308 PFORMAT_STRING pFormat)
5310 unsigned short type, size;
5312 size = *(const unsigned short*)pFormat;
5313 pStubMsg->Memory += size;
5314 pFormat += 2;
5316 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5317 if(!pFormat)
5318 return 0;
5320 type = *(const unsigned short*)pFormat;
5321 if((type & 0xff00) == 0x8000)
5323 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5325 else
5327 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5328 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5329 unsigned char *saved_buffer;
5330 if (m)
5332 switch(*desc)
5334 case RPC_FC_RP:
5335 case RPC_FC_UP:
5336 case RPC_FC_OP:
5337 case RPC_FC_FP:
5338 ALIGN_POINTER(pStubMsg->Buffer, 4);
5339 saved_buffer = pStubMsg->Buffer;
5340 safe_buffer_increment(pStubMsg, 4);
5341 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5342 pStubMsg->MemorySize += 4;
5343 if (!pStubMsg->IgnoreEmbeddedPointers)
5344 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5345 break;
5346 default:
5347 return m(pStubMsg, desc);
5350 else FIXME("no marshaller for embedded type %02x\n", *desc);
5353 TRACE("size %d\n", size);
5354 return size;
5357 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5358 unsigned char *pMemory,
5359 ULONG discriminant,
5360 PFORMAT_STRING pFormat)
5362 unsigned short type;
5364 pFormat += 2;
5366 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5367 if(!pFormat)
5368 return;
5370 type = *(const unsigned short*)pFormat;
5371 if((type & 0xff00) != 0x8000)
5373 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5374 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5375 if (m)
5377 switch(*desc)
5379 case RPC_FC_RP:
5380 case RPC_FC_UP:
5381 case RPC_FC_OP:
5382 case RPC_FC_FP:
5383 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5384 break;
5385 default:
5386 m(pStubMsg, pMemory, desc);
5392 /***********************************************************************
5393 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5395 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5396 unsigned char *pMemory,
5397 PFORMAT_STRING pFormat)
5399 unsigned char switch_type;
5400 unsigned char increment;
5401 ULONG switch_value;
5403 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5404 pFormat++;
5406 switch_type = *pFormat & 0xf;
5407 increment = (*pFormat & 0xf0) >> 4;
5408 pFormat++;
5410 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5412 switch_value = get_discriminant(switch_type, pMemory);
5413 TRACE("got switch value 0x%x\n", switch_value);
5415 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5416 pMemory += increment;
5418 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5421 /***********************************************************************
5422 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5424 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5425 unsigned char **ppMemory,
5426 PFORMAT_STRING pFormat,
5427 unsigned char fMustAlloc)
5429 unsigned char switch_type;
5430 unsigned char increment;
5431 ULONG switch_value;
5432 unsigned short size;
5433 unsigned char *pMemoryArm;
5435 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5436 pFormat++;
5438 switch_type = *pFormat & 0xf;
5439 increment = (*pFormat & 0xf0) >> 4;
5440 pFormat++;
5442 ALIGN_POINTER(pStubMsg->Buffer, increment);
5443 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5444 TRACE("got switch value 0x%x\n", switch_value);
5446 size = *(const unsigned short*)pFormat + increment;
5447 if(!*ppMemory || fMustAlloc)
5448 *ppMemory = NdrAllocate(pStubMsg, size);
5450 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5451 pMemoryArm = *ppMemory + increment;
5453 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5456 /***********************************************************************
5457 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5459 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5460 unsigned char *pMemory,
5461 PFORMAT_STRING pFormat)
5463 unsigned char switch_type;
5464 unsigned char increment;
5465 ULONG switch_value;
5467 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5468 pFormat++;
5470 switch_type = *pFormat & 0xf;
5471 increment = (*pFormat & 0xf0) >> 4;
5472 pFormat++;
5474 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5475 switch_value = get_discriminant(switch_type, pMemory);
5476 TRACE("got switch value 0x%x\n", switch_value);
5478 /* Add discriminant size */
5479 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5480 pMemory += increment;
5482 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5485 /***********************************************************************
5486 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5488 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5489 PFORMAT_STRING pFormat)
5491 unsigned char switch_type;
5492 unsigned char increment;
5493 ULONG switch_value;
5495 switch_type = *pFormat & 0xf;
5496 increment = (*pFormat & 0xf0) >> 4;
5497 pFormat++;
5499 ALIGN_POINTER(pStubMsg->Buffer, increment);
5500 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5501 TRACE("got switch value 0x%x\n", switch_value);
5503 pStubMsg->Memory += increment;
5505 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5508 /***********************************************************************
5509 * NdrEncapsulatedUnionFree [RPCRT4.@]
5511 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5512 unsigned char *pMemory,
5513 PFORMAT_STRING pFormat)
5515 unsigned char switch_type;
5516 unsigned char increment;
5517 ULONG switch_value;
5519 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5520 pFormat++;
5522 switch_type = *pFormat & 0xf;
5523 increment = (*pFormat & 0xf0) >> 4;
5524 pFormat++;
5526 switch_value = get_discriminant(switch_type, pMemory);
5527 TRACE("got switch value 0x%x\n", switch_value);
5529 pMemory += increment;
5531 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5534 /***********************************************************************
5535 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5537 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5538 unsigned char *pMemory,
5539 PFORMAT_STRING pFormat)
5541 unsigned char switch_type;
5543 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5544 pFormat++;
5546 switch_type = *pFormat;
5547 pFormat++;
5549 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5550 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5551 /* Marshall discriminant */
5552 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5554 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5557 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5558 PFORMAT_STRING *ppFormat)
5560 long discriminant = 0;
5562 switch(**ppFormat)
5564 case RPC_FC_BYTE:
5565 case RPC_FC_CHAR:
5566 case RPC_FC_SMALL:
5567 case RPC_FC_USMALL:
5569 UCHAR d;
5570 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5571 discriminant = d;
5572 break;
5574 case RPC_FC_WCHAR:
5575 case RPC_FC_SHORT:
5576 case RPC_FC_USHORT:
5578 USHORT d;
5579 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5580 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5581 discriminant = d;
5582 break;
5584 case RPC_FC_LONG:
5585 case RPC_FC_ULONG:
5587 ULONG d;
5588 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5589 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5590 discriminant = d;
5591 break;
5593 default:
5594 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5596 (*ppFormat)++;
5598 if (pStubMsg->fHasNewCorrDesc)
5599 *ppFormat += 6;
5600 else
5601 *ppFormat += 4;
5602 return discriminant;
5605 /**********************************************************************
5606 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5608 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5609 unsigned char **ppMemory,
5610 PFORMAT_STRING pFormat,
5611 unsigned char fMustAlloc)
5613 long discriminant;
5614 unsigned short size;
5616 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5617 pFormat++;
5619 /* Unmarshall discriminant */
5620 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5621 TRACE("unmarshalled discriminant %lx\n", discriminant);
5623 pFormat += *(const SHORT*)pFormat;
5625 size = *(const unsigned short*)pFormat;
5627 if(!*ppMemory || fMustAlloc)
5628 *ppMemory = NdrAllocate(pStubMsg, size);
5630 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5633 /***********************************************************************
5634 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5636 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5637 unsigned char *pMemory,
5638 PFORMAT_STRING pFormat)
5640 unsigned char switch_type;
5642 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5643 pFormat++;
5645 switch_type = *pFormat;
5646 pFormat++;
5648 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5649 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5650 /* Add discriminant size */
5651 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5653 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5656 /***********************************************************************
5657 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5659 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5660 PFORMAT_STRING pFormat)
5662 ULONG discriminant;
5664 pFormat++;
5665 /* Unmarshall discriminant */
5666 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5667 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5669 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5672 /***********************************************************************
5673 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5675 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5676 unsigned char *pMemory,
5677 PFORMAT_STRING pFormat)
5679 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5680 pFormat++;
5681 pFormat++;
5683 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5684 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5686 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5689 /***********************************************************************
5690 * NdrByteCountPointerMarshall [RPCRT4.@]
5692 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5693 unsigned char *pMemory,
5694 PFORMAT_STRING pFormat)
5696 FIXME("stub\n");
5697 return NULL;
5700 /***********************************************************************
5701 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5703 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5704 unsigned char **ppMemory,
5705 PFORMAT_STRING pFormat,
5706 unsigned char fMustAlloc)
5708 FIXME("stub\n");
5709 return NULL;
5712 /***********************************************************************
5713 * NdrByteCountPointerBufferSize [RPCRT4.@]
5715 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5716 unsigned char *pMemory,
5717 PFORMAT_STRING pFormat)
5719 FIXME("stub\n");
5722 /***********************************************************************
5723 * NdrByteCountPointerMemorySize [RPCRT4.@]
5725 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5726 PFORMAT_STRING pFormat)
5728 FIXME("stub\n");
5729 return 0;
5732 /***********************************************************************
5733 * NdrByteCountPointerFree [RPCRT4.@]
5735 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5736 unsigned char *pMemory,
5737 PFORMAT_STRING pFormat)
5739 FIXME("stub\n");
5742 /***********************************************************************
5743 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5745 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5746 unsigned char *pMemory,
5747 PFORMAT_STRING pFormat)
5749 FIXME("stub\n");
5750 return NULL;
5753 /***********************************************************************
5754 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5756 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5757 unsigned char **ppMemory,
5758 PFORMAT_STRING pFormat,
5759 unsigned char fMustAlloc)
5761 FIXME("stub\n");
5762 return NULL;
5765 /***********************************************************************
5766 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5768 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5769 unsigned char *pMemory,
5770 PFORMAT_STRING pFormat)
5772 FIXME("stub\n");
5775 /***********************************************************************
5776 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5778 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5779 PFORMAT_STRING pFormat)
5781 FIXME("stub\n");
5782 return 0;
5785 /***********************************************************************
5786 * NdrXmitOrRepAsFree [RPCRT4.@]
5788 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5789 unsigned char *pMemory,
5790 PFORMAT_STRING pFormat)
5792 FIXME("stub\n");
5795 #include "pshpack1.h"
5796 typedef struct
5798 unsigned char type;
5799 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5800 ULONG low_value;
5801 ULONG high_value;
5802 } NDR_RANGE;
5803 #include "poppack.h"
5805 /***********************************************************************
5806 * NdrRangeMarshall [internal]
5808 unsigned char *WINAPI NdrRangeMarshall(
5809 PMIDL_STUB_MESSAGE pStubMsg,
5810 unsigned char *pMemory,
5811 PFORMAT_STRING pFormat)
5813 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5814 unsigned char base_type;
5816 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5818 if (pRange->type != RPC_FC_RANGE)
5820 ERR("invalid format type %x\n", pRange->type);
5821 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5822 return NULL;
5825 base_type = pRange->flags_type & 0xf;
5827 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5830 /***********************************************************************
5831 * NdrRangeUnmarshall
5833 unsigned char *WINAPI NdrRangeUnmarshall(
5834 PMIDL_STUB_MESSAGE pStubMsg,
5835 unsigned char **ppMemory,
5836 PFORMAT_STRING pFormat,
5837 unsigned char fMustAlloc)
5839 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5840 unsigned char base_type;
5842 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5844 if (pRange->type != RPC_FC_RANGE)
5846 ERR("invalid format type %x\n", pRange->type);
5847 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5848 return NULL;
5850 base_type = pRange->flags_type & 0xf;
5852 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5853 base_type, pRange->low_value, pRange->high_value);
5855 #define RANGE_UNMARSHALL(type, format_spec) \
5856 do \
5858 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5859 if (fMustAlloc || !*ppMemory) \
5860 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5861 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5863 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5864 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5865 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5867 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5868 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5870 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5871 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5872 (type)pRange->high_value); \
5873 RpcRaiseException(RPC_S_INVALID_BOUND); \
5874 return NULL; \
5876 TRACE("*ppMemory: %p\n", *ppMemory); \
5877 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5878 pStubMsg->Buffer += sizeof(type); \
5879 } while (0)
5881 switch(base_type)
5883 case RPC_FC_CHAR:
5884 case RPC_FC_SMALL:
5885 RANGE_UNMARSHALL(UCHAR, "%d");
5886 TRACE("value: 0x%02x\n", **ppMemory);
5887 break;
5888 case RPC_FC_BYTE:
5889 case RPC_FC_USMALL:
5890 RANGE_UNMARSHALL(CHAR, "%u");
5891 TRACE("value: 0x%02x\n", **ppMemory);
5892 break;
5893 case RPC_FC_WCHAR: /* FIXME: valid? */
5894 case RPC_FC_USHORT:
5895 RANGE_UNMARSHALL(USHORT, "%u");
5896 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5897 break;
5898 case RPC_FC_SHORT:
5899 RANGE_UNMARSHALL(SHORT, "%d");
5900 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5901 break;
5902 case RPC_FC_LONG:
5903 RANGE_UNMARSHALL(LONG, "%d");
5904 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5905 break;
5906 case RPC_FC_ULONG:
5907 RANGE_UNMARSHALL(ULONG, "%u");
5908 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5909 break;
5910 case RPC_FC_ENUM16:
5911 case RPC_FC_ENUM32:
5912 FIXME("Unhandled enum type\n");
5913 break;
5914 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5915 case RPC_FC_FLOAT:
5916 case RPC_FC_DOUBLE:
5917 case RPC_FC_HYPER:
5918 default:
5919 ERR("invalid range base type: 0x%02x\n", base_type);
5920 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5923 return NULL;
5926 /***********************************************************************
5927 * NdrRangeBufferSize [internal]
5929 void WINAPI NdrRangeBufferSize(
5930 PMIDL_STUB_MESSAGE pStubMsg,
5931 unsigned char *pMemory,
5932 PFORMAT_STRING pFormat)
5934 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5935 unsigned char base_type;
5937 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5939 if (pRange->type != RPC_FC_RANGE)
5941 ERR("invalid format type %x\n", pRange->type);
5942 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5944 base_type = pRange->flags_type & 0xf;
5946 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5949 /***********************************************************************
5950 * NdrRangeMemorySize [internal]
5952 ULONG WINAPI NdrRangeMemorySize(
5953 PMIDL_STUB_MESSAGE pStubMsg,
5954 PFORMAT_STRING pFormat)
5956 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5957 unsigned char base_type;
5959 if (pRange->type != RPC_FC_RANGE)
5961 ERR("invalid format type %x\n", pRange->type);
5962 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5963 return 0;
5965 base_type = pRange->flags_type & 0xf;
5967 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5970 /***********************************************************************
5971 * NdrRangeFree [internal]
5973 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5974 unsigned char *pMemory,
5975 PFORMAT_STRING pFormat)
5977 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5979 /* nothing to do */
5982 /***********************************************************************
5983 * NdrBaseTypeMarshall [internal]
5985 static unsigned char *WINAPI NdrBaseTypeMarshall(
5986 PMIDL_STUB_MESSAGE pStubMsg,
5987 unsigned char *pMemory,
5988 PFORMAT_STRING pFormat)
5990 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5992 switch(*pFormat)
5994 case RPC_FC_BYTE:
5995 case RPC_FC_CHAR:
5996 case RPC_FC_SMALL:
5997 case RPC_FC_USMALL:
5998 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5999 TRACE("value: 0x%02x\n", *pMemory);
6000 break;
6001 case RPC_FC_WCHAR:
6002 case RPC_FC_SHORT:
6003 case RPC_FC_USHORT:
6004 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6005 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6006 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6007 break;
6008 case RPC_FC_LONG:
6009 case RPC_FC_ULONG:
6010 case RPC_FC_ERROR_STATUS_T:
6011 case RPC_FC_ENUM32:
6012 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6013 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6014 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6015 break;
6016 case RPC_FC_FLOAT:
6017 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6018 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6019 break;
6020 case RPC_FC_DOUBLE:
6021 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6022 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6023 break;
6024 case RPC_FC_HYPER:
6025 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6026 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6027 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6028 break;
6029 case RPC_FC_ENUM16:
6030 /* only 16-bits on the wire, so do a sanity check */
6031 if (*(UINT *)pMemory > SHRT_MAX)
6032 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6033 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6034 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6035 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6036 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6037 pStubMsg->Buffer += sizeof(USHORT);
6038 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6039 break;
6040 case RPC_FC_IGNORE:
6041 break;
6042 default:
6043 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6046 /* FIXME: what is the correct return value? */
6047 return NULL;
6050 /***********************************************************************
6051 * NdrBaseTypeUnmarshall [internal]
6053 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6054 PMIDL_STUB_MESSAGE pStubMsg,
6055 unsigned char **ppMemory,
6056 PFORMAT_STRING pFormat,
6057 unsigned char fMustAlloc)
6059 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6061 #define BASE_TYPE_UNMARSHALL(type) \
6062 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6063 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6065 *ppMemory = pStubMsg->Buffer; \
6066 TRACE("*ppMemory: %p\n", *ppMemory); \
6068 else \
6070 if (fMustAlloc) \
6071 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6072 TRACE("*ppMemory: %p\n", *ppMemory); \
6073 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6075 safe_buffer_increment(pStubMsg, sizeof(type));
6077 switch(*pFormat)
6079 case RPC_FC_BYTE:
6080 case RPC_FC_CHAR:
6081 case RPC_FC_SMALL:
6082 case RPC_FC_USMALL:
6083 BASE_TYPE_UNMARSHALL(UCHAR);
6084 TRACE("value: 0x%02x\n", **ppMemory);
6085 break;
6086 case RPC_FC_WCHAR:
6087 case RPC_FC_SHORT:
6088 case RPC_FC_USHORT:
6089 BASE_TYPE_UNMARSHALL(USHORT);
6090 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6091 break;
6092 case RPC_FC_LONG:
6093 case RPC_FC_ULONG:
6094 case RPC_FC_ERROR_STATUS_T:
6095 case RPC_FC_ENUM32:
6096 BASE_TYPE_UNMARSHALL(ULONG);
6097 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6098 break;
6099 case RPC_FC_FLOAT:
6100 BASE_TYPE_UNMARSHALL(float);
6101 TRACE("value: %f\n", **(float **)ppMemory);
6102 break;
6103 case RPC_FC_DOUBLE:
6104 BASE_TYPE_UNMARSHALL(double);
6105 TRACE("value: %f\n", **(double **)ppMemory);
6106 break;
6107 case RPC_FC_HYPER:
6108 BASE_TYPE_UNMARSHALL(ULONGLONG);
6109 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6110 break;
6111 case RPC_FC_ENUM16:
6112 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6113 if (fMustAlloc || !*ppMemory)
6114 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6115 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6116 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6117 TRACE("*ppMemory: %p\n", *ppMemory);
6118 /* 16-bits on the wire, but int in memory */
6119 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6120 pStubMsg->Buffer += sizeof(USHORT);
6121 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6122 break;
6123 case RPC_FC_IGNORE:
6124 break;
6125 default:
6126 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6128 #undef BASE_TYPE_UNMARSHALL
6130 /* FIXME: what is the correct return value? */
6132 return NULL;
6135 /***********************************************************************
6136 * NdrBaseTypeBufferSize [internal]
6138 static void WINAPI NdrBaseTypeBufferSize(
6139 PMIDL_STUB_MESSAGE pStubMsg,
6140 unsigned char *pMemory,
6141 PFORMAT_STRING pFormat)
6143 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6145 switch(*pFormat)
6147 case RPC_FC_BYTE:
6148 case RPC_FC_CHAR:
6149 case RPC_FC_SMALL:
6150 case RPC_FC_USMALL:
6151 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6152 break;
6153 case RPC_FC_WCHAR:
6154 case RPC_FC_SHORT:
6155 case RPC_FC_USHORT:
6156 case RPC_FC_ENUM16:
6157 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6158 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6159 break;
6160 case RPC_FC_LONG:
6161 case RPC_FC_ULONG:
6162 case RPC_FC_ENUM32:
6163 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6164 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6165 break;
6166 case RPC_FC_FLOAT:
6167 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6168 safe_buffer_length_increment(pStubMsg, sizeof(float));
6169 break;
6170 case RPC_FC_DOUBLE:
6171 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6172 safe_buffer_length_increment(pStubMsg, sizeof(double));
6173 break;
6174 case RPC_FC_HYPER:
6175 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6176 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6177 break;
6178 case RPC_FC_ERROR_STATUS_T:
6179 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6180 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6181 break;
6182 case RPC_FC_IGNORE:
6183 break;
6184 default:
6185 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6189 /***********************************************************************
6190 * NdrBaseTypeMemorySize [internal]
6192 static ULONG WINAPI NdrBaseTypeMemorySize(
6193 PMIDL_STUB_MESSAGE pStubMsg,
6194 PFORMAT_STRING pFormat)
6196 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6198 switch(*pFormat)
6200 case RPC_FC_BYTE:
6201 case RPC_FC_CHAR:
6202 case RPC_FC_SMALL:
6203 case RPC_FC_USMALL:
6204 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6205 pStubMsg->MemorySize += sizeof(UCHAR);
6206 return sizeof(UCHAR);
6207 case RPC_FC_WCHAR:
6208 case RPC_FC_SHORT:
6209 case RPC_FC_USHORT:
6210 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6211 pStubMsg->MemorySize += sizeof(USHORT);
6212 return sizeof(USHORT);
6213 case RPC_FC_LONG:
6214 case RPC_FC_ULONG:
6215 case RPC_FC_ENUM32:
6216 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6217 pStubMsg->MemorySize += sizeof(ULONG);
6218 return sizeof(ULONG);
6219 case RPC_FC_FLOAT:
6220 safe_buffer_increment(pStubMsg, sizeof(float));
6221 pStubMsg->MemorySize += sizeof(float);
6222 return sizeof(float);
6223 case RPC_FC_DOUBLE:
6224 safe_buffer_increment(pStubMsg, sizeof(double));
6225 pStubMsg->MemorySize += sizeof(double);
6226 return sizeof(double);
6227 case RPC_FC_HYPER:
6228 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6229 pStubMsg->MemorySize += sizeof(ULONGLONG);
6230 return sizeof(ULONGLONG);
6231 case RPC_FC_ERROR_STATUS_T:
6232 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6233 pStubMsg->MemorySize += sizeof(error_status_t);
6234 return sizeof(error_status_t);
6235 case RPC_FC_ENUM16:
6236 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6237 pStubMsg->MemorySize += sizeof(UINT);
6238 return sizeof(UINT);
6239 case RPC_FC_IGNORE:
6240 pStubMsg->MemorySize += sizeof(void *);
6241 return sizeof(void *);
6242 default:
6243 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6244 return 0;
6248 /***********************************************************************
6249 * NdrBaseTypeFree [internal]
6251 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6252 unsigned char *pMemory,
6253 PFORMAT_STRING pFormat)
6255 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6257 /* nothing to do */
6260 /***********************************************************************
6261 * NdrContextHandleBufferSize [internal]
6263 static void WINAPI NdrContextHandleBufferSize(
6264 PMIDL_STUB_MESSAGE pStubMsg,
6265 unsigned char *pMemory,
6266 PFORMAT_STRING pFormat)
6268 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6270 if (*pFormat != RPC_FC_BIND_CONTEXT)
6272 ERR("invalid format type %x\n", *pFormat);
6273 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6275 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6276 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6279 /***********************************************************************
6280 * NdrContextHandleMarshall [internal]
6282 static unsigned char *WINAPI NdrContextHandleMarshall(
6283 PMIDL_STUB_MESSAGE pStubMsg,
6284 unsigned char *pMemory,
6285 PFORMAT_STRING pFormat)
6287 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6289 if (*pFormat != RPC_FC_BIND_CONTEXT)
6291 ERR("invalid format type %x\n", *pFormat);
6292 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6294 TRACE("flags: 0x%02x\n", pFormat[1]);
6296 if (pFormat[1] & 0x80)
6297 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6298 else
6299 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6301 return NULL;
6304 /***********************************************************************
6305 * NdrContextHandleUnmarshall [internal]
6307 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6308 PMIDL_STUB_MESSAGE pStubMsg,
6309 unsigned char **ppMemory,
6310 PFORMAT_STRING pFormat,
6311 unsigned char fMustAlloc)
6313 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6314 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6316 if (*pFormat != RPC_FC_BIND_CONTEXT)
6318 ERR("invalid format type %x\n", *pFormat);
6319 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6321 TRACE("flags: 0x%02x\n", pFormat[1]);
6323 /* [out]-only or [ret] param */
6324 if ((pFormat[1] & 0x60) == 0x20)
6325 **(NDR_CCONTEXT **)ppMemory = NULL;
6326 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6328 return NULL;
6331 /***********************************************************************
6332 * NdrClientContextMarshall [RPCRT4.@]
6334 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6335 NDR_CCONTEXT ContextHandle,
6336 int fCheck)
6338 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6340 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6342 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6344 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6345 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6346 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6349 /* FIXME: what does fCheck do? */
6350 NDRCContextMarshall(ContextHandle,
6351 pStubMsg->Buffer);
6353 pStubMsg->Buffer += cbNDRContext;
6356 /***********************************************************************
6357 * NdrClientContextUnmarshall [RPCRT4.@]
6359 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6360 NDR_CCONTEXT * pContextHandle,
6361 RPC_BINDING_HANDLE BindHandle)
6363 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6365 ALIGN_POINTER(pStubMsg->Buffer, 4);
6367 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6368 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6370 NDRCContextUnmarshall(pContextHandle,
6371 BindHandle,
6372 pStubMsg->Buffer,
6373 pStubMsg->RpcMsg->DataRepresentation);
6375 pStubMsg->Buffer += cbNDRContext;
6378 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6379 NDR_SCONTEXT ContextHandle,
6380 NDR_RUNDOWN RundownRoutine )
6382 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6384 ALIGN_POINTER(pStubMsg->Buffer, 4);
6386 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6388 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6389 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6390 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6393 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6394 pStubMsg->Buffer, RundownRoutine, NULL,
6395 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6396 pStubMsg->Buffer += cbNDRContext;
6399 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6401 NDR_SCONTEXT ContextHandle;
6403 TRACE("(%p)\n", pStubMsg);
6405 ALIGN_POINTER(pStubMsg->Buffer, 4);
6407 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6409 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6410 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6411 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6414 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6415 pStubMsg->Buffer,
6416 pStubMsg->RpcMsg->DataRepresentation,
6417 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6418 pStubMsg->Buffer += cbNDRContext;
6420 return ContextHandle;
6423 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6424 unsigned char* pMemory,
6425 PFORMAT_STRING pFormat)
6427 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6430 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6431 PFORMAT_STRING pFormat)
6433 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6434 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6436 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6438 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6439 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6440 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6441 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6442 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6444 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6445 if_id = &sif->InterfaceId;
6448 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6449 pStubMsg->RpcMsg->DataRepresentation, if_id,
6450 flags);
6453 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6454 NDR_SCONTEXT ContextHandle,
6455 NDR_RUNDOWN RundownRoutine,
6456 PFORMAT_STRING pFormat)
6458 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6459 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6461 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6463 ALIGN_POINTER(pStubMsg->Buffer, 4);
6465 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6467 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6468 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6469 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6472 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6473 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6474 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6475 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6476 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6478 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6479 if_id = &sif->InterfaceId;
6482 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6483 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6484 pStubMsg->Buffer += cbNDRContext;
6487 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6488 PFORMAT_STRING pFormat)
6490 NDR_SCONTEXT ContextHandle;
6491 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6492 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6494 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6496 ALIGN_POINTER(pStubMsg->Buffer, 4);
6498 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6500 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6501 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6502 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6505 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6506 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6507 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6508 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6509 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6511 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6512 if_id = &sif->InterfaceId;
6515 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6516 pStubMsg->Buffer,
6517 pStubMsg->RpcMsg->DataRepresentation,
6518 if_id, flags);
6519 pStubMsg->Buffer += cbNDRContext;
6521 return ContextHandle;
6524 /***********************************************************************
6525 * NdrCorrelationInitialize [RPCRT4.@]
6527 * Initializes correlation validity checking.
6529 * PARAMS
6530 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6531 * pMemory [I] Pointer to memory to use as a cache.
6532 * CacheSize [I] Size of the memory pointed to by pMemory.
6533 * Flags [I] Reserved. Set to zero.
6535 * RETURNS
6536 * Nothing.
6538 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6540 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6541 pStubMsg->fHasNewCorrDesc = TRUE;
6544 /***********************************************************************
6545 * NdrCorrelationPass [RPCRT4.@]
6547 * Performs correlation validity checking.
6549 * PARAMS
6550 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6552 * RETURNS
6553 * Nothing.
6555 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6557 FIXME("(%p): stub\n", pStubMsg);
6560 /***********************************************************************
6561 * NdrCorrelationFree [RPCRT4.@]
6563 * Frees any resources used while unmarshalling parameters that need
6564 * correlation validity checking.
6566 * PARAMS
6567 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6569 * RETURNS
6570 * Nothing.
6572 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6574 FIXME("(%p): stub\n", pStubMsg);