fusion: Implement CreateAssemblyCache.
[wine.git] / dlls / rpcrt4 / ndr_marshall.c
blob42aebf0edd0723267892dd8308fe85743f15c04f
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 base type and 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 /* incremement 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 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
2008 unsigned char FormatChar )
2010 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
2013 /***********************************************************************
2014 * NdrSimpleStructMarshall [RPCRT4.@]
2016 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2017 unsigned char *pMemory,
2018 PFORMAT_STRING pFormat)
2020 unsigned size = *(const WORD*)(pFormat+2);
2021 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2023 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2025 pStubMsg->BufferMark = pStubMsg->Buffer;
2026 safe_copy_to_buffer(pStubMsg, pMemory, size);
2028 if (pFormat[0] != RPC_FC_STRUCT)
2029 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
2031 return NULL;
2034 /***********************************************************************
2035 * NdrSimpleStructUnmarshall [RPCRT4.@]
2037 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2038 unsigned char **ppMemory,
2039 PFORMAT_STRING pFormat,
2040 unsigned char fMustAlloc)
2042 unsigned size = *(const WORD*)(pFormat+2);
2043 unsigned char *saved_buffer;
2044 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2046 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2048 if (fMustAlloc)
2049 *ppMemory = NdrAllocate(pStubMsg, size);
2050 else
2052 if (!pStubMsg->IsClient && !*ppMemory)
2053 /* for servers, we just point straight into the RPC buffer */
2054 *ppMemory = pStubMsg->Buffer;
2057 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2058 safe_buffer_increment(pStubMsg, size);
2059 if (pFormat[0] == RPC_FC_PSTRUCT)
2060 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
2062 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2063 if (*ppMemory != saved_buffer)
2064 memcpy(*ppMemory, saved_buffer, size);
2066 return NULL;
2069 /***********************************************************************
2070 * NdrSimpleStructBufferSize [RPCRT4.@]
2072 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2073 unsigned char *pMemory,
2074 PFORMAT_STRING pFormat)
2076 unsigned size = *(const WORD*)(pFormat+2);
2077 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2079 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2081 safe_buffer_length_increment(pStubMsg, size);
2082 if (pFormat[0] != RPC_FC_STRUCT)
2083 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
2086 /***********************************************************************
2087 * NdrSimpleStructMemorySize [RPCRT4.@]
2089 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2090 PFORMAT_STRING pFormat)
2092 unsigned short size = *(const WORD *)(pFormat+2);
2094 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2096 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2097 pStubMsg->MemorySize += size;
2098 safe_buffer_increment(pStubMsg, size);
2100 if (pFormat[0] != RPC_FC_STRUCT)
2101 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
2102 return pStubMsg->MemorySize;
2105 /***********************************************************************
2106 * NdrSimpleStructFree [RPCRT4.@]
2108 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2109 unsigned char *pMemory,
2110 PFORMAT_STRING pFormat)
2112 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2113 if (pFormat[0] != RPC_FC_STRUCT)
2114 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
2118 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
2119 PFORMAT_STRING pFormat)
2121 switch (*pFormat) {
2122 case RPC_FC_STRUCT:
2123 case RPC_FC_PSTRUCT:
2124 case RPC_FC_CSTRUCT:
2125 case RPC_FC_BOGUS_STRUCT:
2126 case RPC_FC_SMFARRAY:
2127 case RPC_FC_SMVARRAY:
2128 case RPC_FC_CSTRING:
2129 return *(const WORD*)&pFormat[2];
2130 case RPC_FC_USER_MARSHAL:
2131 return *(const WORD*)&pFormat[4];
2132 case RPC_FC_NON_ENCAPSULATED_UNION:
2133 pFormat += 2;
2134 if (pStubMsg->fHasNewCorrDesc)
2135 pFormat += 6;
2136 else
2137 pFormat += 4;
2139 pFormat += *(const SHORT*)pFormat;
2140 return *(const SHORT*)pFormat;
2141 case RPC_FC_IP:
2142 return sizeof(void *);
2143 case RPC_FC_WSTRING:
2144 return *(const WORD*)&pFormat[2] * 2;
2145 default:
2146 FIXME("unhandled embedded type %02x\n", *pFormat);
2148 return 0;
2152 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2153 PFORMAT_STRING pFormat)
2155 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2157 if (!m)
2159 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2160 return 0;
2163 return m(pStubMsg, pFormat);
2167 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2168 unsigned char *pMemory,
2169 PFORMAT_STRING pFormat,
2170 PFORMAT_STRING pPointer)
2172 PFORMAT_STRING desc;
2173 NDR_MARSHALL m;
2174 unsigned long size;
2176 while (*pFormat != RPC_FC_END) {
2177 switch (*pFormat) {
2178 case RPC_FC_BYTE:
2179 case RPC_FC_CHAR:
2180 case RPC_FC_SMALL:
2181 case RPC_FC_USMALL:
2182 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2183 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2184 pMemory += 1;
2185 break;
2186 case RPC_FC_WCHAR:
2187 case RPC_FC_SHORT:
2188 case RPC_FC_USHORT:
2189 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2190 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2191 pMemory += 2;
2192 break;
2193 case RPC_FC_ENUM16:
2194 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2195 if (32767 < *(DWORD*)pMemory)
2196 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2197 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2198 pMemory += 4;
2199 break;
2200 case RPC_FC_LONG:
2201 case RPC_FC_ULONG:
2202 case RPC_FC_ENUM32:
2203 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2204 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2205 pMemory += 4;
2206 break;
2207 case RPC_FC_HYPER:
2208 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2209 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2210 pMemory += 8;
2211 break;
2212 case RPC_FC_POINTER:
2214 unsigned char *saved_buffer;
2215 int pointer_buffer_mark_set = 0;
2216 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2217 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2218 saved_buffer = pStubMsg->Buffer;
2219 if (pStubMsg->PointerBufferMark)
2221 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2222 pStubMsg->PointerBufferMark = NULL;
2223 pointer_buffer_mark_set = 1;
2225 else
2226 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2227 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2228 if (pointer_buffer_mark_set)
2230 STD_OVERFLOW_CHECK(pStubMsg);
2231 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2232 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2234 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2235 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2236 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2238 pStubMsg->Buffer = saved_buffer + 4;
2240 pPointer += 4;
2241 pMemory += 4;
2242 break;
2244 case RPC_FC_ALIGNM4:
2245 ALIGN_POINTER(pMemory, 4);
2246 break;
2247 case RPC_FC_ALIGNM8:
2248 ALIGN_POINTER(pMemory, 8);
2249 break;
2250 case RPC_FC_STRUCTPAD1:
2251 case RPC_FC_STRUCTPAD2:
2252 case RPC_FC_STRUCTPAD3:
2253 case RPC_FC_STRUCTPAD4:
2254 case RPC_FC_STRUCTPAD5:
2255 case RPC_FC_STRUCTPAD6:
2256 case RPC_FC_STRUCTPAD7:
2257 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2258 break;
2259 case RPC_FC_EMBEDDED_COMPLEX:
2260 pMemory += pFormat[1];
2261 pFormat += 2;
2262 desc = pFormat + *(const SHORT*)pFormat;
2263 size = EmbeddedComplexSize(pStubMsg, desc);
2264 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2265 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2266 if (m)
2268 /* for some reason interface pointers aren't generated as
2269 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2270 * they still need the derefencing treatment that pointers are
2271 * given */
2272 if (*desc == RPC_FC_IP)
2273 m(pStubMsg, *(unsigned char **)pMemory, desc);
2274 else
2275 m(pStubMsg, pMemory, desc);
2277 else FIXME("no marshaller for embedded type %02x\n", *desc);
2278 pMemory += size;
2279 pFormat += 2;
2280 continue;
2281 case RPC_FC_PAD:
2282 break;
2283 default:
2284 FIXME("unhandled format 0x%02x\n", *pFormat);
2286 pFormat++;
2289 return pMemory;
2292 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2293 unsigned char *pMemory,
2294 PFORMAT_STRING pFormat,
2295 PFORMAT_STRING pPointer)
2297 PFORMAT_STRING desc;
2298 NDR_UNMARSHALL m;
2299 unsigned long size;
2301 while (*pFormat != RPC_FC_END) {
2302 switch (*pFormat) {
2303 case RPC_FC_BYTE:
2304 case RPC_FC_CHAR:
2305 case RPC_FC_SMALL:
2306 case RPC_FC_USMALL:
2307 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2308 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2309 pMemory += 1;
2310 break;
2311 case RPC_FC_WCHAR:
2312 case RPC_FC_SHORT:
2313 case RPC_FC_USHORT:
2314 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2315 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2316 pMemory += 2;
2317 break;
2318 case RPC_FC_ENUM16:
2319 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2320 *(DWORD*)pMemory &= 0xffff;
2321 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2322 if (32767 < *(DWORD*)pMemory)
2323 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2324 pMemory += 4;
2325 break;
2326 case RPC_FC_LONG:
2327 case RPC_FC_ULONG:
2328 case RPC_FC_ENUM32:
2329 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2330 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2331 pMemory += 4;
2332 break;
2333 case RPC_FC_HYPER:
2334 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2335 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2336 pMemory += 8;
2337 break;
2338 case RPC_FC_POINTER:
2340 unsigned char *saved_buffer;
2341 int pointer_buffer_mark_set = 0;
2342 TRACE("pointer => %p\n", pMemory);
2343 ALIGN_POINTER(pStubMsg->Buffer, 4);
2344 saved_buffer = pStubMsg->Buffer;
2345 if (pStubMsg->PointerBufferMark)
2347 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2348 pStubMsg->PointerBufferMark = NULL;
2349 pointer_buffer_mark_set = 1;
2351 else
2352 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2354 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2355 if (pointer_buffer_mark_set)
2357 STD_OVERFLOW_CHECK(pStubMsg);
2358 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2359 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2361 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2362 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2363 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2365 pStubMsg->Buffer = saved_buffer + 4;
2367 pPointer += 4;
2368 pMemory += 4;
2369 break;
2371 case RPC_FC_ALIGNM4:
2372 ALIGN_POINTER_CLEAR(pMemory, 4);
2373 break;
2374 case RPC_FC_ALIGNM8:
2375 ALIGN_POINTER_CLEAR(pMemory, 8);
2376 break;
2377 case RPC_FC_STRUCTPAD1:
2378 case RPC_FC_STRUCTPAD2:
2379 case RPC_FC_STRUCTPAD3:
2380 case RPC_FC_STRUCTPAD4:
2381 case RPC_FC_STRUCTPAD5:
2382 case RPC_FC_STRUCTPAD6:
2383 case RPC_FC_STRUCTPAD7:
2384 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2385 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2386 break;
2387 case RPC_FC_EMBEDDED_COMPLEX:
2388 pMemory += pFormat[1];
2389 pFormat += 2;
2390 desc = pFormat + *(const SHORT*)pFormat;
2391 size = EmbeddedComplexSize(pStubMsg, desc);
2392 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2393 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2394 memset(pMemory, 0, size); /* just in case */
2395 if (m)
2397 /* for some reason interface pointers aren't generated as
2398 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2399 * they still need the derefencing treatment that pointers are
2400 * given */
2401 if (*desc == RPC_FC_IP)
2402 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2403 else
2404 m(pStubMsg, &pMemory, desc, FALSE);
2406 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2407 pMemory += size;
2408 pFormat += 2;
2409 continue;
2410 case RPC_FC_PAD:
2411 break;
2412 default:
2413 FIXME("unhandled format %d\n", *pFormat);
2415 pFormat++;
2418 return pMemory;
2421 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2422 unsigned char *pMemory,
2423 PFORMAT_STRING pFormat,
2424 PFORMAT_STRING pPointer)
2426 PFORMAT_STRING desc;
2427 NDR_BUFFERSIZE m;
2428 unsigned long size;
2430 while (*pFormat != RPC_FC_END) {
2431 switch (*pFormat) {
2432 case RPC_FC_BYTE:
2433 case RPC_FC_CHAR:
2434 case RPC_FC_SMALL:
2435 case RPC_FC_USMALL:
2436 safe_buffer_length_increment(pStubMsg, 1);
2437 pMemory += 1;
2438 break;
2439 case RPC_FC_WCHAR:
2440 case RPC_FC_SHORT:
2441 case RPC_FC_USHORT:
2442 safe_buffer_length_increment(pStubMsg, 2);
2443 pMemory += 2;
2444 break;
2445 case RPC_FC_ENUM16:
2446 safe_buffer_length_increment(pStubMsg, 2);
2447 pMemory += 4;
2448 break;
2449 case RPC_FC_LONG:
2450 case RPC_FC_ULONG:
2451 case RPC_FC_ENUM32:
2452 safe_buffer_length_increment(pStubMsg, 4);
2453 pMemory += 4;
2454 break;
2455 case RPC_FC_HYPER:
2456 safe_buffer_length_increment(pStubMsg, 8);
2457 pMemory += 8;
2458 break;
2459 case RPC_FC_POINTER:
2460 if (!pStubMsg->IgnoreEmbeddedPointers)
2462 int saved_buffer_length = pStubMsg->BufferLength;
2463 pStubMsg->BufferLength = pStubMsg->PointerLength;
2464 pStubMsg->PointerLength = 0;
2465 if(!pStubMsg->BufferLength)
2466 ERR("BufferLength == 0??\n");
2467 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2468 pStubMsg->PointerLength = pStubMsg->BufferLength;
2469 pStubMsg->BufferLength = saved_buffer_length;
2471 safe_buffer_length_increment(pStubMsg, 4);
2472 pPointer += 4;
2473 pMemory += 4;
2474 break;
2475 case RPC_FC_ALIGNM4:
2476 ALIGN_POINTER(pMemory, 4);
2477 break;
2478 case RPC_FC_ALIGNM8:
2479 ALIGN_POINTER(pMemory, 8);
2480 break;
2481 case RPC_FC_STRUCTPAD1:
2482 case RPC_FC_STRUCTPAD2:
2483 case RPC_FC_STRUCTPAD3:
2484 case RPC_FC_STRUCTPAD4:
2485 case RPC_FC_STRUCTPAD5:
2486 case RPC_FC_STRUCTPAD6:
2487 case RPC_FC_STRUCTPAD7:
2488 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2489 break;
2490 case RPC_FC_EMBEDDED_COMPLEX:
2491 pMemory += pFormat[1];
2492 pFormat += 2;
2493 desc = pFormat + *(const SHORT*)pFormat;
2494 size = EmbeddedComplexSize(pStubMsg, desc);
2495 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2496 if (m)
2498 /* for some reason interface pointers aren't generated as
2499 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2500 * they still need the derefencing treatment that pointers are
2501 * given */
2502 if (*desc == RPC_FC_IP)
2503 m(pStubMsg, *(unsigned char **)pMemory, desc);
2504 else
2505 m(pStubMsg, pMemory, desc);
2507 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2508 pMemory += size;
2509 pFormat += 2;
2510 continue;
2511 case RPC_FC_PAD:
2512 break;
2513 default:
2514 FIXME("unhandled format 0x%02x\n", *pFormat);
2516 pFormat++;
2519 return pMemory;
2522 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2523 unsigned char *pMemory,
2524 PFORMAT_STRING pFormat,
2525 PFORMAT_STRING pPointer)
2527 PFORMAT_STRING desc;
2528 NDR_FREE m;
2529 unsigned long size;
2531 while (*pFormat != RPC_FC_END) {
2532 switch (*pFormat) {
2533 case RPC_FC_BYTE:
2534 case RPC_FC_CHAR:
2535 case RPC_FC_SMALL:
2536 case RPC_FC_USMALL:
2537 pMemory += 1;
2538 break;
2539 case RPC_FC_WCHAR:
2540 case RPC_FC_SHORT:
2541 case RPC_FC_USHORT:
2542 pMemory += 2;
2543 break;
2544 case RPC_FC_LONG:
2545 case RPC_FC_ULONG:
2546 case RPC_FC_ENUM16:
2547 case RPC_FC_ENUM32:
2548 pMemory += 4;
2549 break;
2550 case RPC_FC_HYPER:
2551 pMemory += 8;
2552 break;
2553 case RPC_FC_POINTER:
2554 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2555 pPointer += 4;
2556 pMemory += 4;
2557 break;
2558 case RPC_FC_ALIGNM4:
2559 ALIGN_POINTER(pMemory, 4);
2560 break;
2561 case RPC_FC_ALIGNM8:
2562 ALIGN_POINTER(pMemory, 8);
2563 break;
2564 case RPC_FC_STRUCTPAD1:
2565 case RPC_FC_STRUCTPAD2:
2566 case RPC_FC_STRUCTPAD3:
2567 case RPC_FC_STRUCTPAD4:
2568 case RPC_FC_STRUCTPAD5:
2569 case RPC_FC_STRUCTPAD6:
2570 case RPC_FC_STRUCTPAD7:
2571 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2572 break;
2573 case RPC_FC_EMBEDDED_COMPLEX:
2574 pMemory += pFormat[1];
2575 pFormat += 2;
2576 desc = pFormat + *(const SHORT*)pFormat;
2577 size = EmbeddedComplexSize(pStubMsg, desc);
2578 m = NdrFreer[*desc & NDR_TABLE_MASK];
2579 if (m)
2581 /* for some reason interface pointers aren't generated as
2582 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2583 * they still need the derefencing treatment that pointers are
2584 * given */
2585 if (*desc == RPC_FC_IP)
2586 m(pStubMsg, *(unsigned char **)pMemory, desc);
2587 else
2588 m(pStubMsg, pMemory, desc);
2590 pMemory += size;
2591 pFormat += 2;
2592 continue;
2593 case RPC_FC_PAD:
2594 break;
2595 default:
2596 FIXME("unhandled format 0x%02x\n", *pFormat);
2598 pFormat++;
2601 return pMemory;
2604 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2605 PFORMAT_STRING pFormat)
2607 PFORMAT_STRING desc;
2608 unsigned long size = 0;
2610 while (*pFormat != RPC_FC_END) {
2611 switch (*pFormat) {
2612 case RPC_FC_BYTE:
2613 case RPC_FC_CHAR:
2614 case RPC_FC_SMALL:
2615 case RPC_FC_USMALL:
2616 size += 1;
2617 safe_buffer_increment(pStubMsg, 1);
2618 break;
2619 case RPC_FC_WCHAR:
2620 case RPC_FC_SHORT:
2621 case RPC_FC_USHORT:
2622 size += 2;
2623 safe_buffer_increment(pStubMsg, 2);
2624 break;
2625 case RPC_FC_ENUM16:
2626 size += 4;
2627 safe_buffer_increment(pStubMsg, 2);
2628 break;
2629 case RPC_FC_LONG:
2630 case RPC_FC_ULONG:
2631 case RPC_FC_ENUM32:
2632 size += 4;
2633 safe_buffer_increment(pStubMsg, 4);
2634 break;
2635 case RPC_FC_HYPER:
2636 size += 8;
2637 safe_buffer_increment(pStubMsg, 8);
2638 break;
2639 case RPC_FC_POINTER:
2640 size += 4;
2641 safe_buffer_increment(pStubMsg, 4);
2642 if (!pStubMsg->IgnoreEmbeddedPointers)
2643 FIXME("embedded pointers\n");
2644 break;
2645 case RPC_FC_ALIGNM4:
2646 ALIGN_LENGTH(size, 4);
2647 ALIGN_POINTER(pStubMsg->Buffer, 4);
2648 break;
2649 case RPC_FC_ALIGNM8:
2650 ALIGN_LENGTH(size, 8);
2651 ALIGN_POINTER(pStubMsg->Buffer, 8);
2652 break;
2653 case RPC_FC_STRUCTPAD1:
2654 case RPC_FC_STRUCTPAD2:
2655 case RPC_FC_STRUCTPAD3:
2656 case RPC_FC_STRUCTPAD4:
2657 case RPC_FC_STRUCTPAD5:
2658 case RPC_FC_STRUCTPAD6:
2659 case RPC_FC_STRUCTPAD7:
2660 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2661 break;
2662 case RPC_FC_EMBEDDED_COMPLEX:
2663 size += pFormat[1];
2664 pFormat += 2;
2665 desc = pFormat + *(const SHORT*)pFormat;
2666 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2667 pFormat += 2;
2668 continue;
2669 case RPC_FC_PAD:
2670 break;
2671 default:
2672 FIXME("unhandled format 0x%02x\n", *pFormat);
2674 pFormat++;
2677 return size;
2680 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
2681 PFORMAT_STRING pFormat)
2683 PFORMAT_STRING desc;
2684 unsigned long size = 0;
2686 while (*pFormat != RPC_FC_END) {
2687 switch (*pFormat) {
2688 case RPC_FC_BYTE:
2689 case RPC_FC_CHAR:
2690 case RPC_FC_SMALL:
2691 case RPC_FC_USMALL:
2692 size += 1;
2693 break;
2694 case RPC_FC_WCHAR:
2695 case RPC_FC_SHORT:
2696 case RPC_FC_USHORT:
2697 size += 2;
2698 break;
2699 case RPC_FC_LONG:
2700 case RPC_FC_ULONG:
2701 case RPC_FC_ENUM16:
2702 case RPC_FC_ENUM32:
2703 size += 4;
2704 break;
2705 case RPC_FC_HYPER:
2706 size += 8;
2707 break;
2708 case RPC_FC_POINTER:
2709 size += sizeof(void *);
2710 break;
2711 case RPC_FC_ALIGNM4:
2712 ALIGN_LENGTH(size, 4);
2713 break;
2714 case RPC_FC_ALIGNM8:
2715 ALIGN_LENGTH(size, 8);
2716 break;
2717 case RPC_FC_STRUCTPAD1:
2718 case RPC_FC_STRUCTPAD2:
2719 case RPC_FC_STRUCTPAD3:
2720 case RPC_FC_STRUCTPAD4:
2721 case RPC_FC_STRUCTPAD5:
2722 case RPC_FC_STRUCTPAD6:
2723 case RPC_FC_STRUCTPAD7:
2724 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2725 break;
2726 case RPC_FC_EMBEDDED_COMPLEX:
2727 size += pFormat[1];
2728 pFormat += 2;
2729 desc = pFormat + *(const SHORT*)pFormat;
2730 size += EmbeddedComplexSize(pStubMsg, desc);
2731 pFormat += 2;
2732 continue;
2733 case RPC_FC_PAD:
2734 break;
2735 default:
2736 FIXME("unhandled format 0x%02x\n", *pFormat);
2738 pFormat++;
2741 return size;
2744 /***********************************************************************
2745 * NdrComplexStructMarshall [RPCRT4.@]
2747 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2748 unsigned char *pMemory,
2749 PFORMAT_STRING pFormat)
2751 PFORMAT_STRING conf_array = NULL;
2752 PFORMAT_STRING pointer_desc = NULL;
2753 unsigned char *OldMemory = pStubMsg->Memory;
2754 int pointer_buffer_mark_set = 0;
2756 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2758 if (!pStubMsg->PointerBufferMark)
2760 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2761 /* save buffer length */
2762 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2764 /* get the buffer pointer after complex array data, but before
2765 * pointer data */
2766 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2767 pStubMsg->IgnoreEmbeddedPointers = 1;
2768 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2769 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2771 /* save it for use by embedded pointer code later */
2772 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2773 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2774 pointer_buffer_mark_set = 1;
2776 /* restore the original buffer length */
2777 pStubMsg->BufferLength = saved_buffer_length;
2780 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2782 pFormat += 4;
2783 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2784 pFormat += 2;
2785 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2786 pFormat += 2;
2788 pStubMsg->Memory = pMemory;
2790 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2792 if (conf_array)
2793 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2795 pStubMsg->Memory = OldMemory;
2797 if (pointer_buffer_mark_set)
2799 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2800 pStubMsg->PointerBufferMark = NULL;
2803 STD_OVERFLOW_CHECK(pStubMsg);
2805 return NULL;
2808 /***********************************************************************
2809 * NdrComplexStructUnmarshall [RPCRT4.@]
2811 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2812 unsigned char **ppMemory,
2813 PFORMAT_STRING pFormat,
2814 unsigned char fMustAlloc)
2816 unsigned size = *(const WORD*)(pFormat+2);
2817 PFORMAT_STRING conf_array = NULL;
2818 PFORMAT_STRING pointer_desc = NULL;
2819 unsigned char *pMemory;
2820 int pointer_buffer_mark_set = 0;
2822 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2824 if (!pStubMsg->PointerBufferMark)
2826 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2827 /* save buffer pointer */
2828 unsigned char *saved_buffer = pStubMsg->Buffer;
2830 /* get the buffer pointer after complex array data, but before
2831 * pointer data */
2832 pStubMsg->IgnoreEmbeddedPointers = 1;
2833 NdrComplexStructMemorySize(pStubMsg, pFormat);
2834 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2836 /* save it for use by embedded pointer code later */
2837 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2838 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2839 pointer_buffer_mark_set = 1;
2841 /* restore the original buffer */
2842 pStubMsg->Buffer = saved_buffer;
2845 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2847 if (fMustAlloc || !*ppMemory)
2849 *ppMemory = NdrAllocate(pStubMsg, size);
2850 memset(*ppMemory, 0, size);
2853 pFormat += 4;
2854 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2855 pFormat += 2;
2856 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2857 pFormat += 2;
2859 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2861 if (conf_array)
2862 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2864 if (pointer_buffer_mark_set)
2866 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2867 pStubMsg->PointerBufferMark = NULL;
2870 return NULL;
2873 /***********************************************************************
2874 * NdrComplexStructBufferSize [RPCRT4.@]
2876 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2877 unsigned char *pMemory,
2878 PFORMAT_STRING pFormat)
2880 PFORMAT_STRING conf_array = NULL;
2881 PFORMAT_STRING pointer_desc = NULL;
2882 unsigned char *OldMemory = pStubMsg->Memory;
2883 int pointer_length_set = 0;
2885 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2887 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2889 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2891 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2892 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2894 /* get the buffer length after complex struct data, but before
2895 * pointer data */
2896 pStubMsg->IgnoreEmbeddedPointers = 1;
2897 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2898 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2900 /* save it for use by embedded pointer code later */
2901 pStubMsg->PointerLength = pStubMsg->BufferLength;
2902 pointer_length_set = 1;
2903 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2905 /* restore the original buffer length */
2906 pStubMsg->BufferLength = saved_buffer_length;
2909 pFormat += 4;
2910 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2911 pFormat += 2;
2912 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2913 pFormat += 2;
2915 pStubMsg->Memory = pMemory;
2917 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2919 if (conf_array)
2920 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2922 pStubMsg->Memory = OldMemory;
2924 if(pointer_length_set)
2926 pStubMsg->BufferLength = pStubMsg->PointerLength;
2927 pStubMsg->PointerLength = 0;
2932 /***********************************************************************
2933 * NdrComplexStructMemorySize [RPCRT4.@]
2935 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2936 PFORMAT_STRING pFormat)
2938 unsigned size = *(const WORD*)(pFormat+2);
2939 PFORMAT_STRING conf_array = NULL;
2940 PFORMAT_STRING pointer_desc = NULL;
2942 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2944 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2946 pFormat += 4;
2947 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2948 pFormat += 2;
2949 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2950 pFormat += 2;
2952 ComplexStructMemorySize(pStubMsg, pFormat);
2954 if (conf_array)
2955 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2957 return size;
2960 /***********************************************************************
2961 * NdrComplexStructFree [RPCRT4.@]
2963 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2964 unsigned char *pMemory,
2965 PFORMAT_STRING pFormat)
2967 PFORMAT_STRING conf_array = NULL;
2968 PFORMAT_STRING pointer_desc = NULL;
2969 unsigned char *OldMemory = pStubMsg->Memory;
2971 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2973 pFormat += 4;
2974 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2975 pFormat += 2;
2976 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2977 pFormat += 2;
2979 pStubMsg->Memory = pMemory;
2981 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2983 if (conf_array)
2984 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2986 pStubMsg->Memory = OldMemory;
2989 /***********************************************************************
2990 * NdrConformantArrayMarshall [RPCRT4.@]
2992 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2993 unsigned char *pMemory,
2994 PFORMAT_STRING pFormat)
2996 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2997 unsigned char alignment = pFormat[1] + 1;
2999 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3000 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3002 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3004 WriteConformance(pStubMsg);
3006 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3008 size = safe_multiply(esize, pStubMsg->MaxCount);
3009 pStubMsg->BufferMark = pStubMsg->Buffer;
3010 safe_copy_to_buffer(pStubMsg, pMemory, size);
3012 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3014 return NULL;
3017 /***********************************************************************
3018 * NdrConformantArrayUnmarshall [RPCRT4.@]
3020 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3021 unsigned char **ppMemory,
3022 PFORMAT_STRING pFormat,
3023 unsigned char fMustAlloc)
3025 DWORD size, esize = *(const WORD*)(pFormat+2);
3026 unsigned char alignment = pFormat[1] + 1;
3027 unsigned char *saved_buffer;
3029 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3030 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3032 pFormat = ReadConformance(pStubMsg, pFormat+4);
3034 size = safe_multiply(esize, pStubMsg->MaxCount);
3035 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3037 if (fMustAlloc)
3038 *ppMemory = NdrAllocate(pStubMsg, size);
3039 else
3041 if (!pStubMsg->IsClient && !*ppMemory)
3042 /* for servers, we just point straight into the RPC buffer */
3043 *ppMemory = pStubMsg->Buffer;
3046 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3047 safe_buffer_increment(pStubMsg, size);
3048 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3050 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3051 if (*ppMemory != saved_buffer)
3052 memcpy(*ppMemory, saved_buffer, size);
3054 return NULL;
3057 /***********************************************************************
3058 * NdrConformantArrayBufferSize [RPCRT4.@]
3060 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3061 unsigned char *pMemory,
3062 PFORMAT_STRING pFormat)
3064 DWORD size, esize = *(const WORD*)(pFormat+2);
3065 unsigned char alignment = pFormat[1] + 1;
3067 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3068 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3070 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3072 SizeConformance(pStubMsg);
3074 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3076 size = safe_multiply(esize, pStubMsg->MaxCount);
3077 /* conformance value plus array */
3078 safe_buffer_length_increment(pStubMsg, size);
3080 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3083 /***********************************************************************
3084 * NdrConformantArrayMemorySize [RPCRT4.@]
3086 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3087 PFORMAT_STRING pFormat)
3089 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3090 unsigned char alignment = pFormat[1] + 1;
3092 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3093 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3095 pFormat = ReadConformance(pStubMsg, pFormat+4);
3096 size = safe_multiply(esize, pStubMsg->MaxCount);
3097 pStubMsg->MemorySize += size;
3099 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3100 pStubMsg->BufferMark = pStubMsg->Buffer;
3101 safe_buffer_increment(pStubMsg, size);
3103 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3105 return pStubMsg->MemorySize;
3108 /***********************************************************************
3109 * NdrConformantArrayFree [RPCRT4.@]
3111 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3112 unsigned char *pMemory,
3113 PFORMAT_STRING pFormat)
3115 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3116 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3118 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3120 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3124 /***********************************************************************
3125 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3127 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3128 unsigned char* pMemory,
3129 PFORMAT_STRING pFormat )
3131 ULONG bufsize;
3132 unsigned char alignment = pFormat[1] + 1;
3133 DWORD esize = *(const WORD*)(pFormat+2);
3135 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3137 if (pFormat[0] != RPC_FC_CVARRAY)
3139 ERR("invalid format type %x\n", pFormat[0]);
3140 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3141 return NULL;
3144 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3145 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3147 WriteConformance(pStubMsg);
3148 WriteVariance(pStubMsg);
3150 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3152 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3154 pStubMsg->BufferMark = pStubMsg->Buffer;
3155 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
3157 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3159 return NULL;
3163 /***********************************************************************
3164 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3166 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3167 unsigned char** ppMemory,
3168 PFORMAT_STRING pFormat,
3169 unsigned char fMustAlloc )
3171 ULONG bufsize, memsize;
3172 unsigned char alignment = pFormat[1] + 1;
3173 DWORD esize = *(const WORD*)(pFormat+2);
3174 unsigned char *saved_buffer;
3175 ULONG offset;
3177 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3179 if (pFormat[0] != RPC_FC_CVARRAY)
3181 ERR("invalid format type %x\n", pFormat[0]);
3182 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3183 return NULL;
3186 pFormat = ReadConformance(pStubMsg, pFormat+4);
3187 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3189 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3191 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3192 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3193 offset = pStubMsg->Offset;
3195 if (!*ppMemory || fMustAlloc)
3196 *ppMemory = NdrAllocate(pStubMsg, memsize);
3197 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3198 safe_buffer_increment(pStubMsg, bufsize);
3200 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3202 memcpy(*ppMemory + offset, saved_buffer, bufsize);
3204 return NULL;
3208 /***********************************************************************
3209 * NdrConformantVaryingArrayFree [RPCRT4.@]
3211 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3212 unsigned char* pMemory,
3213 PFORMAT_STRING pFormat )
3215 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3217 if (pFormat[0] != RPC_FC_CVARRAY)
3219 ERR("invalid format type %x\n", pFormat[0]);
3220 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3221 return;
3224 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3225 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3227 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3231 /***********************************************************************
3232 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3234 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3235 unsigned char* pMemory, PFORMAT_STRING pFormat )
3237 unsigned char alignment = pFormat[1] + 1;
3238 DWORD esize = *(const WORD*)(pFormat+2);
3240 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3242 if (pFormat[0] != RPC_FC_CVARRAY)
3244 ERR("invalid format type %x\n", pFormat[0]);
3245 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3246 return;
3249 /* compute size */
3250 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3251 /* compute length */
3252 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3254 SizeConformance(pStubMsg);
3255 SizeVariance(pStubMsg);
3257 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3259 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3261 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3265 /***********************************************************************
3266 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3268 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3269 PFORMAT_STRING pFormat )
3271 ULONG bufsize, memsize;
3272 unsigned char alignment = pFormat[1] + 1;
3273 DWORD esize = *(const WORD*)(pFormat+2);
3275 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3277 if (pFormat[0] != RPC_FC_CVARRAY)
3279 ERR("invalid format type %x\n", pFormat[0]);
3280 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3281 return pStubMsg->MemorySize;
3284 pFormat = ReadConformance(pStubMsg, pFormat+4);
3285 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3287 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3289 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3290 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3292 safe_buffer_increment(pStubMsg, bufsize);
3293 pStubMsg->MemorySize += memsize;
3295 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3297 return pStubMsg->MemorySize;
3301 /***********************************************************************
3302 * NdrComplexArrayMarshall [RPCRT4.@]
3304 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3305 unsigned char *pMemory,
3306 PFORMAT_STRING pFormat)
3308 ULONG i, count, def;
3309 BOOL variance_present;
3310 unsigned char alignment;
3311 int pointer_buffer_mark_set = 0;
3313 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3315 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3317 ERR("invalid format type %x\n", pFormat[0]);
3318 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3319 return NULL;
3322 alignment = pFormat[1] + 1;
3324 if (!pStubMsg->PointerBufferMark)
3326 /* save buffer fields that may be changed by buffer sizer functions
3327 * and that may be needed later on */
3328 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3329 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3330 unsigned long saved_max_count = pStubMsg->MaxCount;
3331 unsigned long saved_offset = pStubMsg->Offset;
3332 unsigned long saved_actual_count = pStubMsg->ActualCount;
3334 /* get the buffer pointer after complex array data, but before
3335 * pointer data */
3336 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3337 pStubMsg->IgnoreEmbeddedPointers = 1;
3338 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3339 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3341 /* save it for use by embedded pointer code later */
3342 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3343 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3344 pointer_buffer_mark_set = 1;
3346 /* restore fields */
3347 pStubMsg->ActualCount = saved_actual_count;
3348 pStubMsg->Offset = saved_offset;
3349 pStubMsg->MaxCount = saved_max_count;
3350 pStubMsg->BufferLength = saved_buffer_length;
3353 def = *(const WORD*)&pFormat[2];
3354 pFormat += 4;
3356 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3357 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3359 variance_present = IsConformanceOrVariancePresent(pFormat);
3360 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3361 TRACE("variance = %d\n", pStubMsg->ActualCount);
3363 WriteConformance(pStubMsg);
3364 if (variance_present)
3365 WriteVariance(pStubMsg);
3367 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3369 count = pStubMsg->ActualCount;
3370 for (i = 0; i < count; i++)
3371 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3373 STD_OVERFLOW_CHECK(pStubMsg);
3375 if (pointer_buffer_mark_set)
3377 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3378 pStubMsg->PointerBufferMark = NULL;
3381 return NULL;
3384 /***********************************************************************
3385 * NdrComplexArrayUnmarshall [RPCRT4.@]
3387 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3388 unsigned char **ppMemory,
3389 PFORMAT_STRING pFormat,
3390 unsigned char fMustAlloc)
3392 ULONG i, count, size;
3393 unsigned char alignment;
3394 unsigned char *pMemory;
3395 unsigned char *saved_buffer;
3396 int pointer_buffer_mark_set = 0;
3397 int saved_ignore_embedded;
3399 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3401 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3403 ERR("invalid format type %x\n", pFormat[0]);
3404 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3405 return NULL;
3408 alignment = pFormat[1] + 1;
3410 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3411 /* save buffer pointer */
3412 saved_buffer = pStubMsg->Buffer;
3413 /* get the buffer pointer after complex array data, but before
3414 * pointer data */
3415 pStubMsg->IgnoreEmbeddedPointers = 1;
3416 pStubMsg->MemorySize = 0;
3417 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3418 size = pStubMsg->MemorySize;
3419 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3421 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3422 if (!pStubMsg->PointerBufferMark)
3424 /* save it for use by embedded pointer code later */
3425 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3426 pointer_buffer_mark_set = 1;
3428 /* restore the original buffer */
3429 pStubMsg->Buffer = saved_buffer;
3431 pFormat += 4;
3433 pFormat = ReadConformance(pStubMsg, pFormat);
3434 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3436 if (fMustAlloc || !*ppMemory)
3438 *ppMemory = NdrAllocate(pStubMsg, size);
3439 memset(*ppMemory, 0, size);
3442 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3444 pMemory = *ppMemory;
3445 count = pStubMsg->ActualCount;
3446 for (i = 0; i < count; i++)
3447 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3449 if (pointer_buffer_mark_set)
3451 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3452 pStubMsg->PointerBufferMark = NULL;
3455 return NULL;
3458 /***********************************************************************
3459 * NdrComplexArrayBufferSize [RPCRT4.@]
3461 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3462 unsigned char *pMemory,
3463 PFORMAT_STRING pFormat)
3465 ULONG i, count, def;
3466 unsigned char alignment;
3467 BOOL variance_present;
3468 int pointer_length_set = 0;
3470 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3472 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3474 ERR("invalid format type %x\n", pFormat[0]);
3475 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3476 return;
3479 alignment = pFormat[1] + 1;
3481 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3483 /* save buffer fields that may be changed by buffer sizer functions
3484 * and that may be needed later on */
3485 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3486 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3487 unsigned long saved_max_count = pStubMsg->MaxCount;
3488 unsigned long saved_offset = pStubMsg->Offset;
3489 unsigned long saved_actual_count = pStubMsg->ActualCount;
3491 /* get the buffer pointer after complex array data, but before
3492 * pointer data */
3493 pStubMsg->IgnoreEmbeddedPointers = 1;
3494 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3495 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3497 /* save it for use by embedded pointer code later */
3498 pStubMsg->PointerLength = pStubMsg->BufferLength;
3499 pointer_length_set = 1;
3501 /* restore fields */
3502 pStubMsg->ActualCount = saved_actual_count;
3503 pStubMsg->Offset = saved_offset;
3504 pStubMsg->MaxCount = saved_max_count;
3505 pStubMsg->BufferLength = saved_buffer_length;
3507 def = *(const WORD*)&pFormat[2];
3508 pFormat += 4;
3510 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3511 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3512 SizeConformance(pStubMsg);
3514 variance_present = IsConformanceOrVariancePresent(pFormat);
3515 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3516 TRACE("variance = %d\n", pStubMsg->ActualCount);
3518 if (variance_present)
3519 SizeVariance(pStubMsg);
3521 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3523 count = pStubMsg->ActualCount;
3524 for (i = 0; i < count; i++)
3525 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3527 if(pointer_length_set)
3529 pStubMsg->BufferLength = pStubMsg->PointerLength;
3530 pStubMsg->PointerLength = 0;
3534 /***********************************************************************
3535 * NdrComplexArrayMemorySize [RPCRT4.@]
3537 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3538 PFORMAT_STRING pFormat)
3540 ULONG i, count, esize, SavedMemorySize, MemorySize;
3541 unsigned char alignment;
3543 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3545 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3547 ERR("invalid format type %x\n", pFormat[0]);
3548 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3549 return 0;
3552 alignment = pFormat[1] + 1;
3554 pFormat += 4;
3556 pFormat = ReadConformance(pStubMsg, pFormat);
3557 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3559 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3561 SavedMemorySize = pStubMsg->MemorySize;
3563 esize = ComplexStructSize(pStubMsg, pFormat);
3565 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3567 count = pStubMsg->ActualCount;
3568 for (i = 0; i < count; i++)
3569 ComplexStructMemorySize(pStubMsg, pFormat);
3571 pStubMsg->MemorySize = SavedMemorySize;
3573 pStubMsg->MemorySize += MemorySize;
3574 return MemorySize;
3577 /***********************************************************************
3578 * NdrComplexArrayFree [RPCRT4.@]
3580 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3581 unsigned char *pMemory,
3582 PFORMAT_STRING pFormat)
3584 ULONG i, count, def;
3586 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3588 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3590 ERR("invalid format type %x\n", pFormat[0]);
3591 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3592 return;
3595 def = *(const WORD*)&pFormat[2];
3596 pFormat += 4;
3598 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3599 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3601 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3602 TRACE("variance = %d\n", pStubMsg->ActualCount);
3604 count = pStubMsg->ActualCount;
3605 for (i = 0; i < count; i++)
3606 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3609 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3610 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3611 USER_MARSHAL_CB *umcb)
3613 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3614 pStubMsg->RpcMsg->DataRepresentation);
3615 umcb->pStubMsg = pStubMsg;
3616 umcb->pReserve = NULL;
3617 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3618 umcb->CBType = cbtype;
3619 umcb->pFormat = pFormat;
3620 umcb->pTypeFormat = NULL /* FIXME */;
3623 #define USER_MARSHAL_PTR_PREFIX \
3624 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3625 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3627 /***********************************************************************
3628 * NdrUserMarshalMarshall [RPCRT4.@]
3630 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3631 unsigned char *pMemory,
3632 PFORMAT_STRING pFormat)
3634 unsigned flags = pFormat[1];
3635 unsigned index = *(const WORD*)&pFormat[2];
3636 unsigned char *saved_buffer = NULL;
3637 USER_MARSHAL_CB umcb;
3639 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3640 TRACE("index=%d\n", index);
3642 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3644 if (flags & USER_MARSHAL_POINTER)
3646 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3647 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3648 pStubMsg->Buffer += 4;
3649 if (pStubMsg->PointerBufferMark)
3651 saved_buffer = pStubMsg->Buffer;
3652 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3653 pStubMsg->PointerBufferMark = NULL;
3655 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3657 else
3658 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3660 pStubMsg->Buffer =
3661 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3662 &umcb.Flags, pStubMsg->Buffer, pMemory);
3664 if (saved_buffer)
3666 STD_OVERFLOW_CHECK(pStubMsg);
3667 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3668 pStubMsg->Buffer = saved_buffer;
3671 STD_OVERFLOW_CHECK(pStubMsg);
3673 return NULL;
3676 /***********************************************************************
3677 * NdrUserMarshalUnmarshall [RPCRT4.@]
3679 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3680 unsigned char **ppMemory,
3681 PFORMAT_STRING pFormat,
3682 unsigned char fMustAlloc)
3684 unsigned flags = pFormat[1];
3685 unsigned index = *(const WORD*)&pFormat[2];
3686 DWORD memsize = *(const WORD*)&pFormat[4];
3687 unsigned char *saved_buffer = NULL;
3688 USER_MARSHAL_CB umcb;
3690 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3691 TRACE("index=%d\n", index);
3693 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3695 if (flags & USER_MARSHAL_POINTER)
3697 ALIGN_POINTER(pStubMsg->Buffer, 4);
3698 /* skip pointer prefix */
3699 pStubMsg->Buffer += 4;
3700 if (pStubMsg->PointerBufferMark)
3702 saved_buffer = pStubMsg->Buffer;
3703 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3704 pStubMsg->PointerBufferMark = NULL;
3706 ALIGN_POINTER(pStubMsg->Buffer, 8);
3708 else
3709 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3711 if (fMustAlloc || !*ppMemory)
3712 *ppMemory = NdrAllocate(pStubMsg, memsize);
3714 pStubMsg->Buffer =
3715 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3716 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3718 if (saved_buffer)
3720 STD_OVERFLOW_CHECK(pStubMsg);
3721 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3722 pStubMsg->Buffer = saved_buffer;
3725 return NULL;
3728 /***********************************************************************
3729 * NdrUserMarshalBufferSize [RPCRT4.@]
3731 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3732 unsigned char *pMemory,
3733 PFORMAT_STRING pFormat)
3735 unsigned flags = pFormat[1];
3736 unsigned index = *(const WORD*)&pFormat[2];
3737 DWORD bufsize = *(const WORD*)&pFormat[6];
3738 USER_MARSHAL_CB umcb;
3739 unsigned long saved_buffer_length = 0;
3741 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3742 TRACE("index=%d\n", index);
3744 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3746 if (flags & USER_MARSHAL_POINTER)
3748 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3749 /* skip pointer prefix */
3750 safe_buffer_length_increment(pStubMsg, 4);
3751 if (pStubMsg->IgnoreEmbeddedPointers)
3752 return;
3753 if (pStubMsg->PointerLength)
3755 saved_buffer_length = pStubMsg->BufferLength;
3756 pStubMsg->BufferLength = pStubMsg->PointerLength;
3757 pStubMsg->PointerLength = 0;
3759 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3761 else
3762 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3764 if (bufsize) {
3765 TRACE("size=%d\n", bufsize);
3766 safe_buffer_length_increment(pStubMsg, bufsize);
3768 else
3769 pStubMsg->BufferLength =
3770 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3771 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3773 if (saved_buffer_length)
3775 pStubMsg->PointerLength = pStubMsg->BufferLength;
3776 pStubMsg->BufferLength = saved_buffer_length;
3781 /***********************************************************************
3782 * NdrUserMarshalMemorySize [RPCRT4.@]
3784 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3785 PFORMAT_STRING pFormat)
3787 unsigned flags = pFormat[1];
3788 unsigned index = *(const WORD*)&pFormat[2];
3789 DWORD memsize = *(const WORD*)&pFormat[4];
3790 DWORD bufsize = *(const WORD*)&pFormat[6];
3792 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3793 TRACE("index=%d\n", index);
3795 pStubMsg->MemorySize += memsize;
3797 if (flags & USER_MARSHAL_POINTER)
3799 ALIGN_POINTER(pStubMsg->Buffer, 4);
3800 /* skip pointer prefix */
3801 pStubMsg->Buffer += 4;
3802 if (pStubMsg->IgnoreEmbeddedPointers)
3803 return pStubMsg->MemorySize;
3804 ALIGN_POINTER(pStubMsg->Buffer, 8);
3806 else
3807 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3809 if (!bufsize)
3810 FIXME("not implemented for varying buffer size\n");
3812 pStubMsg->Buffer += bufsize;
3814 return pStubMsg->MemorySize;
3817 /***********************************************************************
3818 * NdrUserMarshalFree [RPCRT4.@]
3820 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3821 unsigned char *pMemory,
3822 PFORMAT_STRING pFormat)
3824 /* unsigned flags = pFormat[1]; */
3825 unsigned index = *(const WORD*)&pFormat[2];
3826 USER_MARSHAL_CB umcb;
3828 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3829 TRACE("index=%d\n", index);
3831 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3833 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3834 &umcb.Flags, pMemory);
3837 /***********************************************************************
3838 * NdrClearOutParameters [RPCRT4.@]
3840 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3841 PFORMAT_STRING pFormat,
3842 void *ArgAddr)
3844 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3847 /***********************************************************************
3848 * NdrConvert [RPCRT4.@]
3850 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3852 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3853 /* FIXME: since this stub doesn't do any converting, the proper behavior
3854 is to raise an exception */
3857 /***********************************************************************
3858 * NdrConvert2 [RPCRT4.@]
3860 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3862 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3863 pStubMsg, pFormat, NumberParams);
3864 /* FIXME: since this stub doesn't do any converting, the proper behavior
3865 is to raise an exception */
3868 #include "pshpack1.h"
3869 typedef struct _NDR_CSTRUCT_FORMAT
3871 unsigned char type;
3872 unsigned char alignment;
3873 unsigned short memory_size;
3874 short offset_to_array_description;
3875 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3876 #include "poppack.h"
3878 /***********************************************************************
3879 * NdrConformantStructMarshall [RPCRT4.@]
3881 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3882 unsigned char *pMemory,
3883 PFORMAT_STRING pFormat)
3885 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3886 PFORMAT_STRING pCArrayFormat;
3887 ULONG esize, bufsize;
3889 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3891 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3892 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3894 ERR("invalid format type %x\n", pCStructFormat->type);
3895 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3896 return NULL;
3899 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3900 pCStructFormat->offset_to_array_description;
3901 if (*pCArrayFormat != RPC_FC_CARRAY)
3903 ERR("invalid array format type %x\n", pCStructFormat->type);
3904 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3905 return NULL;
3907 esize = *(const WORD*)(pCArrayFormat+2);
3909 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3910 pCArrayFormat + 4, 0);
3912 WriteConformance(pStubMsg);
3914 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3916 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3918 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3919 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3921 ERR("integer overflow of memory_size %u with bufsize %u\n",
3922 pCStructFormat->memory_size, bufsize);
3923 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3925 /* copy constant sized part of struct */
3926 pStubMsg->BufferMark = pStubMsg->Buffer;
3927 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3929 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3930 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3932 return NULL;
3935 /***********************************************************************
3936 * NdrConformantStructUnmarshall [RPCRT4.@]
3938 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3939 unsigned char **ppMemory,
3940 PFORMAT_STRING pFormat,
3941 unsigned char fMustAlloc)
3943 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3944 PFORMAT_STRING pCArrayFormat;
3945 ULONG esize, bufsize;
3946 unsigned char *saved_buffer;
3948 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
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;
3957 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3958 pCStructFormat->offset_to_array_description;
3959 if (*pCArrayFormat != RPC_FC_CARRAY)
3961 ERR("invalid array format type %x\n", pCStructFormat->type);
3962 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3963 return NULL;
3965 esize = *(const WORD*)(pCArrayFormat+2);
3967 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3969 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3971 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3973 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3974 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3976 ERR("integer overflow of memory_size %u with bufsize %u\n",
3977 pCStructFormat->memory_size, bufsize);
3978 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3981 if (fMustAlloc)
3983 SIZE_T size = pCStructFormat->memory_size + bufsize;
3984 *ppMemory = NdrAllocate(pStubMsg, size);
3986 else
3988 if (!pStubMsg->IsClient && !*ppMemory)
3989 /* for servers, we just point straight into the RPC buffer */
3990 *ppMemory = pStubMsg->Buffer;
3993 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3994 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3995 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3996 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3998 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3999 if (*ppMemory != saved_buffer)
4000 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4002 return NULL;
4005 /***********************************************************************
4006 * NdrConformantStructBufferSize [RPCRT4.@]
4008 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4009 unsigned char *pMemory,
4010 PFORMAT_STRING pFormat)
4012 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4013 PFORMAT_STRING pCArrayFormat;
4014 ULONG esize;
4016 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4018 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4019 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4021 ERR("invalid format type %x\n", pCStructFormat->type);
4022 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4023 return;
4025 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4026 pCStructFormat->offset_to_array_description;
4027 if (*pCArrayFormat != RPC_FC_CARRAY)
4029 ERR("invalid array format type %x\n", pCStructFormat->type);
4030 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4031 return;
4033 esize = *(const WORD*)(pCArrayFormat+2);
4035 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4036 SizeConformance(pStubMsg);
4038 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4040 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4042 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4043 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4045 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4046 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4049 /***********************************************************************
4050 * NdrConformantStructMemorySize [RPCRT4.@]
4052 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4053 PFORMAT_STRING pFormat)
4055 FIXME("stub\n");
4056 return 0;
4059 /***********************************************************************
4060 * NdrConformantStructFree [RPCRT4.@]
4062 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4063 unsigned char *pMemory,
4064 PFORMAT_STRING pFormat)
4066 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4067 PFORMAT_STRING pCArrayFormat;
4068 ULONG esize;
4070 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4072 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4073 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4075 ERR("invalid format type %x\n", pCStructFormat->type);
4076 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4077 return;
4080 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4081 pCStructFormat->offset_to_array_description;
4082 if (*pCArrayFormat != RPC_FC_CARRAY)
4084 ERR("invalid array format type %x\n", pCStructFormat->type);
4085 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4086 return;
4088 esize = *(const WORD*)(pCArrayFormat+2);
4090 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4091 pCArrayFormat + 4, 0);
4093 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4095 /* copy constant sized part of struct */
4096 pStubMsg->BufferMark = pStubMsg->Buffer;
4098 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4099 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4102 /***********************************************************************
4103 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4105 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4106 unsigned char *pMemory,
4107 PFORMAT_STRING pFormat)
4109 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4110 PFORMAT_STRING pCVArrayFormat;
4111 ULONG esize, bufsize;
4113 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4115 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4116 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4118 ERR("invalid format type %x\n", pCVStructFormat->type);
4119 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4120 return NULL;
4123 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4124 pCVStructFormat->offset_to_array_description;
4125 switch (*pCVArrayFormat)
4127 case RPC_FC_CVARRAY:
4128 esize = *(const WORD*)(pCVArrayFormat+2);
4130 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4131 pCVArrayFormat + 4, 0);
4132 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4133 pCVArrayFormat, 0);
4134 break;
4135 case RPC_FC_C_CSTRING:
4136 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4137 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4138 esize = sizeof(char);
4139 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4140 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4141 pCVArrayFormat + 2, 0);
4142 else
4143 pStubMsg->MaxCount = pStubMsg->ActualCount;
4144 break;
4145 case RPC_FC_C_WSTRING:
4146 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4147 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4148 esize = sizeof(WCHAR);
4149 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4150 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4151 pCVArrayFormat + 2, 0);
4152 else
4153 pStubMsg->MaxCount = pStubMsg->ActualCount;
4154 break;
4155 default:
4156 ERR("invalid array format type %x\n", *pCVArrayFormat);
4157 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4158 return NULL;
4161 WriteConformance(pStubMsg);
4163 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4165 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4167 /* write constant sized part */
4168 pStubMsg->BufferMark = pStubMsg->Buffer;
4169 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4171 WriteVariance(pStubMsg);
4173 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4175 /* write array part */
4176 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
4178 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4180 return NULL;
4183 /***********************************************************************
4184 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4186 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4187 unsigned char **ppMemory,
4188 PFORMAT_STRING pFormat,
4189 unsigned char fMustAlloc)
4191 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4192 PFORMAT_STRING pCVArrayFormat;
4193 ULONG esize, bufsize;
4194 unsigned char cvarray_type;
4196 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4198 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4199 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4201 ERR("invalid format type %x\n", pCVStructFormat->type);
4202 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4203 return NULL;
4206 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4207 pCVStructFormat->offset_to_array_description;
4208 cvarray_type = *pCVArrayFormat;
4209 switch (cvarray_type)
4211 case RPC_FC_CVARRAY:
4212 esize = *(const WORD*)(pCVArrayFormat+2);
4213 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4214 break;
4215 case RPC_FC_C_CSTRING:
4216 esize = sizeof(char);
4217 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4218 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4219 else
4220 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4221 break;
4222 case RPC_FC_C_WSTRING:
4223 esize = sizeof(WCHAR);
4224 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4225 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4226 else
4227 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4228 break;
4229 default:
4230 ERR("invalid array format type %x\n", *pCVArrayFormat);
4231 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4232 return NULL;
4235 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4237 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4239 /* work out how much memory to allocate if we need to do so */
4240 if (!*ppMemory || fMustAlloc)
4242 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4243 *ppMemory = NdrAllocate(pStubMsg, size);
4246 /* copy the constant data */
4247 pStubMsg->BufferMark = pStubMsg->Buffer;
4248 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
4250 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4252 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4254 if ((cvarray_type == RPC_FC_C_CSTRING) ||
4255 (cvarray_type == RPC_FC_C_WSTRING))
4257 ULONG i;
4258 /* strings must always have null terminating bytes */
4259 if (bufsize < esize)
4261 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
4262 RpcRaiseException(RPC_S_INVALID_BOUND);
4263 return NULL;
4265 for (i = bufsize - esize; i < bufsize; i++)
4266 if (pStubMsg->Buffer[i] != 0)
4268 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
4269 i, pStubMsg->Buffer[i]);
4270 RpcRaiseException(RPC_S_INVALID_BOUND);
4271 return NULL;
4275 /* copy the array data */
4276 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
4278 if (cvarray_type == RPC_FC_C_CSTRING)
4279 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4280 else if (cvarray_type == RPC_FC_C_WSTRING)
4281 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4283 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4285 return NULL;
4288 /***********************************************************************
4289 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4291 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4292 unsigned char *pMemory,
4293 PFORMAT_STRING pFormat)
4295 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4296 PFORMAT_STRING pCVArrayFormat;
4297 ULONG esize;
4299 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4301 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4302 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4304 ERR("invalid format type %x\n", pCVStructFormat->type);
4305 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4306 return;
4309 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4310 pCVStructFormat->offset_to_array_description;
4311 switch (*pCVArrayFormat)
4313 case RPC_FC_CVARRAY:
4314 esize = *(const WORD*)(pCVArrayFormat+2);
4316 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4317 pCVArrayFormat + 4, 0);
4318 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4319 pCVArrayFormat, 0);
4320 break;
4321 case RPC_FC_C_CSTRING:
4322 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4323 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4324 esize = sizeof(char);
4325 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4326 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4327 pCVArrayFormat + 2, 0);
4328 else
4329 pStubMsg->MaxCount = pStubMsg->ActualCount;
4330 break;
4331 case RPC_FC_C_WSTRING:
4332 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4333 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4334 esize = sizeof(WCHAR);
4335 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4336 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4337 pCVArrayFormat + 2, 0);
4338 else
4339 pStubMsg->MaxCount = pStubMsg->ActualCount;
4340 break;
4341 default:
4342 ERR("invalid array format type %x\n", *pCVArrayFormat);
4343 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4344 return;
4347 SizeConformance(pStubMsg);
4349 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4351 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4353 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4354 SizeVariance(pStubMsg);
4355 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4357 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4360 /***********************************************************************
4361 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4363 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4364 PFORMAT_STRING pFormat)
4366 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4367 PFORMAT_STRING pCVArrayFormat;
4368 ULONG esize;
4369 unsigned char cvarray_type;
4371 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4373 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4374 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4376 ERR("invalid format type %x\n", pCVStructFormat->type);
4377 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4378 return 0;
4381 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4382 pCVStructFormat->offset_to_array_description;
4383 cvarray_type = *pCVArrayFormat;
4384 switch (cvarray_type)
4386 case RPC_FC_CVARRAY:
4387 esize = *(const WORD*)(pCVArrayFormat+2);
4388 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4389 break;
4390 case RPC_FC_C_CSTRING:
4391 esize = sizeof(char);
4392 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4393 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4394 else
4395 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4396 break;
4397 case RPC_FC_C_WSTRING:
4398 esize = sizeof(WCHAR);
4399 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4400 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4401 else
4402 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4403 break;
4404 default:
4405 ERR("invalid array format type %x\n", *pCVArrayFormat);
4406 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4407 return 0;
4410 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4412 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4414 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4415 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4416 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4418 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4420 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4422 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4425 /***********************************************************************
4426 * NdrConformantVaryingStructFree [RPCRT4.@]
4428 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4429 unsigned char *pMemory,
4430 PFORMAT_STRING pFormat)
4432 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4433 PFORMAT_STRING pCVArrayFormat;
4434 ULONG esize;
4436 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4438 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4439 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4441 ERR("invalid format type %x\n", pCVStructFormat->type);
4442 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4443 return;
4446 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4447 pCVStructFormat->offset_to_array_description;
4448 switch (*pCVArrayFormat)
4450 case RPC_FC_CVARRAY:
4451 esize = *(const WORD*)(pCVArrayFormat+2);
4453 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4454 pCVArrayFormat + 4, 0);
4455 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4456 pCVArrayFormat, 0);
4457 break;
4458 case RPC_FC_C_CSTRING:
4459 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4460 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4461 esize = sizeof(char);
4462 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4463 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4464 pCVArrayFormat + 2, 0);
4465 else
4466 pStubMsg->MaxCount = pStubMsg->ActualCount;
4467 break;
4468 case RPC_FC_C_WSTRING:
4469 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4470 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4471 esize = sizeof(WCHAR);
4472 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4473 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4474 pCVArrayFormat + 2, 0);
4475 else
4476 pStubMsg->MaxCount = pStubMsg->ActualCount;
4477 break;
4478 default:
4479 ERR("invalid array format type %x\n", *pCVArrayFormat);
4480 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4481 return;
4484 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4486 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4489 #include "pshpack1.h"
4490 typedef struct
4492 unsigned char type;
4493 unsigned char alignment;
4494 unsigned short total_size;
4495 } NDR_SMFARRAY_FORMAT;
4497 typedef struct
4499 unsigned char type;
4500 unsigned char alignment;
4501 unsigned long total_size;
4502 } NDR_LGFARRAY_FORMAT;
4503 #include "poppack.h"
4505 /***********************************************************************
4506 * NdrFixedArrayMarshall [RPCRT4.@]
4508 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4509 unsigned char *pMemory,
4510 PFORMAT_STRING pFormat)
4512 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4513 unsigned long total_size;
4515 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4517 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4518 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4520 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4521 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4522 return NULL;
4525 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4527 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4529 total_size = pSmFArrayFormat->total_size;
4530 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4532 else
4534 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4535 total_size = pLgFArrayFormat->total_size;
4536 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4539 pStubMsg->BufferMark = pStubMsg->Buffer;
4540 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4542 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4544 return NULL;
4547 /***********************************************************************
4548 * NdrFixedArrayUnmarshall [RPCRT4.@]
4550 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4551 unsigned char **ppMemory,
4552 PFORMAT_STRING pFormat,
4553 unsigned char fMustAlloc)
4555 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4556 unsigned long total_size;
4557 unsigned char *saved_buffer;
4559 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4561 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4562 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4564 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4565 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4566 return NULL;
4569 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4571 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4573 total_size = pSmFArrayFormat->total_size;
4574 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4576 else
4578 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4579 total_size = pLgFArrayFormat->total_size;
4580 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4583 if (fMustAlloc)
4584 *ppMemory = NdrAllocate(pStubMsg, total_size);
4585 else
4587 if (!pStubMsg->IsClient && !*ppMemory)
4588 /* for servers, we just point straight into the RPC buffer */
4589 *ppMemory = pStubMsg->Buffer;
4592 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4593 safe_buffer_increment(pStubMsg, total_size);
4594 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4596 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4597 if (*ppMemory != saved_buffer)
4598 memcpy(*ppMemory, saved_buffer, total_size);
4600 return NULL;
4603 /***********************************************************************
4604 * NdrFixedArrayBufferSize [RPCRT4.@]
4606 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4607 unsigned char *pMemory,
4608 PFORMAT_STRING pFormat)
4610 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4611 unsigned long total_size;
4613 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4615 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4616 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4618 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4619 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4620 return;
4623 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4625 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4627 total_size = pSmFArrayFormat->total_size;
4628 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4630 else
4632 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4633 total_size = pLgFArrayFormat->total_size;
4634 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4636 safe_buffer_length_increment(pStubMsg, total_size);
4638 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4641 /***********************************************************************
4642 * NdrFixedArrayMemorySize [RPCRT4.@]
4644 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4645 PFORMAT_STRING pFormat)
4647 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4648 ULONG total_size;
4650 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4652 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4653 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4655 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4656 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4657 return 0;
4660 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4662 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4664 total_size = pSmFArrayFormat->total_size;
4665 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4667 else
4669 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4670 total_size = pLgFArrayFormat->total_size;
4671 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4673 pStubMsg->BufferMark = pStubMsg->Buffer;
4674 safe_buffer_increment(pStubMsg, total_size);
4675 pStubMsg->MemorySize += total_size;
4677 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4679 return total_size;
4682 /***********************************************************************
4683 * NdrFixedArrayFree [RPCRT4.@]
4685 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4686 unsigned char *pMemory,
4687 PFORMAT_STRING pFormat)
4689 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4691 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4693 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4694 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4696 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4697 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4698 return;
4701 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4702 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4703 else
4705 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4706 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4709 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4712 /***********************************************************************
4713 * NdrVaryingArrayMarshall [RPCRT4.@]
4715 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4716 unsigned char *pMemory,
4717 PFORMAT_STRING pFormat)
4719 unsigned char alignment;
4720 DWORD elements, esize;
4721 ULONG bufsize;
4723 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4725 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4726 (pFormat[0] != RPC_FC_LGVARRAY))
4728 ERR("invalid format type %x\n", pFormat[0]);
4729 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4730 return NULL;
4733 alignment = pFormat[1] + 1;
4735 if (pFormat[0] == RPC_FC_SMVARRAY)
4737 pFormat += 2;
4738 pFormat += sizeof(WORD);
4739 elements = *(const WORD*)pFormat;
4740 pFormat += sizeof(WORD);
4742 else
4744 pFormat += 2;
4745 pFormat += sizeof(DWORD);
4746 elements = *(const DWORD*)pFormat;
4747 pFormat += sizeof(DWORD);
4750 esize = *(const WORD*)pFormat;
4751 pFormat += sizeof(WORD);
4753 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4754 if ((pStubMsg->ActualCount > elements) ||
4755 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4757 RpcRaiseException(RPC_S_INVALID_BOUND);
4758 return NULL;
4761 WriteVariance(pStubMsg);
4763 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4765 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4766 pStubMsg->BufferMark = pStubMsg->Buffer;
4767 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4769 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4771 return NULL;
4774 /***********************************************************************
4775 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4777 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4778 unsigned char **ppMemory,
4779 PFORMAT_STRING pFormat,
4780 unsigned char fMustAlloc)
4782 unsigned char alignment;
4783 DWORD size, elements, esize;
4784 ULONG bufsize;
4785 unsigned char *saved_buffer;
4786 ULONG offset;
4788 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4790 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4791 (pFormat[0] != RPC_FC_LGVARRAY))
4793 ERR("invalid format type %x\n", pFormat[0]);
4794 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4795 return NULL;
4798 alignment = pFormat[1] + 1;
4800 if (pFormat[0] == RPC_FC_SMVARRAY)
4802 pFormat += 2;
4803 size = *(const WORD*)pFormat;
4804 pFormat += sizeof(WORD);
4805 elements = *(const WORD*)pFormat;
4806 pFormat += sizeof(WORD);
4808 else
4810 pFormat += 2;
4811 size = *(const DWORD*)pFormat;
4812 pFormat += sizeof(DWORD);
4813 elements = *(const DWORD*)pFormat;
4814 pFormat += sizeof(DWORD);
4817 esize = *(const WORD*)pFormat;
4818 pFormat += sizeof(WORD);
4820 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4822 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4824 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4825 offset = pStubMsg->Offset;
4827 if (!*ppMemory || fMustAlloc)
4828 *ppMemory = NdrAllocate(pStubMsg, size);
4829 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4830 safe_buffer_increment(pStubMsg, bufsize);
4832 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4834 memcpy(*ppMemory + offset, saved_buffer, bufsize);
4836 return NULL;
4839 /***********************************************************************
4840 * NdrVaryingArrayBufferSize [RPCRT4.@]
4842 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4843 unsigned char *pMemory,
4844 PFORMAT_STRING pFormat)
4846 unsigned char alignment;
4847 DWORD elements, esize;
4849 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4851 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4852 (pFormat[0] != RPC_FC_LGVARRAY))
4854 ERR("invalid format type %x\n", pFormat[0]);
4855 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4856 return;
4859 alignment = pFormat[1] + 1;
4861 if (pFormat[0] == RPC_FC_SMVARRAY)
4863 pFormat += 2;
4864 pFormat += sizeof(WORD);
4865 elements = *(const WORD*)pFormat;
4866 pFormat += sizeof(WORD);
4868 else
4870 pFormat += 2;
4871 pFormat += sizeof(DWORD);
4872 elements = *(const DWORD*)pFormat;
4873 pFormat += sizeof(DWORD);
4876 esize = *(const WORD*)pFormat;
4877 pFormat += sizeof(WORD);
4879 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4880 if ((pStubMsg->ActualCount > elements) ||
4881 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4883 RpcRaiseException(RPC_S_INVALID_BOUND);
4884 return;
4887 SizeVariance(pStubMsg);
4889 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4891 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4893 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4896 /***********************************************************************
4897 * NdrVaryingArrayMemorySize [RPCRT4.@]
4899 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4900 PFORMAT_STRING pFormat)
4902 unsigned char alignment;
4903 DWORD size, elements, esize;
4905 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4907 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4908 (pFormat[0] != RPC_FC_LGVARRAY))
4910 ERR("invalid format type %x\n", pFormat[0]);
4911 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4912 return 0;
4915 alignment = pFormat[1] + 1;
4917 if (pFormat[0] == RPC_FC_SMVARRAY)
4919 pFormat += 2;
4920 size = *(const WORD*)pFormat;
4921 pFormat += sizeof(WORD);
4922 elements = *(const WORD*)pFormat;
4923 pFormat += sizeof(WORD);
4925 else
4927 pFormat += 2;
4928 size = *(const DWORD*)pFormat;
4929 pFormat += sizeof(DWORD);
4930 elements = *(const DWORD*)pFormat;
4931 pFormat += sizeof(DWORD);
4934 esize = *(const WORD*)pFormat;
4935 pFormat += sizeof(WORD);
4937 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4939 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4941 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4942 pStubMsg->MemorySize += size;
4944 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4946 return pStubMsg->MemorySize;
4949 /***********************************************************************
4950 * NdrVaryingArrayFree [RPCRT4.@]
4952 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4953 unsigned char *pMemory,
4954 PFORMAT_STRING pFormat)
4956 unsigned char alignment;
4957 DWORD elements;
4959 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4961 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4962 (pFormat[0] != RPC_FC_LGVARRAY))
4964 ERR("invalid format type %x\n", pFormat[0]);
4965 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4966 return;
4969 alignment = pFormat[1] + 1;
4971 if (pFormat[0] == RPC_FC_SMVARRAY)
4973 pFormat += 2;
4974 pFormat += sizeof(WORD);
4975 elements = *(const WORD*)pFormat;
4976 pFormat += sizeof(WORD);
4978 else
4980 pFormat += 2;
4981 pFormat += sizeof(DWORD);
4982 elements = *(const DWORD*)pFormat;
4983 pFormat += sizeof(DWORD);
4986 pFormat += sizeof(WORD);
4988 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4989 if ((pStubMsg->ActualCount > elements) ||
4990 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4992 RpcRaiseException(RPC_S_INVALID_BOUND);
4993 return;
4996 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4999 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5001 switch (fc)
5003 case RPC_FC_BYTE:
5004 case RPC_FC_CHAR:
5005 case RPC_FC_SMALL:
5006 case RPC_FC_USMALL:
5007 return *pMemory;
5008 case RPC_FC_WCHAR:
5009 case RPC_FC_SHORT:
5010 case RPC_FC_USHORT:
5011 case RPC_FC_ENUM16:
5012 return *(const USHORT *)pMemory;
5013 case RPC_FC_LONG:
5014 case RPC_FC_ULONG:
5015 case RPC_FC_ENUM32:
5016 return *(const ULONG *)pMemory;
5017 default:
5018 FIXME("Unhandled base type: 0x%02x\n", fc);
5019 return 0;
5023 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5024 unsigned long discriminant,
5025 PFORMAT_STRING pFormat)
5027 unsigned short num_arms, arm, type;
5029 num_arms = *(const SHORT*)pFormat & 0x0fff;
5030 pFormat += 2;
5031 for(arm = 0; arm < num_arms; arm++)
5033 if(discriminant == *(const ULONG*)pFormat)
5035 pFormat += 4;
5036 break;
5038 pFormat += 6;
5041 type = *(const unsigned short*)pFormat;
5042 TRACE("type %04x\n", type);
5043 if(arm == num_arms) /* default arm extras */
5045 if(type == 0xffff)
5047 ERR("no arm for 0x%lx and no default case\n", discriminant);
5048 RpcRaiseException(RPC_S_INVALID_TAG);
5049 return NULL;
5051 if(type == 0)
5053 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5054 return NULL;
5057 return pFormat;
5060 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5062 unsigned short type;
5064 pFormat += 2;
5066 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5067 if(!pFormat)
5068 return NULL;
5070 type = *(const unsigned short*)pFormat;
5071 if((type & 0xff00) == 0x8000)
5073 unsigned char basetype = LOBYTE(type);
5074 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5076 else
5078 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5079 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5080 if (m)
5082 unsigned char *saved_buffer = NULL;
5083 int pointer_buffer_mark_set = 0;
5084 switch(*desc)
5086 case RPC_FC_RP:
5087 case RPC_FC_UP:
5088 case RPC_FC_OP:
5089 case RPC_FC_FP:
5090 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5091 saved_buffer = pStubMsg->Buffer;
5092 if (pStubMsg->PointerBufferMark)
5094 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5095 pStubMsg->PointerBufferMark = NULL;
5096 pointer_buffer_mark_set = 1;
5098 else
5099 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5101 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5102 if (pointer_buffer_mark_set)
5104 STD_OVERFLOW_CHECK(pStubMsg);
5105 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5106 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5108 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5109 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5110 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5112 pStubMsg->Buffer = saved_buffer + 4;
5114 break;
5115 default:
5116 m(pStubMsg, pMemory, desc);
5119 else FIXME("no marshaller for embedded type %02x\n", *desc);
5121 return NULL;
5124 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5125 unsigned char **ppMemory,
5126 ULONG discriminant,
5127 PFORMAT_STRING pFormat,
5128 unsigned char fMustAlloc)
5130 unsigned short type;
5132 pFormat += 2;
5134 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5135 if(!pFormat)
5136 return NULL;
5138 type = *(const unsigned short*)pFormat;
5139 if((type & 0xff00) == 0x8000)
5141 unsigned char basetype = LOBYTE(type);
5142 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5144 else
5146 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5147 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5148 if (m)
5150 unsigned char *saved_buffer = NULL;
5151 int pointer_buffer_mark_set = 0;
5152 switch(*desc)
5154 case RPC_FC_RP:
5155 case RPC_FC_UP:
5156 case RPC_FC_OP:
5157 case RPC_FC_FP:
5158 **(void***)ppMemory = NULL;
5159 ALIGN_POINTER(pStubMsg->Buffer, 4);
5160 saved_buffer = pStubMsg->Buffer;
5161 if (pStubMsg->PointerBufferMark)
5163 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5164 pStubMsg->PointerBufferMark = NULL;
5165 pointer_buffer_mark_set = 1;
5167 else
5168 pStubMsg->Buffer += 4; /* for pointer ID */
5170 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5172 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5173 saved_buffer, pStubMsg->BufferEnd);
5174 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5177 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5178 if (pointer_buffer_mark_set)
5180 STD_OVERFLOW_CHECK(pStubMsg);
5181 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5182 pStubMsg->Buffer = saved_buffer + 4;
5184 break;
5185 default:
5186 m(pStubMsg, ppMemory, desc, fMustAlloc);
5189 else FIXME("no marshaller for embedded type %02x\n", *desc);
5191 return NULL;
5194 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5195 unsigned char *pMemory,
5196 ULONG discriminant,
5197 PFORMAT_STRING pFormat)
5199 unsigned short type;
5201 pFormat += 2;
5203 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5204 if(!pFormat)
5205 return;
5207 type = *(const unsigned short*)pFormat;
5208 if((type & 0xff00) == 0x8000)
5210 unsigned char basetype = LOBYTE(type);
5211 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5213 else
5215 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5216 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5217 if (m)
5219 switch(*desc)
5221 case RPC_FC_RP:
5222 case RPC_FC_UP:
5223 case RPC_FC_OP:
5224 case RPC_FC_FP:
5225 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5226 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5227 if (!pStubMsg->IgnoreEmbeddedPointers)
5229 int saved_buffer_length = pStubMsg->BufferLength;
5230 pStubMsg->BufferLength = pStubMsg->PointerLength;
5231 pStubMsg->PointerLength = 0;
5232 if(!pStubMsg->BufferLength)
5233 ERR("BufferLength == 0??\n");
5234 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5235 pStubMsg->PointerLength = pStubMsg->BufferLength;
5236 pStubMsg->BufferLength = saved_buffer_length;
5238 break;
5239 default:
5240 m(pStubMsg, pMemory, desc);
5243 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5247 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5248 ULONG discriminant,
5249 PFORMAT_STRING pFormat)
5251 unsigned short type, size;
5253 size = *(const unsigned short*)pFormat;
5254 pStubMsg->Memory += size;
5255 pFormat += 2;
5257 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5258 if(!pFormat)
5259 return 0;
5261 type = *(const unsigned short*)pFormat;
5262 if((type & 0xff00) == 0x8000)
5264 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5266 else
5268 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5269 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5270 unsigned char *saved_buffer;
5271 if (m)
5273 switch(*desc)
5275 case RPC_FC_RP:
5276 case RPC_FC_UP:
5277 case RPC_FC_OP:
5278 case RPC_FC_FP:
5279 ALIGN_POINTER(pStubMsg->Buffer, 4);
5280 saved_buffer = pStubMsg->Buffer;
5281 safe_buffer_increment(pStubMsg, 4);
5282 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5283 pStubMsg->MemorySize += 4;
5284 if (!pStubMsg->IgnoreEmbeddedPointers)
5285 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5286 break;
5287 default:
5288 return m(pStubMsg, desc);
5291 else FIXME("no marshaller for embedded type %02x\n", *desc);
5294 TRACE("size %d\n", size);
5295 return size;
5298 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5299 unsigned char *pMemory,
5300 ULONG discriminant,
5301 PFORMAT_STRING pFormat)
5303 unsigned short type;
5305 pFormat += 2;
5307 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5308 if(!pFormat)
5309 return;
5311 type = *(const unsigned short*)pFormat;
5312 if((type & 0xff00) != 0x8000)
5314 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5315 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5316 if (m)
5318 switch(*desc)
5320 case RPC_FC_RP:
5321 case RPC_FC_UP:
5322 case RPC_FC_OP:
5323 case RPC_FC_FP:
5324 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5325 break;
5326 default:
5327 m(pStubMsg, pMemory, desc);
5333 /***********************************************************************
5334 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5336 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5337 unsigned char *pMemory,
5338 PFORMAT_STRING pFormat)
5340 unsigned char switch_type;
5341 unsigned char increment;
5342 ULONG switch_value;
5344 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5345 pFormat++;
5347 switch_type = *pFormat & 0xf;
5348 increment = (*pFormat & 0xf0) >> 4;
5349 pFormat++;
5351 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5353 switch_value = get_discriminant(switch_type, pMemory);
5354 TRACE("got switch value 0x%x\n", switch_value);
5356 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5357 pMemory += increment;
5359 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5362 /***********************************************************************
5363 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5365 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5366 unsigned char **ppMemory,
5367 PFORMAT_STRING pFormat,
5368 unsigned char fMustAlloc)
5370 unsigned char switch_type;
5371 unsigned char increment;
5372 ULONG switch_value;
5373 unsigned short size;
5374 unsigned char *pMemoryArm;
5376 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5377 pFormat++;
5379 switch_type = *pFormat & 0xf;
5380 increment = (*pFormat & 0xf0) >> 4;
5381 pFormat++;
5383 ALIGN_POINTER(pStubMsg->Buffer, increment);
5384 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5385 TRACE("got switch value 0x%x\n", switch_value);
5387 size = *(const unsigned short*)pFormat + increment;
5388 if(!*ppMemory || fMustAlloc)
5389 *ppMemory = NdrAllocate(pStubMsg, size);
5391 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5392 pMemoryArm = *ppMemory + increment;
5394 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5397 /***********************************************************************
5398 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5400 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5401 unsigned char *pMemory,
5402 PFORMAT_STRING pFormat)
5404 unsigned char switch_type;
5405 unsigned char increment;
5406 ULONG switch_value;
5408 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5409 pFormat++;
5411 switch_type = *pFormat & 0xf;
5412 increment = (*pFormat & 0xf0) >> 4;
5413 pFormat++;
5415 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5416 switch_value = get_discriminant(switch_type, pMemory);
5417 TRACE("got switch value 0x%x\n", switch_value);
5419 /* Add discriminant size */
5420 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5421 pMemory += increment;
5423 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5426 /***********************************************************************
5427 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5429 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5430 PFORMAT_STRING pFormat)
5432 unsigned char switch_type;
5433 unsigned char increment;
5434 ULONG switch_value;
5436 switch_type = *pFormat & 0xf;
5437 increment = (*pFormat & 0xf0) >> 4;
5438 pFormat++;
5440 ALIGN_POINTER(pStubMsg->Buffer, increment);
5441 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5442 TRACE("got switch value 0x%x\n", switch_value);
5444 pStubMsg->Memory += increment;
5446 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5449 /***********************************************************************
5450 * NdrEncapsulatedUnionFree [RPCRT4.@]
5452 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5453 unsigned char *pMemory,
5454 PFORMAT_STRING pFormat)
5456 unsigned char switch_type;
5457 unsigned char increment;
5458 ULONG switch_value;
5460 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5461 pFormat++;
5463 switch_type = *pFormat & 0xf;
5464 increment = (*pFormat & 0xf0) >> 4;
5465 pFormat++;
5467 switch_value = get_discriminant(switch_type, pMemory);
5468 TRACE("got switch value 0x%x\n", switch_value);
5470 pMemory += increment;
5472 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5475 /***********************************************************************
5476 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5478 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5479 unsigned char *pMemory,
5480 PFORMAT_STRING pFormat)
5482 unsigned char switch_type;
5484 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5485 pFormat++;
5487 switch_type = *pFormat;
5488 pFormat++;
5490 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5491 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5492 /* Marshall discriminant */
5493 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5495 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5498 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5499 PFORMAT_STRING *ppFormat)
5501 long discriminant = 0;
5503 switch(**ppFormat)
5505 case RPC_FC_BYTE:
5506 case RPC_FC_CHAR:
5507 case RPC_FC_SMALL:
5508 case RPC_FC_USMALL:
5510 UCHAR d;
5511 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5512 discriminant = d;
5513 break;
5515 case RPC_FC_WCHAR:
5516 case RPC_FC_SHORT:
5517 case RPC_FC_USHORT:
5519 USHORT d;
5520 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5521 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5522 discriminant = d;
5523 break;
5525 case RPC_FC_LONG:
5526 case RPC_FC_ULONG:
5528 ULONG d;
5529 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5530 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5531 discriminant = d;
5532 break;
5534 default:
5535 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5537 (*ppFormat)++;
5539 if (pStubMsg->fHasNewCorrDesc)
5540 *ppFormat += 6;
5541 else
5542 *ppFormat += 4;
5543 return discriminant;
5546 /**********************************************************************
5547 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5549 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5550 unsigned char **ppMemory,
5551 PFORMAT_STRING pFormat,
5552 unsigned char fMustAlloc)
5554 long discriminant;
5555 unsigned short size;
5557 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5558 pFormat++;
5560 /* Unmarshall discriminant */
5561 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5562 TRACE("unmarshalled discriminant %lx\n", discriminant);
5564 pFormat += *(const SHORT*)pFormat;
5566 size = *(const unsigned short*)pFormat;
5568 if(!*ppMemory || fMustAlloc)
5569 *ppMemory = NdrAllocate(pStubMsg, size);
5571 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5574 /***********************************************************************
5575 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5577 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5578 unsigned char *pMemory,
5579 PFORMAT_STRING pFormat)
5581 unsigned char switch_type;
5583 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5584 pFormat++;
5586 switch_type = *pFormat;
5587 pFormat++;
5589 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5590 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5591 /* Add discriminant size */
5592 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5594 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5597 /***********************************************************************
5598 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5600 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5601 PFORMAT_STRING pFormat)
5603 ULONG discriminant;
5605 pFormat++;
5606 /* Unmarshall discriminant */
5607 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5608 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5610 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5613 /***********************************************************************
5614 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5616 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5617 unsigned char *pMemory,
5618 PFORMAT_STRING pFormat)
5620 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5621 pFormat++;
5622 pFormat++;
5624 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5625 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5627 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5630 /***********************************************************************
5631 * NdrByteCountPointerMarshall [RPCRT4.@]
5633 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5634 unsigned char *pMemory,
5635 PFORMAT_STRING pFormat)
5637 FIXME("stub\n");
5638 return NULL;
5641 /***********************************************************************
5642 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5644 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5645 unsigned char **ppMemory,
5646 PFORMAT_STRING pFormat,
5647 unsigned char fMustAlloc)
5649 FIXME("stub\n");
5650 return NULL;
5653 /***********************************************************************
5654 * NdrByteCountPointerBufferSize [RPCRT4.@]
5656 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5657 unsigned char *pMemory,
5658 PFORMAT_STRING pFormat)
5660 FIXME("stub\n");
5663 /***********************************************************************
5664 * NdrByteCountPointerMemorySize [RPCRT4.@]
5666 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5667 PFORMAT_STRING pFormat)
5669 FIXME("stub\n");
5670 return 0;
5673 /***********************************************************************
5674 * NdrByteCountPointerFree [RPCRT4.@]
5676 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5677 unsigned char *pMemory,
5678 PFORMAT_STRING pFormat)
5680 FIXME("stub\n");
5683 /***********************************************************************
5684 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5686 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5687 unsigned char *pMemory,
5688 PFORMAT_STRING pFormat)
5690 FIXME("stub\n");
5691 return NULL;
5694 /***********************************************************************
5695 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5697 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5698 unsigned char **ppMemory,
5699 PFORMAT_STRING pFormat,
5700 unsigned char fMustAlloc)
5702 FIXME("stub\n");
5703 return NULL;
5706 /***********************************************************************
5707 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5709 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5710 unsigned char *pMemory,
5711 PFORMAT_STRING pFormat)
5713 FIXME("stub\n");
5716 /***********************************************************************
5717 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5719 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5720 PFORMAT_STRING pFormat)
5722 FIXME("stub\n");
5723 return 0;
5726 /***********************************************************************
5727 * NdrXmitOrRepAsFree [RPCRT4.@]
5729 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5730 unsigned char *pMemory,
5731 PFORMAT_STRING pFormat)
5733 FIXME("stub\n");
5736 #include "pshpack1.h"
5737 typedef struct
5739 unsigned char type;
5740 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5741 ULONG low_value;
5742 ULONG high_value;
5743 } NDR_RANGE;
5744 #include "poppack.h"
5746 /***********************************************************************
5747 * NdrRangeMarshall [internal]
5749 unsigned char *WINAPI NdrRangeMarshall(
5750 PMIDL_STUB_MESSAGE pStubMsg,
5751 unsigned char *pMemory,
5752 PFORMAT_STRING pFormat)
5754 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5755 unsigned char base_type;
5757 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5759 if (pRange->type != RPC_FC_RANGE)
5761 ERR("invalid format type %x\n", pRange->type);
5762 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5763 return NULL;
5766 base_type = pRange->flags_type & 0xf;
5768 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5771 /***********************************************************************
5772 * NdrRangeUnmarshall
5774 unsigned char *WINAPI NdrRangeUnmarshall(
5775 PMIDL_STUB_MESSAGE pStubMsg,
5776 unsigned char **ppMemory,
5777 PFORMAT_STRING pFormat,
5778 unsigned char fMustAlloc)
5780 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5781 unsigned char base_type;
5783 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5785 if (pRange->type != RPC_FC_RANGE)
5787 ERR("invalid format type %x\n", pRange->type);
5788 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5789 return NULL;
5791 base_type = pRange->flags_type & 0xf;
5793 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5794 base_type, pRange->low_value, pRange->high_value);
5796 #define RANGE_UNMARSHALL(type, format_spec) \
5797 do \
5799 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5800 if (fMustAlloc || !*ppMemory) \
5801 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5802 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5804 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5805 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5806 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5808 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5809 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5811 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5812 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5813 (type)pRange->high_value); \
5814 RpcRaiseException(RPC_S_INVALID_BOUND); \
5815 return NULL; \
5817 TRACE("*ppMemory: %p\n", *ppMemory); \
5818 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5819 pStubMsg->Buffer += sizeof(type); \
5820 } while (0)
5822 switch(base_type)
5824 case RPC_FC_CHAR:
5825 case RPC_FC_SMALL:
5826 RANGE_UNMARSHALL(UCHAR, "%d");
5827 TRACE("value: 0x%02x\n", **ppMemory);
5828 break;
5829 case RPC_FC_BYTE:
5830 case RPC_FC_USMALL:
5831 RANGE_UNMARSHALL(CHAR, "%u");
5832 TRACE("value: 0x%02x\n", **ppMemory);
5833 break;
5834 case RPC_FC_WCHAR: /* FIXME: valid? */
5835 case RPC_FC_USHORT:
5836 RANGE_UNMARSHALL(USHORT, "%u");
5837 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5838 break;
5839 case RPC_FC_SHORT:
5840 RANGE_UNMARSHALL(SHORT, "%d");
5841 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5842 break;
5843 case RPC_FC_LONG:
5844 RANGE_UNMARSHALL(LONG, "%d");
5845 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5846 break;
5847 case RPC_FC_ULONG:
5848 RANGE_UNMARSHALL(ULONG, "%u");
5849 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5850 break;
5851 case RPC_FC_ENUM16:
5852 case RPC_FC_ENUM32:
5853 FIXME("Unhandled enum type\n");
5854 break;
5855 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5856 case RPC_FC_FLOAT:
5857 case RPC_FC_DOUBLE:
5858 case RPC_FC_HYPER:
5859 default:
5860 ERR("invalid range base type: 0x%02x\n", base_type);
5861 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5864 return NULL;
5867 /***********************************************************************
5868 * NdrRangeBufferSize [internal]
5870 void WINAPI NdrRangeBufferSize(
5871 PMIDL_STUB_MESSAGE pStubMsg,
5872 unsigned char *pMemory,
5873 PFORMAT_STRING pFormat)
5875 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5876 unsigned char base_type;
5878 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5880 if (pRange->type != RPC_FC_RANGE)
5882 ERR("invalid format type %x\n", pRange->type);
5883 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5885 base_type = pRange->flags_type & 0xf;
5887 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5890 /***********************************************************************
5891 * NdrRangeMemorySize [internal]
5893 ULONG WINAPI NdrRangeMemorySize(
5894 PMIDL_STUB_MESSAGE pStubMsg,
5895 PFORMAT_STRING pFormat)
5897 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5898 unsigned char base_type;
5900 if (pRange->type != RPC_FC_RANGE)
5902 ERR("invalid format type %x\n", pRange->type);
5903 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5904 return 0;
5906 base_type = pRange->flags_type & 0xf;
5908 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5911 /***********************************************************************
5912 * NdrRangeFree [internal]
5914 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5915 unsigned char *pMemory,
5916 PFORMAT_STRING pFormat)
5918 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5920 /* nothing to do */
5923 /***********************************************************************
5924 * NdrBaseTypeMarshall [internal]
5926 static unsigned char *WINAPI NdrBaseTypeMarshall(
5927 PMIDL_STUB_MESSAGE pStubMsg,
5928 unsigned char *pMemory,
5929 PFORMAT_STRING pFormat)
5931 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5933 switch(*pFormat)
5935 case RPC_FC_BYTE:
5936 case RPC_FC_CHAR:
5937 case RPC_FC_SMALL:
5938 case RPC_FC_USMALL:
5939 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5940 TRACE("value: 0x%02x\n", *pMemory);
5941 break;
5942 case RPC_FC_WCHAR:
5943 case RPC_FC_SHORT:
5944 case RPC_FC_USHORT:
5945 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5946 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5947 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5948 break;
5949 case RPC_FC_LONG:
5950 case RPC_FC_ULONG:
5951 case RPC_FC_ERROR_STATUS_T:
5952 case RPC_FC_ENUM32:
5953 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
5954 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5955 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5956 break;
5957 case RPC_FC_FLOAT:
5958 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
5959 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5960 break;
5961 case RPC_FC_DOUBLE:
5962 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
5963 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5964 break;
5965 case RPC_FC_HYPER:
5966 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
5967 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5968 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5969 break;
5970 case RPC_FC_ENUM16:
5971 /* only 16-bits on the wire, so do a sanity check */
5972 if (*(UINT *)pMemory > SHRT_MAX)
5973 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5974 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5975 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5976 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5977 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5978 pStubMsg->Buffer += sizeof(USHORT);
5979 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5980 break;
5981 case RPC_FC_IGNORE:
5982 break;
5983 default:
5984 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5987 /* FIXME: what is the correct return value? */
5988 return NULL;
5991 /***********************************************************************
5992 * NdrBaseTypeUnmarshall [internal]
5994 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5995 PMIDL_STUB_MESSAGE pStubMsg,
5996 unsigned char **ppMemory,
5997 PFORMAT_STRING pFormat,
5998 unsigned char fMustAlloc)
6000 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6002 #define BASE_TYPE_UNMARSHALL(type) \
6003 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6004 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6006 *ppMemory = pStubMsg->Buffer; \
6007 TRACE("*ppMemory: %p\n", *ppMemory); \
6009 else \
6011 if (fMustAlloc) \
6012 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6013 TRACE("*ppMemory: %p\n", *ppMemory); \
6014 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6016 pStubMsg->Buffer += sizeof(type);
6018 switch(*pFormat)
6020 case RPC_FC_BYTE:
6021 case RPC_FC_CHAR:
6022 case RPC_FC_SMALL:
6023 case RPC_FC_USMALL:
6024 BASE_TYPE_UNMARSHALL(UCHAR);
6025 TRACE("value: 0x%02x\n", **ppMemory);
6026 break;
6027 case RPC_FC_WCHAR:
6028 case RPC_FC_SHORT:
6029 case RPC_FC_USHORT:
6030 BASE_TYPE_UNMARSHALL(USHORT);
6031 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6032 break;
6033 case RPC_FC_LONG:
6034 case RPC_FC_ULONG:
6035 case RPC_FC_ERROR_STATUS_T:
6036 case RPC_FC_ENUM32:
6037 BASE_TYPE_UNMARSHALL(ULONG);
6038 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6039 break;
6040 case RPC_FC_FLOAT:
6041 BASE_TYPE_UNMARSHALL(float);
6042 TRACE("value: %f\n", **(float **)ppMemory);
6043 break;
6044 case RPC_FC_DOUBLE:
6045 BASE_TYPE_UNMARSHALL(double);
6046 TRACE("value: %f\n", **(double **)ppMemory);
6047 break;
6048 case RPC_FC_HYPER:
6049 BASE_TYPE_UNMARSHALL(ULONGLONG);
6050 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6051 break;
6052 case RPC_FC_ENUM16:
6053 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6054 if (fMustAlloc || !*ppMemory)
6055 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6056 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6057 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6058 TRACE("*ppMemory: %p\n", *ppMemory);
6059 /* 16-bits on the wire, but int in memory */
6060 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6061 pStubMsg->Buffer += sizeof(USHORT);
6062 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6063 break;
6064 case RPC_FC_IGNORE:
6065 break;
6066 default:
6067 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6069 #undef BASE_TYPE_UNMARSHALL
6071 /* FIXME: what is the correct return value? */
6073 return NULL;
6076 /***********************************************************************
6077 * NdrBaseTypeBufferSize [internal]
6079 static void WINAPI NdrBaseTypeBufferSize(
6080 PMIDL_STUB_MESSAGE pStubMsg,
6081 unsigned char *pMemory,
6082 PFORMAT_STRING pFormat)
6084 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6086 switch(*pFormat)
6088 case RPC_FC_BYTE:
6089 case RPC_FC_CHAR:
6090 case RPC_FC_SMALL:
6091 case RPC_FC_USMALL:
6092 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6093 break;
6094 case RPC_FC_WCHAR:
6095 case RPC_FC_SHORT:
6096 case RPC_FC_USHORT:
6097 case RPC_FC_ENUM16:
6098 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6099 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6100 break;
6101 case RPC_FC_LONG:
6102 case RPC_FC_ULONG:
6103 case RPC_FC_ENUM32:
6104 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6105 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6106 break;
6107 case RPC_FC_FLOAT:
6108 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6109 safe_buffer_length_increment(pStubMsg, sizeof(float));
6110 break;
6111 case RPC_FC_DOUBLE:
6112 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6113 safe_buffer_length_increment(pStubMsg, sizeof(double));
6114 break;
6115 case RPC_FC_HYPER:
6116 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6117 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6118 break;
6119 case RPC_FC_ERROR_STATUS_T:
6120 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6121 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6122 break;
6123 case RPC_FC_IGNORE:
6124 break;
6125 default:
6126 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6130 /***********************************************************************
6131 * NdrBaseTypeMemorySize [internal]
6133 static ULONG WINAPI NdrBaseTypeMemorySize(
6134 PMIDL_STUB_MESSAGE pStubMsg,
6135 PFORMAT_STRING pFormat)
6137 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6139 switch(*pFormat)
6141 case RPC_FC_BYTE:
6142 case RPC_FC_CHAR:
6143 case RPC_FC_SMALL:
6144 case RPC_FC_USMALL:
6145 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6146 pStubMsg->MemorySize += sizeof(UCHAR);
6147 return sizeof(UCHAR);
6148 case RPC_FC_WCHAR:
6149 case RPC_FC_SHORT:
6150 case RPC_FC_USHORT:
6151 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6152 pStubMsg->MemorySize += sizeof(USHORT);
6153 return sizeof(USHORT);
6154 case RPC_FC_LONG:
6155 case RPC_FC_ULONG:
6156 case RPC_FC_ENUM32:
6157 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6158 pStubMsg->MemorySize += sizeof(ULONG);
6159 return sizeof(ULONG);
6160 case RPC_FC_FLOAT:
6161 safe_buffer_increment(pStubMsg, sizeof(float));
6162 pStubMsg->MemorySize += sizeof(float);
6163 return sizeof(float);
6164 case RPC_FC_DOUBLE:
6165 safe_buffer_increment(pStubMsg, sizeof(double));
6166 pStubMsg->MemorySize += sizeof(double);
6167 return sizeof(double);
6168 case RPC_FC_HYPER:
6169 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6170 pStubMsg->MemorySize += sizeof(ULONGLONG);
6171 return sizeof(ULONGLONG);
6172 case RPC_FC_ERROR_STATUS_T:
6173 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6174 pStubMsg->MemorySize += sizeof(error_status_t);
6175 return sizeof(error_status_t);
6176 case RPC_FC_ENUM16:
6177 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6178 pStubMsg->MemorySize += sizeof(UINT);
6179 return sizeof(UINT);
6180 case RPC_FC_IGNORE:
6181 pStubMsg->MemorySize += sizeof(void *);
6182 return sizeof(void *);
6183 default:
6184 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6185 return 0;
6189 /***********************************************************************
6190 * NdrBaseTypeFree [internal]
6192 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6193 unsigned char *pMemory,
6194 PFORMAT_STRING pFormat)
6196 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6198 /* nothing to do */
6201 /***********************************************************************
6202 * NdrContextHandleBufferSize [internal]
6204 static void WINAPI NdrContextHandleBufferSize(
6205 PMIDL_STUB_MESSAGE pStubMsg,
6206 unsigned char *pMemory,
6207 PFORMAT_STRING pFormat)
6209 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6211 if (*pFormat != RPC_FC_BIND_CONTEXT)
6213 ERR("invalid format type %x\n", *pFormat);
6214 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6216 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6217 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6220 /***********************************************************************
6221 * NdrContextHandleMarshall [internal]
6223 static unsigned char *WINAPI NdrContextHandleMarshall(
6224 PMIDL_STUB_MESSAGE pStubMsg,
6225 unsigned char *pMemory,
6226 PFORMAT_STRING pFormat)
6228 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6230 if (*pFormat != RPC_FC_BIND_CONTEXT)
6232 ERR("invalid format type %x\n", *pFormat);
6233 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6235 TRACE("flags: 0x%02x\n", pFormat[1]);
6237 if (pFormat[1] & 0x80)
6238 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6239 else
6240 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6242 return NULL;
6245 /***********************************************************************
6246 * NdrContextHandleUnmarshall [internal]
6248 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6249 PMIDL_STUB_MESSAGE pStubMsg,
6250 unsigned char **ppMemory,
6251 PFORMAT_STRING pFormat,
6252 unsigned char fMustAlloc)
6254 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6255 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6257 if (*pFormat != RPC_FC_BIND_CONTEXT)
6259 ERR("invalid format type %x\n", *pFormat);
6260 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6262 TRACE("flags: 0x%02x\n", pFormat[1]);
6264 /* [out]-only or [ret] param */
6265 if ((pFormat[1] & 0x60) == 0x20)
6266 **(NDR_CCONTEXT **)ppMemory = NULL;
6267 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6269 return NULL;
6272 /***********************************************************************
6273 * NdrClientContextMarshall [RPCRT4.@]
6275 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6276 NDR_CCONTEXT ContextHandle,
6277 int fCheck)
6279 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6281 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6283 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6285 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6286 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6287 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6290 /* FIXME: what does fCheck do? */
6291 NDRCContextMarshall(ContextHandle,
6292 pStubMsg->Buffer);
6294 pStubMsg->Buffer += cbNDRContext;
6297 /***********************************************************************
6298 * NdrClientContextUnmarshall [RPCRT4.@]
6300 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6301 NDR_CCONTEXT * pContextHandle,
6302 RPC_BINDING_HANDLE BindHandle)
6304 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6306 ALIGN_POINTER(pStubMsg->Buffer, 4);
6308 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6309 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6311 NDRCContextUnmarshall(pContextHandle,
6312 BindHandle,
6313 pStubMsg->Buffer,
6314 pStubMsg->RpcMsg->DataRepresentation);
6316 pStubMsg->Buffer += cbNDRContext;
6319 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6320 NDR_SCONTEXT ContextHandle,
6321 NDR_RUNDOWN RundownRoutine )
6323 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6325 ALIGN_POINTER(pStubMsg->Buffer, 4);
6327 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6329 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6330 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6331 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6334 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6335 pStubMsg->Buffer, RundownRoutine, NULL,
6336 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6337 pStubMsg->Buffer += cbNDRContext;
6340 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6342 NDR_SCONTEXT ContextHandle;
6344 TRACE("(%p)\n", pStubMsg);
6346 ALIGN_POINTER(pStubMsg->Buffer, 4);
6348 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6350 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6351 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6352 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6355 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6356 pStubMsg->Buffer,
6357 pStubMsg->RpcMsg->DataRepresentation,
6358 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6359 pStubMsg->Buffer += cbNDRContext;
6361 return ContextHandle;
6364 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6365 unsigned char* pMemory,
6366 PFORMAT_STRING pFormat)
6368 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6371 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6372 PFORMAT_STRING pFormat)
6374 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6375 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6377 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6379 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6380 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6381 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6382 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6383 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6385 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6386 if_id = &sif->InterfaceId;
6389 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6390 pStubMsg->RpcMsg->DataRepresentation, if_id,
6391 flags);
6394 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6395 NDR_SCONTEXT ContextHandle,
6396 NDR_RUNDOWN RundownRoutine,
6397 PFORMAT_STRING pFormat)
6399 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6400 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6402 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6404 ALIGN_POINTER(pStubMsg->Buffer, 4);
6406 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6408 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6409 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6410 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6413 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6414 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6415 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6416 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6417 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6419 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6420 if_id = &sif->InterfaceId;
6423 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6424 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6425 pStubMsg->Buffer += cbNDRContext;
6428 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6429 PFORMAT_STRING pFormat)
6431 NDR_SCONTEXT ContextHandle;
6432 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6433 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6435 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6437 ALIGN_POINTER(pStubMsg->Buffer, 4);
6439 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6441 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6442 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6443 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6446 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6447 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6448 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6449 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6450 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6452 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6453 if_id = &sif->InterfaceId;
6456 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6457 pStubMsg->Buffer,
6458 pStubMsg->RpcMsg->DataRepresentation,
6459 if_id, flags);
6460 pStubMsg->Buffer += cbNDRContext;
6462 return ContextHandle;
6465 /***********************************************************************
6466 * NdrCorrelationInitialize [RPCRT4.@]
6468 * Initializes correlation validity checking.
6470 * PARAMS
6471 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6472 * pMemory [I] Pointer to memory to use as a cache.
6473 * CacheSize [I] Size of the memory pointed to by pMemory.
6474 * Flags [I] Reserved. Set to zero.
6476 * RETURNS
6477 * Nothing.
6479 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6481 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6482 pStubMsg->fHasNewCorrDesc = TRUE;
6485 /***********************************************************************
6486 * NdrCorrelationPass [RPCRT4.@]
6488 * Performs correlation validity checking.
6490 * PARAMS
6491 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6493 * RETURNS
6494 * Nothing.
6496 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6498 FIXME("(%p): stub\n", pStubMsg);
6501 /***********************************************************************
6502 * NdrCorrelationFree [RPCRT4.@]
6504 * Frees any resources used while unmarshalling parameters that need
6505 * correlation validity checking.
6507 * PARAMS
6508 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6510 * RETURNS
6511 * Nothing.
6513 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6515 FIXME("(%p): stub\n", pStubMsg);