Changes in crossover-wine-src-6.1.0 except for configure
[wine/hacks.git] / dlls / rpcrt4 / ndr_marshall.c
blobd7c5b131221ec62d3b9f314d47f2e767c0557bd0
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 * - Non-conformant strings
23 * - String structs
24 * - Encapsulated unions
25 * - Byte count pointers
26 * - transmit_as/represent as
27 * - Multi-dimensional arrays
28 * - Conversion functions (NdrConvert)
29 * - Checks for integer addition overflow
30 * - Checks for out-of-memory conditions
33 #include <stdarg.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <assert.h>
37 #include <limits.h>
39 #include "windef.h"
40 #include "winbase.h"
41 #include "winerror.h"
42 #include "winreg.h"
44 #include "ndr_misc.h"
45 #include "rpcndr.h"
47 #include "wine/unicode.h"
48 #include "wine/rpcfc.h"
50 #include "wine/debug.h"
51 #include "wine/list.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(ole);
55 #if defined(__i386__)
56 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
57 (*((UINT32 *)(pchar)) = (uint32))
59 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
60 (*((UINT32 *)(pchar)))
61 #else
62 /* these would work for i386 too, but less efficient */
63 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
64 (*(pchar) = LOBYTE(LOWORD(uint32)), \
65 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
66 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
67 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
68 (uint32)) /* allow as r-value */
70 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
71 (MAKELONG( \
72 MAKEWORD(*(pchar), *((pchar)+1)), \
73 MAKEWORD(*((pchar)+2), *((pchar)+3))))
74 #endif
76 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
77 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
78 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
79 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
80 *(pchar) = HIBYTE(HIWORD(uint32)), \
81 (uint32)) /* allow as r-value */
83 #define BIG_ENDIAN_UINT32_READ(pchar) \
84 (MAKELONG( \
85 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
86 MAKEWORD(*((pchar)+1), *(pchar))))
88 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 BIG_ENDIAN_UINT32_READ(pchar)
93 #else
94 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
95 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
96 # define NDR_LOCAL_UINT32_READ(pchar) \
97 LITTLE_ENDIAN_UINT32_READ(pchar)
98 #endif
100 /* _Align must be the desired alignment,
101 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
102 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
103 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
104 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
105 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
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 NdrRangeMarshall
167 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
169 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
170 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 /* 0x10 */
174 NdrBaseTypeUnmarshall,
175 /* 0x11 */
176 NdrPointerUnmarshall, NdrPointerUnmarshall,
177 NdrPointerUnmarshall, NdrPointerUnmarshall,
178 /* 0x15 */
179 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
180 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
181 NdrConformantVaryingStructUnmarshall,
182 NdrComplexStructUnmarshall,
183 /* 0x1b */
184 NdrConformantArrayUnmarshall,
185 NdrConformantVaryingArrayUnmarshall,
186 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
187 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
188 NdrComplexArrayUnmarshall,
189 /* 0x22 */
190 NdrConformantStringUnmarshall, 0, 0,
191 NdrConformantStringUnmarshall,
192 NdrNonConformantStringUnmarshall, 0, 0, 0,
193 /* 0x2a */
194 NdrEncapsulatedUnionUnmarshall,
195 NdrNonEncapsulatedUnionUnmarshall,
196 NdrByteCountPointerUnmarshall,
197 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
198 /* 0x2f */
199 NdrInterfacePointerUnmarshall,
200 /* 0x30 */
201 NdrContextHandleUnmarshall,
202 /* 0xb1 */
203 0, 0, 0,
204 NdrUserMarshalUnmarshall,
205 0, 0,
206 NdrRangeUnmarshall
208 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
210 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
211 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
212 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 /* 0x10 */
215 NdrBaseTypeBufferSize,
216 /* 0x11 */
217 NdrPointerBufferSize, NdrPointerBufferSize,
218 NdrPointerBufferSize, NdrPointerBufferSize,
219 /* 0x15 */
220 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
221 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
222 NdrConformantVaryingStructBufferSize,
223 NdrComplexStructBufferSize,
224 /* 0x1b */
225 NdrConformantArrayBufferSize,
226 NdrConformantVaryingArrayBufferSize,
227 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
228 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
229 NdrComplexArrayBufferSize,
230 /* 0x22 */
231 NdrConformantStringBufferSize, 0, 0,
232 NdrConformantStringBufferSize,
233 NdrNonConformantStringBufferSize, 0, 0, 0,
234 /* 0x2a */
235 NdrEncapsulatedUnionBufferSize,
236 NdrNonEncapsulatedUnionBufferSize,
237 NdrByteCountPointerBufferSize,
238 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
239 /* 0x2f */
240 NdrInterfacePointerBufferSize,
241 /* 0x30 */
242 NdrContextHandleBufferSize,
243 /* 0xb1 */
244 0, 0, 0,
245 NdrUserMarshalBufferSize,
246 0, 0,
247 NdrRangeBufferSize
249 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
251 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
252 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
253 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
254 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
255 /* 0x10 */
256 NdrBaseTypeMemorySize,
257 /* 0x11 */
258 NdrPointerMemorySize, NdrPointerMemorySize,
259 NdrPointerMemorySize, NdrPointerMemorySize,
260 /* 0x15 */
261 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
262 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
263 NdrConformantVaryingStructMemorySize,
264 NdrComplexStructMemorySize,
265 /* 0x1b */
266 NdrConformantArrayMemorySize,
267 NdrConformantVaryingArrayMemorySize,
268 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
269 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
270 NdrComplexArrayMemorySize,
271 /* 0x22 */
272 NdrConformantStringMemorySize, 0, 0,
273 NdrConformantStringMemorySize,
274 NdrNonConformantStringMemorySize, 0, 0, 0,
275 /* 0x2a */
276 NdrEncapsulatedUnionMemorySize,
277 NdrNonEncapsulatedUnionMemorySize,
278 NdrByteCountPointerMemorySize,
279 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
280 /* 0x2f */
281 NdrInterfacePointerMemorySize,
282 /* 0xb0 */
283 0, 0, 0, 0,
284 NdrUserMarshalMemorySize,
285 0, 0,
286 NdrRangeMemorySize
288 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
290 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
291 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
292 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
293 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
294 /* 0x10 */
295 NdrBaseTypeFree,
296 /* 0x11 */
297 NdrPointerFree, NdrPointerFree,
298 NdrPointerFree, NdrPointerFree,
299 /* 0x15 */
300 NdrSimpleStructFree, NdrSimpleStructFree,
301 NdrConformantStructFree, NdrConformantStructFree,
302 NdrConformantVaryingStructFree,
303 NdrComplexStructFree,
304 /* 0x1b */
305 NdrConformantArrayFree,
306 NdrConformantVaryingArrayFree,
307 NdrFixedArrayFree, NdrFixedArrayFree,
308 NdrVaryingArrayFree, NdrVaryingArrayFree,
309 NdrComplexArrayFree,
310 /* 0x22 */
311 0, 0, 0,
312 0, 0, 0, 0, 0,
313 /* 0x2a */
314 NdrEncapsulatedUnionFree,
315 NdrNonEncapsulatedUnionFree,
317 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
318 /* 0x2f */
319 NdrInterfacePointerFree,
320 /* 0xb0 */
321 0, 0, 0, 0,
322 NdrUserMarshalFree,
323 0, 0,
324 NdrRangeFree
327 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
329 /* hmm, this is probably supposed to do more? */
330 return pStubMsg->pfnAllocate(len);
333 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
335 pStubMsg->pfnFree(Pointer);
338 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
340 return (*(const ULONG *)pFormat != -1);
343 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
345 ALIGN_POINTER(pStubMsg->Buffer, 4);
346 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
347 pStubMsg->Buffer += 4;
348 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
349 if (pStubMsg->fHasNewCorrDesc)
350 return pFormat+6;
351 else
352 return pFormat+4;
355 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
357 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
359 pStubMsg->Offset = 0;
360 pStubMsg->ActualCount = pStubMsg->MaxCount;
361 goto done;
364 ALIGN_POINTER(pStubMsg->Buffer, 4);
365 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
366 pStubMsg->Buffer += 4;
367 TRACE("offset is %d\n", pStubMsg->Offset);
368 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
369 pStubMsg->Buffer += 4;
370 TRACE("variance is %d\n", pStubMsg->ActualCount);
372 if ((pStubMsg->ActualCount > MaxValue) ||
373 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
375 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
376 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
377 RpcRaiseException(RPC_S_INVALID_BOUND);
378 return NULL;
381 done:
382 if (pStubMsg->fHasNewCorrDesc)
383 return pFormat+6;
384 else
385 return pFormat+4;
388 /* writes the conformance value to the buffer */
389 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
391 ALIGN_POINTER(pStubMsg->Buffer, 4);
392 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
393 pStubMsg->Buffer += 4;
396 /* writes the variance values to the buffer */
397 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
399 ALIGN_POINTER(pStubMsg->Buffer, 4);
400 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
401 pStubMsg->Buffer += 4;
402 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
403 pStubMsg->Buffer += 4;
406 /* requests buffer space for the conformance value */
407 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
409 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
410 pStubMsg->BufferLength += 4;
413 /* requests buffer space for the variance values */
414 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
416 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
417 pStubMsg->BufferLength += 8;
420 PFORMAT_STRING ComputeConformanceOrVariance(
421 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
422 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
424 BYTE dtype = pFormat[0] & 0xf;
425 short ofs = *(const short *)&pFormat[2];
426 LPVOID ptr = NULL;
427 DWORD data = 0;
429 if (!IsConformanceOrVariancePresent(pFormat)) {
430 /* null descriptor */
431 *pCount = def;
432 goto finish_conf;
435 switch (pFormat[0] & 0xf0) {
436 case RPC_FC_NORMAL_CONFORMANCE:
437 TRACE("normal conformance, ofs=%d\n", ofs);
438 ptr = pMemory;
439 break;
440 case RPC_FC_POINTER_CONFORMANCE:
441 TRACE("pointer conformance, ofs=%d\n", ofs);
442 ptr = pStubMsg->Memory;
443 break;
444 case RPC_FC_TOP_LEVEL_CONFORMANCE:
445 TRACE("toplevel conformance, ofs=%d\n", ofs);
446 if (pStubMsg->StackTop) {
447 ptr = pStubMsg->StackTop;
449 else {
450 /* -Os mode, *pCount is already set */
451 goto finish_conf;
453 break;
454 case RPC_FC_CONSTANT_CONFORMANCE:
455 data = ofs | ((DWORD)pFormat[1] << 16);
456 TRACE("constant conformance, val=%d\n", data);
457 *pCount = data;
458 goto finish_conf;
459 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
460 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
461 if (pStubMsg->StackTop) {
462 ptr = pStubMsg->StackTop;
464 else {
465 /* ? */
466 goto done_conf_grab;
468 break;
469 default:
470 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
473 switch (pFormat[1]) {
474 case RPC_FC_DEREFERENCE:
475 ptr = *(LPVOID*)((char *)ptr + ofs);
476 break;
477 case RPC_FC_CALLBACK:
479 unsigned char *old_stack_top = pStubMsg->StackTop;
480 pStubMsg->StackTop = ptr;
482 /* ofs is index into StubDesc->apfnExprEval */
483 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
484 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
486 pStubMsg->StackTop = old_stack_top;
488 /* the callback function always stores the computed value in MaxCount */
489 *pCount = pStubMsg->MaxCount;
490 goto finish_conf;
492 default:
493 ptr = (char *)ptr + ofs;
494 break;
497 switch (dtype) {
498 case RPC_FC_LONG:
499 case RPC_FC_ULONG:
500 data = *(DWORD*)ptr;
501 break;
502 case RPC_FC_SHORT:
503 data = *(SHORT*)ptr;
504 break;
505 case RPC_FC_USHORT:
506 data = *(USHORT*)ptr;
507 break;
508 case RPC_FC_CHAR:
509 case RPC_FC_SMALL:
510 data = *(CHAR*)ptr;
511 break;
512 case RPC_FC_BYTE:
513 case RPC_FC_USMALL:
514 data = *(UCHAR*)ptr;
515 break;
516 default:
517 FIXME("unknown conformance data type %x\n", dtype);
518 goto done_conf_grab;
520 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
522 done_conf_grab:
523 switch (pFormat[1]) {
524 case RPC_FC_DEREFERENCE: /* already handled */
525 case 0: /* no op */
526 *pCount = data;
527 break;
528 case RPC_FC_ADD_1:
529 *pCount = data + 1;
530 break;
531 case RPC_FC_SUB_1:
532 *pCount = data - 1;
533 break;
534 case RPC_FC_MULT_2:
535 *pCount = data * 2;
536 break;
537 case RPC_FC_DIV_2:
538 *pCount = data / 2;
539 break;
540 default:
541 FIXME("unknown conformance op %d\n", pFormat[1]);
542 goto finish_conf;
545 finish_conf:
546 TRACE("resulting conformance is %ld\n", *pCount);
547 if (pStubMsg->fHasNewCorrDesc)
548 return pFormat+6;
549 else
550 return pFormat+4;
553 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
554 * the result overflows 32-bits */
555 static inline ULONG safe_multiply(ULONG a, ULONG b)
557 ULONGLONG ret = (ULONGLONG)a * b;
558 if (ret > 0xffffffff)
560 RpcRaiseException(RPC_S_INVALID_BOUND);
561 return 0;
563 return ret;
568 * NdrConformantString:
570 * What MS calls a ConformantString is, in DCE terminology,
571 * a Varying-Conformant String.
573 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
574 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
575 * into unmarshalled string)
576 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
577 * [
578 * data: CHARTYPE[maxlen]
579 * ]
580 * ], where CHARTYPE is the appropriate character type (specified externally)
584 /***********************************************************************
585 * NdrConformantStringMarshall [RPCRT4.@]
587 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
588 unsigned char *pszMessage, PFORMAT_STRING pFormat)
590 ULONG esize, size;
592 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
594 if (*pFormat == RPC_FC_C_CSTRING) {
595 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
596 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
597 esize = 1;
599 else if (*pFormat == RPC_FC_C_WSTRING) {
600 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
601 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
602 esize = 2;
604 else {
605 ERR("Unhandled string type: %#x\n", *pFormat);
606 /* FIXME: raise an exception. */
607 return NULL;
610 if (pFormat[1] == RPC_FC_STRING_SIZED)
611 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
612 else
613 pStubMsg->MaxCount = pStubMsg->ActualCount;
614 pStubMsg->Offset = 0;
615 WriteConformance(pStubMsg);
616 WriteVariance(pStubMsg);
618 size = safe_multiply(esize, pStubMsg->ActualCount);
619 memcpy(pStubMsg->Buffer, pszMessage, size); /* the string itself */
620 pStubMsg->Buffer += size;
622 STD_OVERFLOW_CHECK(pStubMsg);
624 /* success */
625 return NULL; /* is this always right? */
628 /***********************************************************************
629 * NdrConformantStringBufferSize [RPCRT4.@]
631 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
632 unsigned char* pMemory, PFORMAT_STRING pFormat)
634 ULONG esize;
636 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
638 SizeConformance(pStubMsg);
639 SizeVariance(pStubMsg);
641 if (*pFormat == RPC_FC_C_CSTRING) {
642 TRACE("string=%s\n", debugstr_a((char*)pMemory));
643 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
644 esize = 1;
646 else if (*pFormat == RPC_FC_C_WSTRING) {
647 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
648 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
649 esize = 2;
651 else {
652 ERR("Unhandled string type: %#x\n", *pFormat);
653 /* FIXME: raise an exception */
654 return;
657 if (pFormat[1] == RPC_FC_STRING_SIZED)
658 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
659 else
660 pStubMsg->MaxCount = pStubMsg->ActualCount;
662 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
665 /************************************************************************
666 * NdrConformantStringMemorySize [RPCRT4.@]
668 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
669 PFORMAT_STRING pFormat )
671 ULONG rslt = 0;
673 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
675 assert(pStubMsg && pFormat);
677 if (*pFormat == RPC_FC_C_CSTRING) {
678 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
680 else if (*pFormat == RPC_FC_C_WSTRING) {
681 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
683 else {
684 ERR("Unhandled string type: %#x\n", *pFormat);
685 /* FIXME: raise an exception */
688 if (pFormat[1] != RPC_FC_PAD) {
689 FIXME("sized string format=%d\n", pFormat[1]);
692 TRACE(" --> %u\n", rslt);
693 return rslt;
696 /************************************************************************
697 * NdrConformantStringUnmarshall [RPCRT4.@]
699 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
700 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
702 ULONG bufsize, memsize, esize, i;
704 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
705 pStubMsg, *ppMemory, pFormat, fMustAlloc);
707 assert(pFormat && ppMemory && pStubMsg);
709 ReadConformance(pStubMsg, NULL);
710 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
712 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
713 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
714 else {
715 ERR("Unhandled string type: %#x\n", *pFormat);
716 /* FIXME: raise an exception */
717 esize = 0;
720 memsize = safe_multiply(esize, pStubMsg->MaxCount);
721 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
723 /* strings must always have null terminating bytes */
724 if (bufsize < esize)
726 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
727 RpcRaiseException(RPC_S_INVALID_BOUND);
728 return NULL;
730 for (i = bufsize - esize; i < bufsize; i++)
731 if (pStubMsg->Buffer[i] != 0)
733 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
734 i, pStubMsg->Buffer[i]);
735 RpcRaiseException(RPC_S_INVALID_BOUND);
736 return NULL;
739 if (fMustAlloc || !*ppMemory)
740 *ppMemory = NdrAllocate(pStubMsg, memsize);
742 memcpy(*ppMemory, pStubMsg->Buffer, bufsize);
744 pStubMsg->Buffer += bufsize;
746 if (*pFormat == RPC_FC_C_CSTRING) {
747 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
749 else if (*pFormat == RPC_FC_C_WSTRING) {
750 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
753 return NULL; /* FIXME: is this always right? */
756 /***********************************************************************
757 * NdrNonConformantStringMarshall [RPCRT4.@]
759 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
760 unsigned char *pMemory,
761 PFORMAT_STRING pFormat)
763 FIXME("stub\n");
764 return NULL;
767 /***********************************************************************
768 * NdrNonConformantStringUnmarshall [RPCRT4.@]
770 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
771 unsigned char **ppMemory,
772 PFORMAT_STRING pFormat,
773 unsigned char fMustAlloc)
775 FIXME("stub\n");
776 return NULL;
779 /***********************************************************************
780 * NdrNonConformantStringBufferSize [RPCRT4.@]
782 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
783 unsigned char *pMemory,
784 PFORMAT_STRING pFormat)
786 FIXME("stub\n");
789 /***********************************************************************
790 * NdrNonConformantStringMemorySize [RPCRT4.@]
792 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
793 PFORMAT_STRING pFormat)
795 FIXME("stub\n");
796 return 0;
799 static inline void dump_pointer_attr(unsigned char attr)
801 if (attr & RPC_FC_P_ALLOCALLNODES)
802 TRACE(" RPC_FC_P_ALLOCALLNODES");
803 if (attr & RPC_FC_P_DONTFREE)
804 TRACE(" RPC_FC_P_DONTFREE");
805 if (attr & RPC_FC_P_ONSTACK)
806 TRACE(" RPC_FC_P_ONSTACK");
807 if (attr & RPC_FC_P_SIMPLEPOINTER)
808 TRACE(" RPC_FC_P_SIMPLEPOINTER");
809 if (attr & RPC_FC_P_DEREF)
810 TRACE(" RPC_FC_P_DEREF");
811 TRACE("\n");
814 /***********************************************************************
815 * PointerMarshall [internal]
817 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
818 unsigned char *Buffer,
819 unsigned char *Pointer,
820 PFORMAT_STRING pFormat)
822 unsigned type = pFormat[0], attr = pFormat[1];
823 PFORMAT_STRING desc;
824 NDR_MARSHALL m;
825 ULONG pointer_id;
826 int pointer_needs_marshaling;
828 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
829 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
830 pFormat += 2;
831 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
832 else desc = pFormat + *(const SHORT*)pFormat;
834 switch (type) {
835 case RPC_FC_RP: /* ref pointer (always non-null) */
836 if (!Pointer)
838 ERR("NULL ref pointer is not allowed\n");
839 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
840 RpcRaiseException(RPC_X_NULL_REF_POINTER);
841 #endif
843 pointer_needs_marshaling = 1;
844 break;
845 case RPC_FC_UP: /* unique pointer */
846 case RPC_FC_OP: /* object pointer - same as unique here */
847 if (Pointer)
848 pointer_needs_marshaling = 1;
849 else
850 pointer_needs_marshaling = 0;
851 pointer_id = (ULONG)Pointer;
852 TRACE("writing 0x%08x to buffer\n", pointer_id);
853 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
854 break;
855 case RPC_FC_FP:
856 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
857 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
858 TRACE("writing 0x%08x to buffer\n", pointer_id);
859 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
860 break;
861 default:
862 FIXME("unhandled ptr type=%02x\n", type);
863 RpcRaiseException(RPC_X_BAD_STUB_DATA);
864 return;
867 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
869 if (pointer_needs_marshaling) {
870 if (attr & RPC_FC_P_DEREF) {
871 Pointer = *(unsigned char**)Pointer;
872 TRACE("deref => %p\n", Pointer);
874 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
875 if (m) m(pStubMsg, Pointer, desc);
876 else FIXME("no marshaller for data type=%02x\n", *desc);
879 STD_OVERFLOW_CHECK(pStubMsg);
882 /***********************************************************************
883 * PointerUnmarshall [internal]
885 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
886 unsigned char *Buffer,
887 unsigned char **pPointer,
888 PFORMAT_STRING pFormat,
889 unsigned char fMustAlloc)
891 unsigned type = pFormat[0], attr = pFormat[1];
892 PFORMAT_STRING desc;
893 NDR_UNMARSHALL m;
894 DWORD pointer_id = 0;
895 int pointer_needs_unmarshaling;
897 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
898 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
899 pFormat += 2;
900 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
901 else desc = pFormat + *(const SHORT*)pFormat;
903 switch (type) {
904 case RPC_FC_RP: /* ref pointer (always non-null) */
905 pointer_needs_unmarshaling = 1;
906 break;
907 case RPC_FC_UP: /* unique pointer */
908 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
909 TRACE("pointer_id is 0x%08x\n", pointer_id);
910 if (pointer_id)
911 pointer_needs_unmarshaling = 1;
912 else {
913 *pPointer = NULL;
914 pointer_needs_unmarshaling = 0;
916 break;
917 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
918 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
919 TRACE("pointer_id is 0x%08x\n", pointer_id);
920 if (!fMustAlloc && *pPointer)
922 FIXME("free object pointer %p\n", *pPointer);
923 *pPointer = NULL;
925 if (pointer_id)
926 pointer_needs_unmarshaling = 1;
927 else
928 pointer_needs_unmarshaling = 0;
929 break;
930 case RPC_FC_FP:
931 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
932 TRACE("pointer_id is 0x%08x\n", pointer_id);
933 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
934 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
935 break;
936 default:
937 FIXME("unhandled ptr type=%02x\n", type);
938 RpcRaiseException(RPC_X_BAD_STUB_DATA);
939 return;
942 STD_OVERFLOW_CHECK(pStubMsg);
944 if (pointer_needs_unmarshaling) {
945 if (attr & RPC_FC_P_DEREF) {
946 if (!*pPointer || fMustAlloc)
947 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
948 pPointer = *(unsigned char***)pPointer;
949 TRACE("deref => %p\n", pPointer);
951 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
952 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
953 else FIXME("no unmarshaller for data type=%02x\n", *desc);
955 if (type == RPC_FC_FP)
956 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
957 *pPointer);
960 TRACE("pointer=%p\n", *pPointer);
963 /***********************************************************************
964 * PointerBufferSize [internal]
966 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
967 unsigned char *Pointer,
968 PFORMAT_STRING pFormat)
970 unsigned type = pFormat[0], attr = pFormat[1];
971 PFORMAT_STRING desc;
972 NDR_BUFFERSIZE m;
973 int pointer_needs_sizing;
974 ULONG pointer_id;
976 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
977 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
978 pFormat += 2;
979 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
980 else desc = pFormat + *(const SHORT*)pFormat;
982 switch (type) {
983 case RPC_FC_RP: /* ref pointer (always non-null) */
984 break;
985 case RPC_FC_OP:
986 case RPC_FC_UP:
987 /* NULL pointer has no further representation */
988 if (!Pointer)
989 return;
990 break;
991 case RPC_FC_FP:
992 pointer_needs_sizing = !NdrFullPointerQueryPointer(
993 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
994 if (!pointer_needs_sizing)
995 return;
996 break;
997 default:
998 FIXME("unhandled ptr type=%02x\n", type);
999 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1000 return;
1003 if (attr & RPC_FC_P_DEREF) {
1004 Pointer = *(unsigned char**)Pointer;
1005 TRACE("deref => %p\n", Pointer);
1008 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1009 if (m) m(pStubMsg, Pointer, desc);
1010 else FIXME("no buffersizer for data type=%02x\n", *desc);
1013 /***********************************************************************
1014 * PointerMemorySize [internal]
1016 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1017 unsigned char *Buffer,
1018 PFORMAT_STRING pFormat)
1020 unsigned type = pFormat[0], attr = pFormat[1];
1021 PFORMAT_STRING desc;
1022 NDR_MEMORYSIZE m;
1024 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
1025 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1026 pFormat += 2;
1027 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1028 else desc = pFormat + *(const SHORT*)pFormat;
1030 switch (type) {
1031 case RPC_FC_RP: /* ref pointer (always non-null) */
1032 break;
1033 default:
1034 FIXME("unhandled ptr type=%02x\n", type);
1035 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1038 if (attr & RPC_FC_P_DEREF) {
1039 TRACE("deref\n");
1042 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1043 if (m) m(pStubMsg, desc);
1044 else FIXME("no memorysizer for data type=%02x\n", *desc);
1046 return 0;
1049 /***********************************************************************
1050 * PointerFree [internal]
1052 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1053 unsigned char *Pointer,
1054 PFORMAT_STRING pFormat)
1056 unsigned type = pFormat[0], attr = pFormat[1];
1057 PFORMAT_STRING desc;
1058 NDR_FREE m;
1060 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1061 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1062 if (attr & RPC_FC_P_DONTFREE) return;
1063 pFormat += 2;
1064 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1065 else desc = pFormat + *(const SHORT*)pFormat;
1067 if (!Pointer) return;
1069 if (type == RPC_FC_FP) {
1070 int pointer_needs_freeing = NdrFullPointerFree(
1071 pStubMsg->FullPtrXlatTables, Pointer);
1072 if (!pointer_needs_freeing)
1073 return;
1076 if (attr & RPC_FC_P_DEREF) {
1077 Pointer = *(unsigned char**)Pointer;
1078 TRACE("deref => %p\n", Pointer);
1081 m = NdrFreer[*desc & NDR_TABLE_MASK];
1082 if (m) m(pStubMsg, Pointer, desc);
1084 /* hmm... is this sensible?
1085 * perhaps we should check if the memory comes from NdrAllocate,
1086 * and deallocate only if so - checking if the pointer is between
1087 * BufferStart and BufferEnd is probably no good since the buffer
1088 * may be reallocated when the server wants to marshal the reply */
1089 switch (*desc) {
1090 case RPC_FC_BOGUS_STRUCT:
1091 case RPC_FC_BOGUS_ARRAY:
1092 case RPC_FC_USER_MARSHAL:
1093 case RPC_FC_CARRAY:
1094 case RPC_FC_CVARRAY:
1095 break;
1096 default:
1097 FIXME("unhandled data type=%02x\n", *desc);
1098 break;
1099 case RPC_FC_C_CSTRING:
1100 case RPC_FC_C_WSTRING:
1101 if (pStubMsg->ReuseBuffer) goto notfree;
1102 break;
1103 case RPC_FC_IP:
1104 goto notfree;
1107 if (attr & RPC_FC_P_ONSTACK) {
1108 TRACE("not freeing stack ptr %p\n", Pointer);
1109 return;
1111 TRACE("freeing %p\n", Pointer);
1112 NdrFree(pStubMsg, Pointer);
1113 return;
1114 notfree:
1115 TRACE("not freeing %p\n", Pointer);
1118 /***********************************************************************
1119 * EmbeddedPointerMarshall
1121 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1122 unsigned char *pMemory,
1123 PFORMAT_STRING pFormat)
1125 unsigned char *Mark = pStubMsg->BufferMark;
1126 unsigned long Offset = pStubMsg->Offset;
1127 unsigned ofs, rep, count, stride, xofs;
1128 unsigned i;
1129 unsigned char *saved_buffer = NULL;
1131 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1133 if (*pFormat != RPC_FC_PP) return NULL;
1134 pFormat += 2;
1136 if (pStubMsg->PointerBufferMark)
1138 saved_buffer = pStubMsg->Buffer;
1139 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1140 pStubMsg->PointerBufferMark = NULL;
1143 while (pFormat[0] != RPC_FC_END) {
1144 switch (pFormat[0]) {
1145 default:
1146 FIXME("unknown repeat type %d\n", pFormat[0]);
1147 case RPC_FC_NO_REPEAT:
1148 rep = 1;
1149 stride = 0;
1150 ofs = 0;
1151 count = 1;
1152 xofs = 0;
1153 pFormat += 2;
1154 break;
1155 case RPC_FC_FIXED_REPEAT:
1156 rep = *(const WORD*)&pFormat[2];
1157 stride = *(const WORD*)&pFormat[4];
1158 ofs = *(const WORD*)&pFormat[6];
1159 count = *(const WORD*)&pFormat[8];
1160 xofs = 0;
1161 pFormat += 10;
1162 break;
1163 case RPC_FC_VARIABLE_REPEAT:
1164 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1165 stride = *(const WORD*)&pFormat[2];
1166 ofs = *(const WORD*)&pFormat[4];
1167 count = *(const WORD*)&pFormat[6];
1168 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1169 pFormat += 8;
1170 break;
1172 for (i = 0; i < rep; i++) {
1173 PFORMAT_STRING info = pFormat;
1174 unsigned char *membase = pMemory + (i * stride);
1175 unsigned char *bufbase = Mark + (i * stride);
1176 unsigned u;
1177 /* ofs doesn't seem to matter in this context */
1178 for (u=0; u<count; u++,info+=8) {
1179 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1180 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1181 unsigned char *saved_memory = pStubMsg->Memory;
1183 pStubMsg->Memory = pMemory;
1184 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1185 pStubMsg->Memory = saved_memory;
1188 pFormat += 8 * count;
1191 if (saved_buffer)
1193 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1194 pStubMsg->Buffer = saved_buffer;
1197 STD_OVERFLOW_CHECK(pStubMsg);
1199 return NULL;
1202 /***********************************************************************
1203 * EmbeddedPointerUnmarshall
1205 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1206 unsigned char **ppMemory,
1207 PFORMAT_STRING pFormat,
1208 unsigned char fMustAlloc)
1210 unsigned char *Mark = pStubMsg->BufferMark;
1211 unsigned long Offset = pStubMsg->Offset;
1212 unsigned ofs, rep, count, stride, xofs;
1213 unsigned i;
1214 unsigned char *saved_buffer = NULL;
1216 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1218 if (*pFormat != RPC_FC_PP) return NULL;
1219 pFormat += 2;
1221 if (pStubMsg->PointerBufferMark)
1223 saved_buffer = pStubMsg->Buffer;
1224 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1225 pStubMsg->PointerBufferMark = NULL;
1228 while (pFormat[0] != RPC_FC_END) {
1229 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1230 switch (pFormat[0]) {
1231 default:
1232 FIXME("unknown repeat type %d\n", pFormat[0]);
1233 case RPC_FC_NO_REPEAT:
1234 rep = 1;
1235 stride = 0;
1236 ofs = 0;
1237 count = 1;
1238 xofs = 0;
1239 pFormat += 2;
1240 break;
1241 case RPC_FC_FIXED_REPEAT:
1242 rep = *(const WORD*)&pFormat[2];
1243 stride = *(const WORD*)&pFormat[4];
1244 ofs = *(const WORD*)&pFormat[6];
1245 count = *(const WORD*)&pFormat[8];
1246 xofs = 0;
1247 pFormat += 10;
1248 break;
1249 case RPC_FC_VARIABLE_REPEAT:
1250 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1251 stride = *(const WORD*)&pFormat[2];
1252 ofs = *(const WORD*)&pFormat[4];
1253 count = *(const WORD*)&pFormat[6];
1254 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1255 pFormat += 8;
1256 break;
1258 /* ofs doesn't seem to matter in this context */
1259 for (i = 0; i < rep; i++) {
1260 PFORMAT_STRING info = pFormat;
1261 unsigned char *membase = *ppMemory + (i * stride);
1262 unsigned char *bufbase = Mark + (i * stride);
1263 unsigned u;
1264 for (u=0; u<count; u++,info+=8) {
1265 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1266 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1267 *(void **)memptr = NULL;
1268 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, fMustAlloc);
1271 pFormat += 8 * count;
1274 if (saved_buffer)
1276 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1277 pStubMsg->Buffer = saved_buffer;
1280 return NULL;
1283 /***********************************************************************
1284 * EmbeddedPointerBufferSize
1286 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1287 unsigned char *pMemory,
1288 PFORMAT_STRING pFormat)
1290 unsigned long Offset = pStubMsg->Offset;
1291 unsigned ofs, rep, count, stride, xofs;
1292 unsigned i;
1293 ULONG saved_buffer_length = 0;
1295 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1297 if (pStubMsg->IgnoreEmbeddedPointers) return;
1299 if (*pFormat != RPC_FC_PP) return;
1300 pFormat += 2;
1302 if (pStubMsg->PointerLength)
1304 saved_buffer_length = pStubMsg->BufferLength;
1305 pStubMsg->BufferLength = pStubMsg->PointerLength;
1306 pStubMsg->PointerLength = 0;
1309 while (pFormat[0] != RPC_FC_END) {
1310 switch (pFormat[0]) {
1311 default:
1312 FIXME("unknown repeat type %d\n", pFormat[0]);
1313 case RPC_FC_NO_REPEAT:
1314 rep = 1;
1315 stride = 0;
1316 ofs = 0;
1317 count = 1;
1318 xofs = 0;
1319 pFormat += 2;
1320 break;
1321 case RPC_FC_FIXED_REPEAT:
1322 rep = *(const WORD*)&pFormat[2];
1323 stride = *(const WORD*)&pFormat[4];
1324 ofs = *(const WORD*)&pFormat[6];
1325 count = *(const WORD*)&pFormat[8];
1326 xofs = 0;
1327 pFormat += 10;
1328 break;
1329 case RPC_FC_VARIABLE_REPEAT:
1330 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1331 stride = *(const WORD*)&pFormat[2];
1332 ofs = *(const WORD*)&pFormat[4];
1333 count = *(const WORD*)&pFormat[6];
1334 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1335 pFormat += 8;
1336 break;
1338 /* ofs doesn't seem to matter in this context */
1339 for (i = 0; i < rep; i++) {
1340 PFORMAT_STRING info = pFormat;
1341 unsigned char *membase = pMemory + (i * stride);
1342 unsigned u;
1343 for (u=0; u<count; u++,info+=8) {
1344 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1345 unsigned char *saved_memory = pStubMsg->Memory;
1347 pStubMsg->Memory = pMemory;
1348 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1349 pStubMsg->Memory = saved_memory;
1352 pFormat += 8 * count;
1355 if (saved_buffer_length)
1357 pStubMsg->PointerLength = pStubMsg->BufferLength;
1358 pStubMsg->BufferLength = saved_buffer_length;
1362 /***********************************************************************
1363 * EmbeddedPointerMemorySize [internal]
1365 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1366 PFORMAT_STRING pFormat)
1368 unsigned long Offset = pStubMsg->Offset;
1369 unsigned char *Mark = pStubMsg->BufferMark;
1370 unsigned ofs, rep, count, stride, xofs;
1371 unsigned i;
1373 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1375 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1377 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1379 if (*pFormat != RPC_FC_PP) return 0;
1380 pFormat += 2;
1382 while (pFormat[0] != RPC_FC_END) {
1383 switch (pFormat[0]) {
1384 default:
1385 FIXME("unknown repeat type %d\n", pFormat[0]);
1386 case RPC_FC_NO_REPEAT:
1387 rep = 1;
1388 stride = 0;
1389 ofs = 0;
1390 count = 1;
1391 xofs = 0;
1392 pFormat += 2;
1393 break;
1394 case RPC_FC_FIXED_REPEAT:
1395 rep = *(const WORD*)&pFormat[2];
1396 stride = *(const WORD*)&pFormat[4];
1397 ofs = *(const WORD*)&pFormat[6];
1398 count = *(const WORD*)&pFormat[8];
1399 xofs = 0;
1400 pFormat += 10;
1401 break;
1402 case RPC_FC_VARIABLE_REPEAT:
1403 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1404 stride = *(const WORD*)&pFormat[2];
1405 ofs = *(const WORD*)&pFormat[4];
1406 count = *(const WORD*)&pFormat[6];
1407 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1408 pFormat += 8;
1409 break;
1411 /* ofs doesn't seem to matter in this context */
1412 for (i = 0; i < rep; i++) {
1413 PFORMAT_STRING info = pFormat;
1414 unsigned char *bufbase = Mark + (i * stride);
1415 unsigned u;
1416 for (u=0; u<count; u++,info+=8) {
1417 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1418 PointerMemorySize(pStubMsg, bufptr, info+4);
1421 pFormat += 8 * count;
1424 return 0;
1427 /***********************************************************************
1428 * EmbeddedPointerFree [internal]
1430 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1431 unsigned char *pMemory,
1432 PFORMAT_STRING pFormat)
1434 unsigned long Offset = pStubMsg->Offset;
1435 unsigned ofs, rep, count, stride, xofs;
1436 unsigned i;
1438 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1439 if (*pFormat != RPC_FC_PP) return;
1440 pFormat += 2;
1442 while (pFormat[0] != RPC_FC_END) {
1443 switch (pFormat[0]) {
1444 default:
1445 FIXME("unknown repeat type %d\n", pFormat[0]);
1446 case RPC_FC_NO_REPEAT:
1447 rep = 1;
1448 stride = 0;
1449 ofs = 0;
1450 count = 1;
1451 xofs = 0;
1452 pFormat += 2;
1453 break;
1454 case RPC_FC_FIXED_REPEAT:
1455 rep = *(const WORD*)&pFormat[2];
1456 stride = *(const WORD*)&pFormat[4];
1457 ofs = *(const WORD*)&pFormat[6];
1458 count = *(const WORD*)&pFormat[8];
1459 xofs = 0;
1460 pFormat += 10;
1461 break;
1462 case RPC_FC_VARIABLE_REPEAT:
1463 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1464 stride = *(const WORD*)&pFormat[2];
1465 ofs = *(const WORD*)&pFormat[4];
1466 count = *(const WORD*)&pFormat[6];
1467 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1468 pFormat += 8;
1469 break;
1471 /* ofs doesn't seem to matter in this context */
1472 for (i = 0; i < rep; i++) {
1473 PFORMAT_STRING info = pFormat;
1474 unsigned char *membase = pMemory + (i * stride);
1475 unsigned u;
1476 for (u=0; u<count; u++,info+=8) {
1477 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1478 unsigned char *saved_memory = pStubMsg->Memory;
1480 pStubMsg->Memory = pMemory;
1481 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1482 pStubMsg->Memory = saved_memory;
1485 pFormat += 8 * count;
1489 /***********************************************************************
1490 * NdrPointerMarshall [RPCRT4.@]
1492 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1493 unsigned char *pMemory,
1494 PFORMAT_STRING pFormat)
1496 unsigned char *Buffer;
1498 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1500 /* incremement the buffer here instead of in PointerMarshall,
1501 * as that is used by embedded pointers which already handle the incrementing
1502 * the buffer, and shouldn't write any additional pointer data to the wire */
1503 if (*pFormat != RPC_FC_RP)
1505 ALIGN_POINTER(pStubMsg->Buffer, 4);
1506 Buffer = pStubMsg->Buffer;
1507 pStubMsg->Buffer += 4;
1509 else
1510 Buffer = pStubMsg->Buffer;
1512 STD_OVERFLOW_CHECK(pStubMsg);
1514 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1516 STD_OVERFLOW_CHECK(pStubMsg);
1518 return NULL;
1521 /***********************************************************************
1522 * NdrPointerUnmarshall [RPCRT4.@]
1524 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1525 unsigned char **ppMemory,
1526 PFORMAT_STRING pFormat,
1527 unsigned char fMustAlloc)
1529 unsigned char *Buffer;
1531 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1533 STD_OVERFLOW_CHECK(pStubMsg);
1535 /* incremement the buffer here instead of in PointerUnmarshall,
1536 * as that is used by embedded pointers which already handle the incrementing
1537 * the buffer, and shouldn't read any additional pointer data from the
1538 * buffer */
1539 if (*pFormat != RPC_FC_RP)
1541 ALIGN_POINTER(pStubMsg->Buffer, 4);
1542 Buffer = pStubMsg->Buffer;
1543 pStubMsg->Buffer += 4;
1545 else
1546 Buffer = pStubMsg->Buffer;
1548 STD_OVERFLOW_CHECK(pStubMsg);
1550 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1552 return NULL;
1555 /***********************************************************************
1556 * NdrPointerBufferSize [RPCRT4.@]
1558 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1559 unsigned char *pMemory,
1560 PFORMAT_STRING pFormat)
1562 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1564 /* incremement the buffer length here instead of in PointerBufferSize,
1565 * as that is used by embedded pointers which already handle the buffer
1566 * length, and shouldn't write anything more to the wire */
1567 if (*pFormat != RPC_FC_RP)
1569 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1570 pStubMsg->BufferLength += 4;
1573 PointerBufferSize(pStubMsg, pMemory, pFormat);
1576 /***********************************************************************
1577 * NdrPointerMemorySize [RPCRT4.@]
1579 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1580 PFORMAT_STRING pFormat)
1582 /* unsigned size = *(LPWORD)(pFormat+2); */
1583 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1584 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1585 return 0;
1588 /***********************************************************************
1589 * NdrPointerFree [RPCRT4.@]
1591 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1592 unsigned char *pMemory,
1593 PFORMAT_STRING pFormat)
1595 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1596 PointerFree(pStubMsg, pMemory, pFormat);
1599 /***********************************************************************
1600 * NdrSimpleTypeMarshall [RPCRT4.@]
1602 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1603 unsigned char FormatChar )
1605 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1608 /***********************************************************************
1609 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1611 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1612 unsigned char FormatChar )
1614 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
1617 /***********************************************************************
1618 * NdrSimpleStructMarshall [RPCRT4.@]
1620 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1621 unsigned char *pMemory,
1622 PFORMAT_STRING pFormat)
1624 unsigned size = *(const WORD*)(pFormat+2);
1625 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1627 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1629 memcpy(pStubMsg->Buffer, pMemory, size);
1630 pStubMsg->BufferMark = pStubMsg->Buffer;
1631 pStubMsg->Buffer += size;
1633 STD_OVERFLOW_CHECK(pStubMsg);
1635 if (pFormat[0] != RPC_FC_STRUCT)
1636 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1638 STD_OVERFLOW_CHECK(pStubMsg);
1640 return NULL;
1643 /***********************************************************************
1644 * NdrSimpleStructUnmarshall [RPCRT4.@]
1646 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1647 unsigned char **ppMemory,
1648 PFORMAT_STRING pFormat,
1649 unsigned char fMustAlloc)
1651 unsigned size = *(const WORD*)(pFormat+2);
1652 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1654 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1656 /* CODEWEAVERS HACK: Huw has a test that shows this is wrong - it is likely
1657 * that PointerMarshall has set fMustAlloc to 1 in certain circumstances,
1658 * but I haven't worked out what they are yet */
1659 if (fMustAlloc || !*ppMemory) {
1660 *ppMemory = NdrAllocate(pStubMsg, size);
1661 memcpy(*ppMemory, pStubMsg->Buffer, size);
1662 } else {
1663 if (!pStubMsg->IsClient && !*ppMemory)
1664 /* for servers, we just point straight into the RPC buffer */
1665 *ppMemory = pStubMsg->Buffer;
1666 else
1667 /* for clients, memory should be provided by caller */
1668 memcpy(*ppMemory, pStubMsg->Buffer, size);
1671 pStubMsg->BufferMark = pStubMsg->Buffer;
1672 pStubMsg->Buffer += size;
1674 if (pFormat[0] != RPC_FC_STRUCT)
1675 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1677 return NULL;
1680 /***********************************************************************
1681 * NdrSimpleStructBufferSize [RPCRT4.@]
1683 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1684 unsigned char *pMemory,
1685 PFORMAT_STRING pFormat)
1687 unsigned size = *(const WORD*)(pFormat+2);
1688 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1690 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1692 pStubMsg->BufferLength += size;
1693 if (pFormat[0] != RPC_FC_STRUCT)
1694 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1697 /***********************************************************************
1698 * NdrSimpleStructMemorySize [RPCRT4.@]
1700 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1701 PFORMAT_STRING pFormat)
1703 unsigned short size = *(const WORD *)(pFormat+2);
1705 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1707 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1708 pStubMsg->MemorySize += size;
1709 pStubMsg->Buffer += size;
1711 if (pFormat[0] != RPC_FC_STRUCT)
1712 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1713 return size;
1716 /***********************************************************************
1717 * NdrSimpleStructFree [RPCRT4.@]
1719 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1720 unsigned char *pMemory,
1721 PFORMAT_STRING pFormat)
1723 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1724 if (pFormat[0] != RPC_FC_STRUCT)
1725 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1729 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1730 PFORMAT_STRING pFormat)
1732 switch (*pFormat) {
1733 case RPC_FC_STRUCT:
1734 case RPC_FC_PSTRUCT:
1735 case RPC_FC_CSTRUCT:
1736 case RPC_FC_BOGUS_STRUCT:
1737 case RPC_FC_SMFARRAY:
1738 case RPC_FC_SMVARRAY:
1739 return *(const WORD*)&pFormat[2];
1740 case RPC_FC_USER_MARSHAL:
1741 return *(const WORD*)&pFormat[4];
1742 case RPC_FC_RANGE: {
1743 unsigned long ret;
1744 unsigned char *saved_buffer = pStubMsg->Buffer;
1745 ret = NdrRangeMemorySize(pStubMsg, pFormat);
1746 pStubMsg->Buffer = saved_buffer;
1747 return ret;
1749 case RPC_FC_NON_ENCAPSULATED_UNION:
1750 pFormat += 2;
1751 if (pStubMsg->fHasNewCorrDesc)
1752 pFormat += 6;
1753 else
1754 pFormat += 4;
1756 pFormat += *(const SHORT*)pFormat;
1757 return *(const SHORT*)pFormat;
1758 case RPC_FC_IP:
1759 return sizeof(void *);
1760 default:
1761 FIXME("unhandled embedded type %02x\n", *pFormat);
1763 return 0;
1767 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1768 PFORMAT_STRING pFormat)
1770 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1772 if (!m)
1774 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1775 return 0;
1778 return m(pStubMsg, pFormat);
1782 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1783 unsigned char *pMemory,
1784 PFORMAT_STRING pFormat,
1785 PFORMAT_STRING pPointer)
1787 PFORMAT_STRING desc;
1788 NDR_MARSHALL m;
1789 unsigned long size;
1791 while (*pFormat != RPC_FC_END) {
1792 switch (*pFormat) {
1793 case RPC_FC_BYTE:
1794 case RPC_FC_CHAR:
1795 case RPC_FC_SMALL:
1796 case RPC_FC_USMALL:
1797 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1798 memcpy(pStubMsg->Buffer, pMemory, 1);
1799 pStubMsg->Buffer += 1;
1800 pMemory += 1;
1801 break;
1802 case RPC_FC_WCHAR:
1803 case RPC_FC_SHORT:
1804 case RPC_FC_USHORT:
1805 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1806 memcpy(pStubMsg->Buffer, pMemory, 2);
1807 pStubMsg->Buffer += 2;
1808 pMemory += 2;
1809 break;
1810 case RPC_FC_LONG:
1811 case RPC_FC_ULONG:
1812 case RPC_FC_ENUM32:
1813 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1814 memcpy(pStubMsg->Buffer, pMemory, 4);
1815 pStubMsg->Buffer += 4;
1816 pMemory += 4;
1817 break;
1818 case RPC_FC_HYPER:
1819 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1820 memcpy(pStubMsg->Buffer, pMemory, 8);
1821 pStubMsg->Buffer += 8;
1822 pMemory += 8;
1823 break;
1824 case RPC_FC_POINTER:
1826 unsigned char *saved_buffer;
1827 int pointer_buffer_mark_set = 0;
1828 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1829 saved_buffer = pStubMsg->Buffer;
1830 if (pStubMsg->PointerBufferMark)
1832 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1833 pStubMsg->PointerBufferMark = NULL;
1834 pointer_buffer_mark_set = 1;
1836 else
1837 pStubMsg->Buffer += 4; /* for pointer ID */
1838 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
1839 if (pointer_buffer_mark_set)
1841 STD_OVERFLOW_CHECK(pStubMsg);
1842 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1843 pStubMsg->Buffer = saved_buffer + 4;
1845 pPointer += 4;
1846 pMemory += 4;
1847 break;
1849 case RPC_FC_ALIGNM4:
1850 ALIGN_POINTER(pMemory, 4);
1851 break;
1852 case RPC_FC_ALIGNM8:
1853 ALIGN_POINTER(pMemory, 8);
1854 break;
1855 case RPC_FC_STRUCTPAD1:
1856 case RPC_FC_STRUCTPAD2:
1857 case RPC_FC_STRUCTPAD3:
1858 case RPC_FC_STRUCTPAD4:
1859 case RPC_FC_STRUCTPAD5:
1860 case RPC_FC_STRUCTPAD6:
1861 case RPC_FC_STRUCTPAD7:
1862 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1863 break;
1864 case RPC_FC_EMBEDDED_COMPLEX:
1865 pMemory += pFormat[1];
1866 pFormat += 2;
1867 desc = pFormat + *(const SHORT*)pFormat;
1868 size = EmbeddedComplexSize(pStubMsg, desc);
1869 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1870 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1871 if (m)
1873 /* for some reason interface pointers aren't generated as
1874 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1875 * they still need the derefencing treatment that pointers are
1876 * given */
1877 if (*desc == RPC_FC_IP)
1878 m(pStubMsg, *(unsigned char **)pMemory, desc);
1879 else
1880 m(pStubMsg, pMemory, desc);
1882 else FIXME("no marshaller for embedded type %02x\n", *desc);
1883 pMemory += size;
1884 pFormat += 2;
1885 continue;
1886 case RPC_FC_PAD:
1887 break;
1888 default:
1889 FIXME("unhandled format 0x%02x\n", *pFormat);
1891 pFormat++;
1894 return pMemory;
1897 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1898 unsigned char *pMemory,
1899 PFORMAT_STRING pFormat,
1900 PFORMAT_STRING pPointer)
1902 PFORMAT_STRING desc;
1903 NDR_UNMARSHALL m;
1904 unsigned long size;
1906 while (*pFormat != RPC_FC_END) {
1907 switch (*pFormat) {
1908 case RPC_FC_BYTE:
1909 case RPC_FC_CHAR:
1910 case RPC_FC_SMALL:
1911 case RPC_FC_USMALL:
1912 memcpy(pMemory, pStubMsg->Buffer, 1);
1913 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1914 pStubMsg->Buffer += 1;
1915 pMemory += 1;
1916 break;
1917 case RPC_FC_WCHAR:
1918 case RPC_FC_SHORT:
1919 case RPC_FC_USHORT:
1920 memcpy(pMemory, pStubMsg->Buffer, 2);
1921 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1922 pStubMsg->Buffer += 2;
1923 pMemory += 2;
1924 break;
1925 case RPC_FC_LONG:
1926 case RPC_FC_ULONG:
1927 case RPC_FC_ENUM32:
1928 memcpy(pMemory, pStubMsg->Buffer, 4);
1929 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1930 pStubMsg->Buffer += 4;
1931 pMemory += 4;
1932 break;
1933 case RPC_FC_HYPER:
1934 memcpy(pMemory, pStubMsg->Buffer, 8);
1935 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1936 pStubMsg->Buffer += 8;
1937 pMemory += 8;
1938 break;
1939 case RPC_FC_POINTER:
1941 unsigned char *saved_buffer;
1942 int pointer_buffer_mark_set = 0;
1943 *(unsigned char**)pMemory = NULL;
1944 TRACE("pointer => %p\n", pMemory);
1945 ALIGN_POINTER(pStubMsg->Buffer, 4);
1946 saved_buffer = pStubMsg->Buffer;
1947 if (pStubMsg->PointerBufferMark)
1949 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1950 pStubMsg->PointerBufferMark = NULL;
1951 pointer_buffer_mark_set = 1;
1953 else
1954 pStubMsg->Buffer += 4; /* for pointer ID */
1956 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, pPointer, TRUE);
1957 if (pointer_buffer_mark_set)
1959 STD_OVERFLOW_CHECK(pStubMsg);
1960 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1961 pStubMsg->Buffer = saved_buffer + 4;
1963 pPointer += 4;
1964 pMemory += 4;
1965 break;
1967 case RPC_FC_ALIGNM4:
1968 ALIGN_POINTER(pMemory, 4);
1969 break;
1970 case RPC_FC_ALIGNM8:
1971 ALIGN_POINTER(pMemory, 8);
1972 break;
1973 case RPC_FC_STRUCTPAD1:
1974 case RPC_FC_STRUCTPAD2:
1975 case RPC_FC_STRUCTPAD3:
1976 case RPC_FC_STRUCTPAD4:
1977 case RPC_FC_STRUCTPAD5:
1978 case RPC_FC_STRUCTPAD6:
1979 case RPC_FC_STRUCTPAD7:
1980 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1981 break;
1982 case RPC_FC_EMBEDDED_COMPLEX:
1983 pMemory += pFormat[1];
1984 pFormat += 2;
1985 desc = pFormat + *(const SHORT*)pFormat;
1986 size = EmbeddedComplexSize(pStubMsg, desc);
1987 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1988 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1989 memset(pMemory, 0, size); /* just in case */
1990 if (m)
1992 /* for some reason interface pointers aren't generated as
1993 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1994 * they still need the derefencing treatment that pointers are
1995 * given */
1996 if (*desc == RPC_FC_IP)
1997 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
1998 else
1999 m(pStubMsg, &pMemory, desc, FALSE);
2001 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2002 pMemory += size;
2003 pFormat += 2;
2004 continue;
2005 case RPC_FC_PAD:
2006 break;
2007 default:
2008 FIXME("unhandled format %d\n", *pFormat);
2010 pFormat++;
2013 return pMemory;
2016 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2017 unsigned char *pMemory,
2018 PFORMAT_STRING pFormat,
2019 PFORMAT_STRING pPointer)
2021 PFORMAT_STRING desc;
2022 NDR_BUFFERSIZE m;
2023 unsigned long size;
2025 while (*pFormat != RPC_FC_END) {
2026 switch (*pFormat) {
2027 case RPC_FC_BYTE:
2028 case RPC_FC_CHAR:
2029 case RPC_FC_SMALL:
2030 case RPC_FC_USMALL:
2031 pStubMsg->BufferLength += 1;
2032 pMemory += 1;
2033 break;
2034 case RPC_FC_WCHAR:
2035 case RPC_FC_SHORT:
2036 case RPC_FC_USHORT:
2037 pStubMsg->BufferLength += 2;
2038 pMemory += 2;
2039 break;
2040 case RPC_FC_LONG:
2041 case RPC_FC_ULONG:
2042 case RPC_FC_ENUM32:
2043 pStubMsg->BufferLength += 4;
2044 pMemory += 4;
2045 break;
2046 case RPC_FC_HYPER:
2047 pStubMsg->BufferLength += 8;
2048 pMemory += 8;
2049 break;
2050 case RPC_FC_POINTER:
2051 if (!pStubMsg->IgnoreEmbeddedPointers)
2053 int saved_buffer_length = pStubMsg->BufferLength;
2054 pStubMsg->BufferLength = pStubMsg->PointerLength;
2055 pStubMsg->PointerLength = 0;
2056 if(!pStubMsg->BufferLength)
2057 ERR("BufferLength == 0??\n");
2058 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2059 pStubMsg->PointerLength = pStubMsg->BufferLength;
2060 pStubMsg->BufferLength = saved_buffer_length;
2062 pStubMsg->BufferLength += 4;
2063 pPointer += 4;
2064 pMemory += 4;
2065 break;
2066 case RPC_FC_ALIGNM4:
2067 ALIGN_POINTER(pMemory, 4);
2068 break;
2069 case RPC_FC_ALIGNM8:
2070 ALIGN_POINTER(pMemory, 8);
2071 break;
2072 case RPC_FC_STRUCTPAD1:
2073 case RPC_FC_STRUCTPAD2:
2074 case RPC_FC_STRUCTPAD3:
2075 case RPC_FC_STRUCTPAD4:
2076 case RPC_FC_STRUCTPAD5:
2077 case RPC_FC_STRUCTPAD6:
2078 case RPC_FC_STRUCTPAD7:
2079 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2080 break;
2081 case RPC_FC_EMBEDDED_COMPLEX:
2082 pMemory += pFormat[1];
2083 pFormat += 2;
2084 desc = pFormat + *(const SHORT*)pFormat;
2085 size = EmbeddedComplexSize(pStubMsg, desc);
2086 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2087 if (m)
2089 /* for some reason interface pointers aren't generated as
2090 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2091 * they still need the derefencing treatment that pointers are
2092 * given */
2093 if (*desc == RPC_FC_IP)
2094 m(pStubMsg, *(unsigned char **)pMemory, desc);
2095 else
2096 m(pStubMsg, pMemory, desc);
2098 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2099 pMemory += size;
2100 pFormat += 2;
2101 continue;
2102 case RPC_FC_PAD:
2103 break;
2104 default:
2105 FIXME("unhandled format 0x%02x\n", *pFormat);
2107 pFormat++;
2110 return pMemory;
2113 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2114 unsigned char *pMemory,
2115 PFORMAT_STRING pFormat,
2116 PFORMAT_STRING pPointer)
2118 PFORMAT_STRING desc;
2119 NDR_FREE m;
2120 unsigned long size;
2122 while (*pFormat != RPC_FC_END) {
2123 switch (*pFormat) {
2124 case RPC_FC_BYTE:
2125 case RPC_FC_CHAR:
2126 case RPC_FC_SMALL:
2127 case RPC_FC_USMALL:
2128 pMemory += 1;
2129 break;
2130 case RPC_FC_WCHAR:
2131 case RPC_FC_SHORT:
2132 case RPC_FC_USHORT:
2133 pMemory += 2;
2134 break;
2135 case RPC_FC_LONG:
2136 case RPC_FC_ULONG:
2137 case RPC_FC_ENUM32:
2138 pMemory += 4;
2139 break;
2140 case RPC_FC_HYPER:
2141 pMemory += 8;
2142 break;
2143 case RPC_FC_POINTER:
2144 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2145 pPointer += 4;
2146 pMemory += 4;
2147 break;
2148 case RPC_FC_ALIGNM4:
2149 ALIGN_POINTER(pMemory, 4);
2150 break;
2151 case RPC_FC_ALIGNM8:
2152 ALIGN_POINTER(pMemory, 8);
2153 break;
2154 case RPC_FC_STRUCTPAD1:
2155 case RPC_FC_STRUCTPAD2:
2156 case RPC_FC_STRUCTPAD3:
2157 case RPC_FC_STRUCTPAD4:
2158 case RPC_FC_STRUCTPAD5:
2159 case RPC_FC_STRUCTPAD6:
2160 case RPC_FC_STRUCTPAD7:
2161 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2162 break;
2163 case RPC_FC_EMBEDDED_COMPLEX:
2164 pMemory += pFormat[1];
2165 pFormat += 2;
2166 desc = pFormat + *(const SHORT*)pFormat;
2167 size = EmbeddedComplexSize(pStubMsg, desc);
2168 m = NdrFreer[*desc & NDR_TABLE_MASK];
2169 if (m)
2171 /* for some reason interface pointers aren't generated as
2172 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2173 * they still need the derefencing treatment that pointers are
2174 * given */
2175 if (*desc == RPC_FC_IP)
2176 m(pStubMsg, *(unsigned char **)pMemory, desc);
2177 else
2178 m(pStubMsg, pMemory, desc);
2180 else FIXME("no freer for embedded type %02x\n", *desc);
2181 pMemory += size;
2182 pFormat += 2;
2183 continue;
2184 case RPC_FC_PAD:
2185 break;
2186 default:
2187 FIXME("unhandled format 0x%02x\n", *pFormat);
2189 pFormat++;
2192 return pMemory;
2195 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2196 PFORMAT_STRING pFormat)
2198 PFORMAT_STRING desc;
2199 unsigned long size = 0;
2201 while (*pFormat != RPC_FC_END) {
2202 switch (*pFormat) {
2203 case RPC_FC_BYTE:
2204 case RPC_FC_CHAR:
2205 case RPC_FC_SMALL:
2206 case RPC_FC_USMALL:
2207 size += 1;
2208 pStubMsg->Buffer += 1;
2209 break;
2210 case RPC_FC_WCHAR:
2211 case RPC_FC_SHORT:
2212 case RPC_FC_USHORT:
2213 size += 2;
2214 pStubMsg->Buffer += 2;
2215 break;
2216 case RPC_FC_LONG:
2217 case RPC_FC_ULONG:
2218 case RPC_FC_ENUM32:
2219 size += 4;
2220 pStubMsg->Buffer += 4;
2221 break;
2222 case RPC_FC_HYPER:
2223 size += 8;
2224 pStubMsg->Buffer += 8;
2225 break;
2226 case RPC_FC_POINTER:
2227 size += 4;
2228 pStubMsg->Buffer += 4;
2229 if (!pStubMsg->IgnoreEmbeddedPointers)
2230 #if 0
2231 /* FIXME: we don't pass pPointer into this function at the moment */
2232 PointerMemorySize(pStubMsg, pPointer);
2233 #else
2234 FIXME("embedded pointers\n");
2235 #endif
2236 break;
2237 case RPC_FC_ALIGNM4:
2238 ALIGN_LENGTH(size, 4);
2239 ALIGN_POINTER(pStubMsg->Buffer, 4);
2240 break;
2241 case RPC_FC_ALIGNM8:
2242 ALIGN_LENGTH(size, 8);
2243 ALIGN_POINTER(pStubMsg->Buffer, 8);
2244 break;
2245 case RPC_FC_STRUCTPAD1:
2246 case RPC_FC_STRUCTPAD2:
2247 case RPC_FC_STRUCTPAD3:
2248 case RPC_FC_STRUCTPAD4:
2249 case RPC_FC_STRUCTPAD5:
2250 case RPC_FC_STRUCTPAD6:
2251 case RPC_FC_STRUCTPAD7:
2252 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2253 break;
2254 case RPC_FC_EMBEDDED_COMPLEX:
2255 size += pFormat[1];
2256 pFormat += 2;
2257 desc = pFormat + *(const SHORT*)pFormat;
2258 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2259 pFormat += 2;
2260 continue;
2261 case RPC_FC_PAD:
2262 break;
2263 default:
2264 FIXME("unhandled format 0x%02x\n", *pFormat);
2266 pFormat++;
2269 return size;
2272 /***********************************************************************
2273 * NdrComplexStructMarshall [RPCRT4.@]
2275 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2276 unsigned char *pMemory,
2277 PFORMAT_STRING pFormat)
2279 PFORMAT_STRING conf_array = NULL;
2280 PFORMAT_STRING pointer_desc = NULL;
2281 unsigned char *OldMemory = pStubMsg->Memory;
2282 int pointer_buffer_mark_set = 0;
2284 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2286 if (!pStubMsg->PointerBufferMark)
2288 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2289 /* save buffer length */
2290 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2292 /* get the buffer pointer after complex array data, but before
2293 * pointer data */
2294 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2295 pStubMsg->IgnoreEmbeddedPointers = 1;
2296 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2297 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2299 /* save it for use by embedded pointer code later */
2300 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2301 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2302 pointer_buffer_mark_set = 1;
2304 /* restore the original buffer length */
2305 pStubMsg->BufferLength = saved_buffer_length;
2308 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2310 pFormat += 4;
2311 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2312 pFormat += 2;
2313 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2314 pFormat += 2;
2316 pStubMsg->Memory = pMemory;
2318 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2320 if (conf_array)
2321 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2323 pStubMsg->Memory = OldMemory;
2325 if (pointer_buffer_mark_set)
2327 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2328 pStubMsg->PointerBufferMark = NULL;
2331 STD_OVERFLOW_CHECK(pStubMsg);
2333 return NULL;
2336 /***********************************************************************
2337 * NdrComplexStructUnmarshall [RPCRT4.@]
2339 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2340 unsigned char **ppMemory,
2341 PFORMAT_STRING pFormat,
2342 unsigned char fMustAlloc)
2344 unsigned size = *(const WORD*)(pFormat+2);
2345 PFORMAT_STRING conf_array = NULL;
2346 PFORMAT_STRING pointer_desc = NULL;
2347 unsigned char *pMemory;
2348 int pointer_buffer_mark_set = 0;
2350 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2352 if (!pStubMsg->PointerBufferMark)
2354 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2355 /* save buffer pointer */
2356 unsigned char *saved_buffer = pStubMsg->Buffer;
2358 /* get the buffer pointer after complex array data, but before
2359 * pointer data */
2360 pStubMsg->IgnoreEmbeddedPointers = 1;
2361 NdrComplexStructMemorySize(pStubMsg, pFormat);
2362 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2364 /* save it for use by embedded pointer code later */
2365 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2366 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2367 pointer_buffer_mark_set = 1;
2369 /* restore the original buffer */
2370 pStubMsg->Buffer = saved_buffer;
2373 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2375 if (fMustAlloc || !*ppMemory)
2377 *ppMemory = NdrAllocate(pStubMsg, size);
2378 memset(*ppMemory, 0, size);
2381 pFormat += 4;
2382 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2383 pFormat += 2;
2384 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2385 pFormat += 2;
2387 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2389 if (conf_array)
2390 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2392 if (pointer_buffer_mark_set)
2394 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2395 pStubMsg->PointerBufferMark = NULL;
2398 return NULL;
2401 /***********************************************************************
2402 * NdrComplexStructBufferSize [RPCRT4.@]
2404 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2405 unsigned char *pMemory,
2406 PFORMAT_STRING pFormat)
2408 PFORMAT_STRING conf_array = NULL;
2409 PFORMAT_STRING pointer_desc = NULL;
2410 unsigned char *OldMemory = pStubMsg->Memory;
2411 int pointer_length_set = 0;
2413 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2415 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2417 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2419 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2420 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2422 /* get the buffer length after complex struct data, but before
2423 * pointer data */
2424 pStubMsg->IgnoreEmbeddedPointers = 1;
2425 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2426 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2428 /* save it for use by embedded pointer code later */
2429 pStubMsg->PointerLength = pStubMsg->BufferLength;
2430 pointer_length_set = 1;
2431 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2433 /* restore the original buffer length */
2434 pStubMsg->BufferLength = saved_buffer_length;
2437 pFormat += 4;
2438 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2439 pFormat += 2;
2440 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2441 pFormat += 2;
2443 pStubMsg->Memory = pMemory;
2445 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2447 if (conf_array)
2448 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2450 pStubMsg->Memory = OldMemory;
2452 if(pointer_length_set)
2454 pStubMsg->BufferLength = pStubMsg->PointerLength;
2455 pStubMsg->PointerLength = 0;
2460 /***********************************************************************
2461 * NdrComplexStructMemorySize [RPCRT4.@]
2463 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2464 PFORMAT_STRING pFormat)
2466 unsigned size = *(const WORD*)(pFormat+2);
2467 PFORMAT_STRING conf_array = NULL;
2468 PFORMAT_STRING pointer_desc = NULL;
2470 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2472 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2474 pFormat += 4;
2475 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2476 pFormat += 2;
2477 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2478 pFormat += 2;
2480 ComplexStructMemorySize(pStubMsg, pFormat);
2482 if (conf_array)
2483 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2485 return size;
2488 /***********************************************************************
2489 * NdrComplexStructFree [RPCRT4.@]
2491 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2492 unsigned char *pMemory,
2493 PFORMAT_STRING pFormat)
2495 PFORMAT_STRING conf_array = NULL;
2496 PFORMAT_STRING pointer_desc = NULL;
2497 unsigned char *OldMemory = pStubMsg->Memory;
2499 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2501 pFormat += 4;
2502 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2503 pFormat += 2;
2504 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2505 pFormat += 2;
2507 pStubMsg->Memory = pMemory;
2509 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2511 if (conf_array)
2512 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2514 pStubMsg->Memory = OldMemory;
2517 /***********************************************************************
2518 * NdrConformantArrayMarshall [RPCRT4.@]
2520 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2521 unsigned char *pMemory,
2522 PFORMAT_STRING pFormat)
2524 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2525 unsigned char alignment = pFormat[1] + 1;
2527 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2528 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2530 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2532 WriteConformance(pStubMsg);
2534 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2536 size = safe_multiply(esize, pStubMsg->MaxCount);
2537 memcpy(pStubMsg->Buffer, pMemory, size);
2538 pStubMsg->BufferMark = pStubMsg->Buffer;
2539 pStubMsg->Buffer += size;
2541 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2543 STD_OVERFLOW_CHECK(pStubMsg);
2545 return NULL;
2548 /***********************************************************************
2549 * NdrConformantArrayUnmarshall [RPCRT4.@]
2551 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2552 unsigned char **ppMemory,
2553 PFORMAT_STRING pFormat,
2554 unsigned char fMustAlloc)
2556 DWORD size, esize = *(const WORD*)(pFormat+2);
2557 unsigned char alignment = pFormat[1] + 1;
2559 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2560 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2562 pFormat = ReadConformance(pStubMsg, pFormat+4);
2564 size = safe_multiply(esize, pStubMsg->MaxCount);
2566 if (fMustAlloc || !*ppMemory)
2567 *ppMemory = NdrAllocate(pStubMsg, size);
2569 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2571 memcpy(*ppMemory, pStubMsg->Buffer, size);
2573 pStubMsg->BufferMark = pStubMsg->Buffer;
2574 pStubMsg->Buffer += size;
2576 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2578 return NULL;
2581 /***********************************************************************
2582 * NdrConformantArrayBufferSize [RPCRT4.@]
2584 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2585 unsigned char *pMemory,
2586 PFORMAT_STRING pFormat)
2588 DWORD size, esize = *(const WORD*)(pFormat+2);
2589 unsigned char alignment = pFormat[1] + 1;
2591 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2592 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2594 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2596 SizeConformance(pStubMsg);
2598 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2600 size = safe_multiply(esize, pStubMsg->MaxCount);
2601 /* conformance value plus array */
2602 pStubMsg->BufferLength += size;
2604 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2607 /***********************************************************************
2608 * NdrConformantArrayMemorySize [RPCRT4.@]
2610 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2611 PFORMAT_STRING pFormat)
2613 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2614 unsigned char alignment = pFormat[1] + 1;
2616 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2617 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2619 pFormat = ReadConformance(pStubMsg, pFormat+4);
2620 size = safe_multiply(esize, pStubMsg->MaxCount);
2621 pStubMsg->MemorySize += size;
2623 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2624 pStubMsg->BufferMark = pStubMsg->Buffer;
2625 pStubMsg->Buffer += size;
2627 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2629 return pStubMsg->MemorySize;
2632 /***********************************************************************
2633 * NdrConformantArrayFree [RPCRT4.@]
2635 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2636 unsigned char *pMemory,
2637 PFORMAT_STRING pFormat)
2639 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2640 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2642 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2644 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2648 /***********************************************************************
2649 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2651 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2652 unsigned char* pMemory,
2653 PFORMAT_STRING pFormat )
2655 ULONG bufsize;
2656 unsigned char alignment = pFormat[1] + 1;
2657 DWORD esize = *(const WORD*)(pFormat+2);
2659 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2661 if (pFormat[0] != RPC_FC_CVARRAY)
2663 ERR("invalid format type %x\n", pFormat[0]);
2664 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2665 return NULL;
2668 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2669 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2671 WriteConformance(pStubMsg);
2672 WriteVariance(pStubMsg);
2674 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2676 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2678 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2679 pStubMsg->BufferMark = pStubMsg->Buffer;
2680 pStubMsg->Buffer += bufsize;
2682 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2684 STD_OVERFLOW_CHECK(pStubMsg);
2686 return NULL;
2690 /***********************************************************************
2691 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2693 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2694 unsigned char** ppMemory,
2695 PFORMAT_STRING pFormat,
2696 unsigned char fMustAlloc )
2698 ULONG bufsize, memsize;
2699 unsigned char alignment = pFormat[1] + 1;
2700 DWORD esize = *(const WORD*)(pFormat+2);
2702 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2704 if (pFormat[0] != RPC_FC_CVARRAY)
2706 ERR("invalid format type %x\n", pFormat[0]);
2707 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2708 return NULL;
2711 pFormat = ReadConformance(pStubMsg, pFormat+4);
2712 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2714 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2716 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2717 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2719 if (!*ppMemory || fMustAlloc)
2720 *ppMemory = NdrAllocate(pStubMsg, memsize);
2721 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
2722 pStubMsg->Buffer += bufsize;
2724 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2726 return NULL;
2730 /***********************************************************************
2731 * NdrConformantVaryingArrayFree [RPCRT4.@]
2733 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2734 unsigned char* pMemory,
2735 PFORMAT_STRING pFormat )
2737 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2739 if (pFormat[0] != RPC_FC_CVARRAY)
2741 ERR("invalid format type %x\n", pFormat[0]);
2742 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2743 return;
2746 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2747 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2749 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2753 /***********************************************************************
2754 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2756 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2757 unsigned char* pMemory, PFORMAT_STRING pFormat )
2759 unsigned char alignment = pFormat[1] + 1;
2760 DWORD esize = *(const WORD*)(pFormat+2);
2762 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2764 if (pFormat[0] != RPC_FC_CVARRAY)
2766 ERR("invalid format type %x\n", pFormat[0]);
2767 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2768 return;
2771 /* compute size */
2772 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2773 /* compute length */
2774 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2776 SizeConformance(pStubMsg);
2777 SizeVariance(pStubMsg);
2779 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2781 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2783 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2787 /***********************************************************************
2788 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2790 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2791 PFORMAT_STRING pFormat )
2793 FIXME( "stub\n" );
2794 return 0;
2798 /***********************************************************************
2799 * NdrComplexArrayMarshall [RPCRT4.@]
2801 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2802 unsigned char *pMemory,
2803 PFORMAT_STRING pFormat)
2805 ULONG i, count, def;
2806 BOOL variance_present;
2807 unsigned char alignment;
2808 int pointer_buffer_mark_set = 0;
2810 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2812 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2814 ERR("invalid format type %x\n", pFormat[0]);
2815 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2816 return NULL;
2819 alignment = pFormat[1] + 1;
2821 if (!pStubMsg->PointerBufferMark)
2823 /* save buffer fields that may be changed by buffer sizer functions
2824 * and that may be needed later on */
2825 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2826 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2827 unsigned long saved_max_count = pStubMsg->MaxCount;
2828 unsigned long saved_offset = pStubMsg->Offset;
2829 unsigned long saved_actual_count = pStubMsg->ActualCount;
2831 /* get the buffer pointer after complex array data, but before
2832 * pointer data */
2833 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2834 pStubMsg->IgnoreEmbeddedPointers = 1;
2835 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2836 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2838 /* save it for use by embedded pointer code later */
2839 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2840 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
2841 pointer_buffer_mark_set = 1;
2843 /* restore fields */
2844 pStubMsg->ActualCount = saved_actual_count;
2845 pStubMsg->Offset = saved_offset;
2846 pStubMsg->MaxCount = saved_max_count;
2847 pStubMsg->BufferLength = saved_buffer_length;
2850 def = *(const WORD*)&pFormat[2];
2851 pFormat += 4;
2853 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2854 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2856 variance_present = IsConformanceOrVariancePresent(pFormat);
2857 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2858 TRACE("variance = %d\n", pStubMsg->ActualCount);
2860 WriteConformance(pStubMsg);
2861 if (variance_present)
2862 WriteVariance(pStubMsg);
2864 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2866 count = pStubMsg->ActualCount;
2867 for (i = 0; i < count; i++)
2868 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2870 STD_OVERFLOW_CHECK(pStubMsg);
2872 if (pointer_buffer_mark_set)
2874 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2875 pStubMsg->PointerBufferMark = NULL;
2878 return NULL;
2881 /***********************************************************************
2882 * NdrComplexArrayUnmarshall [RPCRT4.@]
2884 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2885 unsigned char **ppMemory,
2886 PFORMAT_STRING pFormat,
2887 unsigned char fMustAlloc)
2889 ULONG i, count, size;
2890 unsigned char alignment;
2891 unsigned char *pMemory;
2892 unsigned char *saved_buffer;
2893 int pointer_buffer_mark_set = 0;
2894 int saved_ignore_embedded;
2896 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2898 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2900 ERR("invalid format type %x\n", pFormat[0]);
2901 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2902 return NULL;
2905 alignment = pFormat[1] + 1;
2907 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2908 /* save buffer pointer */
2909 saved_buffer = pStubMsg->Buffer;
2910 /* get the buffer pointer after complex array data, but before
2911 * pointer data */
2912 pStubMsg->IgnoreEmbeddedPointers = 1;
2913 pStubMsg->MemorySize = 0;
2914 NdrComplexArrayMemorySize(pStubMsg, pFormat);
2915 size = pStubMsg->MemorySize;
2916 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2918 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
2919 if (!pStubMsg->PointerBufferMark)
2921 /* save it for use by embedded pointer code later */
2922 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2923 pointer_buffer_mark_set = 1;
2925 /* restore the original buffer */
2926 pStubMsg->Buffer = saved_buffer;
2928 pFormat += 4;
2930 pFormat = ReadConformance(pStubMsg, pFormat);
2931 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2933 if (fMustAlloc || !*ppMemory)
2935 *ppMemory = NdrAllocate(pStubMsg, size);
2936 memset(*ppMemory, 0, size);
2939 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2941 pMemory = *ppMemory;
2942 count = pStubMsg->ActualCount;
2943 for (i = 0; i < count; i++)
2944 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2946 if (pointer_buffer_mark_set)
2948 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2949 pStubMsg->PointerBufferMark = NULL;
2952 return NULL;
2955 /***********************************************************************
2956 * NdrComplexArrayBufferSize [RPCRT4.@]
2958 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2959 unsigned char *pMemory,
2960 PFORMAT_STRING pFormat)
2962 ULONG i, count, def;
2963 unsigned char alignment;
2964 BOOL variance_present;
2965 int pointer_length_set = 0;
2967 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2969 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2971 ERR("invalid format type %x\n", pFormat[0]);
2972 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2973 return;
2976 alignment = pFormat[1] + 1;
2978 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2980 /* save buffer fields that may be changed by buffer sizer functions
2981 * and that may be needed later on */
2982 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2983 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2984 unsigned long saved_max_count = pStubMsg->MaxCount;
2985 unsigned long saved_offset = pStubMsg->Offset;
2986 unsigned long saved_actual_count = pStubMsg->ActualCount;
2988 /* get the buffer pointer after complex array data, but before
2989 * pointer data */
2990 pStubMsg->IgnoreEmbeddedPointers = 1;
2991 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
2992 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2994 /* save it for use by embedded pointer code later */
2995 pStubMsg->PointerLength = pStubMsg->BufferLength;
2996 pointer_length_set = 1;
2998 /* restore fields */
2999 pStubMsg->ActualCount = saved_actual_count;
3000 pStubMsg->Offset = saved_offset;
3001 pStubMsg->MaxCount = saved_max_count;
3002 pStubMsg->BufferLength = saved_buffer_length;
3004 def = *(const WORD*)&pFormat[2];
3005 pFormat += 4;
3007 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3008 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3009 SizeConformance(pStubMsg);
3011 variance_present = IsConformanceOrVariancePresent(pFormat);
3012 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3013 TRACE("variance = %d\n", pStubMsg->ActualCount);
3015 if (variance_present)
3016 SizeVariance(pStubMsg);
3018 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3020 count = pStubMsg->ActualCount;
3021 for (i = 0; i < count; i++)
3022 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3024 if(pointer_length_set)
3026 pStubMsg->BufferLength = pStubMsg->PointerLength;
3027 pStubMsg->PointerLength = 0;
3031 /***********************************************************************
3032 * NdrComplexArrayMemorySize [RPCRT4.@]
3034 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3035 PFORMAT_STRING pFormat)
3037 ULONG i, count, esize, SavedMemorySize, MemorySize;
3038 unsigned char alignment;
3039 unsigned char *Buffer;
3041 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3043 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3045 ERR("invalid format type %x\n", pFormat[0]);
3046 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3047 return 0;
3050 alignment = pFormat[1] + 1;
3052 pFormat += 4;
3054 pFormat = ReadConformance(pStubMsg, pFormat);
3055 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3057 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3059 SavedMemorySize = pStubMsg->MemorySize;
3061 Buffer = pStubMsg->Buffer;
3062 esize = ComplexStructMemorySize(pStubMsg, pFormat);
3063 pStubMsg->Buffer = Buffer;
3065 MemorySize = esize * pStubMsg->MaxCount;
3067 count = pStubMsg->ActualCount;
3068 for (i = 0; i < count; i++)
3069 ComplexStructMemorySize(pStubMsg, pFormat);
3071 pStubMsg->MemorySize = SavedMemorySize;
3073 pStubMsg->MemorySize += MemorySize;
3074 return MemorySize;
3077 /***********************************************************************
3078 * NdrComplexArrayFree [RPCRT4.@]
3080 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3081 unsigned char *pMemory,
3082 PFORMAT_STRING pFormat)
3084 ULONG i, count, def;
3086 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3088 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3090 ERR("invalid format type %x\n", pFormat[0]);
3091 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3092 return;
3095 def = *(const WORD*)&pFormat[2];
3096 pFormat += 4;
3098 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3099 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3101 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3102 TRACE("variance = %d\n", pStubMsg->ActualCount);
3104 count = pStubMsg->ActualCount;
3105 for (i = 0; i < count; i++)
3106 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3109 static ULONG UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
3111 return MAKELONG(pStubMsg->dwDestContext,
3112 pStubMsg->RpcMsg->DataRepresentation);
3115 #define USER_MARSHAL_PTR_PREFIX \
3116 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3117 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3119 /***********************************************************************
3120 * NdrUserMarshalMarshall [RPCRT4.@]
3122 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3123 unsigned char *pMemory,
3124 PFORMAT_STRING pFormat)
3126 unsigned flags = pFormat[1];
3127 unsigned index = *(const WORD*)&pFormat[2];
3128 unsigned char *saved_buffer = NULL;
3129 ULONG uflag = UserMarshalFlags(pStubMsg);
3130 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3131 TRACE("index=%d\n", index);
3133 if (flags & USER_MARSHAL_POINTER)
3135 ALIGN_POINTER(pStubMsg->Buffer, 4);
3136 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3137 pStubMsg->Buffer += 4;
3138 if (pStubMsg->PointerBufferMark)
3140 saved_buffer = pStubMsg->Buffer;
3141 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3142 pStubMsg->PointerBufferMark = NULL;
3144 ALIGN_POINTER(pStubMsg->Buffer, 8);
3146 else
3147 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3149 pStubMsg->Buffer =
3150 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3151 &uflag, pStubMsg->Buffer, pMemory);
3153 if (saved_buffer)
3155 STD_OVERFLOW_CHECK(pStubMsg);
3156 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3157 pStubMsg->Buffer = saved_buffer;
3160 STD_OVERFLOW_CHECK(pStubMsg);
3162 return NULL;
3165 /***********************************************************************
3166 * NdrUserMarshalUnmarshall [RPCRT4.@]
3168 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3169 unsigned char **ppMemory,
3170 PFORMAT_STRING pFormat,
3171 unsigned char fMustAlloc)
3173 unsigned flags = pFormat[1];
3174 unsigned index = *(const WORD*)&pFormat[2];
3175 DWORD memsize = *(const WORD*)&pFormat[4];
3176 unsigned char *saved_buffer = NULL;
3177 ULONG uflag = UserMarshalFlags(pStubMsg);
3178 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3179 TRACE("index=%d\n", index);
3181 if (flags & USER_MARSHAL_POINTER)
3183 ALIGN_POINTER(pStubMsg->Buffer, 4);
3184 /* skip pointer prefix */
3185 pStubMsg->Buffer += 4;
3186 if (pStubMsg->PointerBufferMark)
3188 saved_buffer = pStubMsg->Buffer;
3189 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3190 pStubMsg->PointerBufferMark = NULL;
3192 ALIGN_POINTER(pStubMsg->Buffer, 8);
3194 else
3195 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3197 if (fMustAlloc || !*ppMemory)
3198 *ppMemory = NdrAllocate(pStubMsg, memsize);
3200 pStubMsg->Buffer =
3201 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3202 &uflag, pStubMsg->Buffer, *ppMemory);
3204 if (saved_buffer)
3206 STD_OVERFLOW_CHECK(pStubMsg);
3207 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3208 pStubMsg->Buffer = saved_buffer;
3211 return NULL;
3214 /***********************************************************************
3215 * NdrUserMarshalBufferSize [RPCRT4.@]
3217 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3218 unsigned char *pMemory,
3219 PFORMAT_STRING pFormat)
3221 unsigned flags = pFormat[1];
3222 unsigned index = *(const WORD*)&pFormat[2];
3223 DWORD bufsize = *(const WORD*)&pFormat[6];
3224 ULONG uflag = UserMarshalFlags(pStubMsg);
3225 unsigned long saved_buffer_length = 0;
3226 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3227 TRACE("index=%d\n", index);
3229 if (flags & USER_MARSHAL_POINTER)
3231 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3232 /* skip pointer prefix */
3233 pStubMsg->BufferLength += 4;
3234 if (pStubMsg->IgnoreEmbeddedPointers)
3235 return;
3236 if (pStubMsg->PointerLength)
3238 saved_buffer_length = pStubMsg->BufferLength;
3239 pStubMsg->BufferLength = pStubMsg->PointerLength;
3240 pStubMsg->PointerLength = 0;
3242 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3244 else
3245 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3247 if (bufsize) {
3248 TRACE("size=%d\n", bufsize);
3249 pStubMsg->BufferLength += bufsize;
3251 else
3252 pStubMsg->BufferLength =
3253 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3254 &uflag, pStubMsg->BufferLength, pMemory);
3256 if (saved_buffer_length)
3258 pStubMsg->PointerLength = pStubMsg->BufferLength;
3259 pStubMsg->BufferLength = saved_buffer_length;
3264 /***********************************************************************
3265 * NdrUserMarshalMemorySize [RPCRT4.@]
3267 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3268 PFORMAT_STRING pFormat)
3270 unsigned flags = pFormat[1];
3271 unsigned index = *(const WORD*)&pFormat[2];
3272 DWORD memsize = *(const WORD*)&pFormat[4];
3273 DWORD bufsize = *(const WORD*)&pFormat[6];
3275 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3276 TRACE("index=%d\n", index);
3278 pStubMsg->MemorySize += memsize;
3280 if (flags & USER_MARSHAL_POINTER)
3282 ALIGN_POINTER(pStubMsg->Buffer, 4);
3283 /* skip pointer prefix */
3284 pStubMsg->Buffer += 4;
3285 if (pStubMsg->IgnoreEmbeddedPointers)
3286 return pStubMsg->MemorySize;
3287 ALIGN_POINTER(pStubMsg->Buffer, 8);
3289 else
3290 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3292 if (!bufsize)
3293 FIXME("not implemented for varying buffer size\n");
3295 pStubMsg->Buffer += bufsize;
3297 return pStubMsg->MemorySize;
3300 /***********************************************************************
3301 * NdrUserMarshalFree [RPCRT4.@]
3303 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3304 unsigned char *pMemory,
3305 PFORMAT_STRING pFormat)
3307 /* unsigned flags = pFormat[1]; */
3308 unsigned index = *(const WORD*)&pFormat[2];
3309 ULONG uflag = UserMarshalFlags(pStubMsg);
3310 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3311 TRACE("index=%d\n", index);
3313 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3314 &uflag, pMemory);
3317 /***********************************************************************
3318 * NdrClearOutParameters [RPCRT4.@]
3320 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3321 PFORMAT_STRING pFormat,
3322 void *ArgAddr)
3324 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3327 /***********************************************************************
3328 * NdrConvert [RPCRT4.@]
3330 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3332 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3333 /* FIXME: since this stub doesn't do any converting, the proper behavior
3334 is to raise an exception */
3337 /***********************************************************************
3338 * NdrConvert2 [RPCRT4.@]
3340 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3342 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3343 pStubMsg, pFormat, NumberParams);
3344 /* FIXME: since this stub doesn't do any converting, the proper behavior
3345 is to raise an exception */
3348 #include "pshpack1.h"
3349 typedef struct _NDR_CSTRUCT_FORMAT
3351 unsigned char type;
3352 unsigned char alignment;
3353 unsigned short memory_size;
3354 short offset_to_array_description;
3355 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3356 #include "poppack.h"
3358 /***********************************************************************
3359 * NdrConformantStructMarshall [RPCRT4.@]
3361 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3362 unsigned char *pMemory,
3363 PFORMAT_STRING pFormat)
3365 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3366 PFORMAT_STRING pCArrayFormat;
3367 ULONG esize, bufsize;
3369 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3371 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3372 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3374 ERR("invalid format type %x\n", pCStructFormat->type);
3375 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3376 return NULL;
3379 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3380 pCStructFormat->offset_to_array_description;
3381 if (*pCArrayFormat != RPC_FC_CARRAY)
3383 ERR("invalid array format type %x\n", pCStructFormat->type);
3384 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3385 return NULL;
3387 esize = *(const WORD*)(pCArrayFormat+2);
3389 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3390 pCArrayFormat + 4, 0);
3392 WriteConformance(pStubMsg);
3394 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3396 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3398 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3399 /* copy constant sized part of struct */
3400 pStubMsg->BufferMark = pStubMsg->Buffer;
3401 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
3402 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3404 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3405 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3407 STD_OVERFLOW_CHECK(pStubMsg);
3409 return NULL;
3412 /***********************************************************************
3413 * NdrConformantStructUnmarshall [RPCRT4.@]
3415 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3416 unsigned char **ppMemory,
3417 PFORMAT_STRING pFormat,
3418 unsigned char fMustAlloc)
3420 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3421 PFORMAT_STRING pCArrayFormat;
3422 ULONG esize, bufsize;
3424 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3426 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3427 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3429 ERR("invalid format type %x\n", pCStructFormat->type);
3430 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3431 return NULL;
3433 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3434 pCStructFormat->offset_to_array_description;
3435 if (*pCArrayFormat != RPC_FC_CARRAY)
3437 ERR("invalid array format type %x\n", pCStructFormat->type);
3438 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3439 return NULL;
3441 esize = *(const WORD*)(pCArrayFormat+2);
3443 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3445 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3447 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3449 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3450 /* work out how much memory to allocate if we need to do so */
3451 if (!*ppMemory || fMustAlloc)
3453 SIZE_T size = pCStructFormat->memory_size + bufsize;
3454 *ppMemory = NdrAllocate(pStubMsg, size);
3457 /* now copy the data */
3458 pStubMsg->BufferMark = pStubMsg->Buffer;
3459 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
3460 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3462 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3463 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3465 return NULL;
3468 /***********************************************************************
3469 * NdrConformantStructBufferSize [RPCRT4.@]
3471 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3472 unsigned char *pMemory,
3473 PFORMAT_STRING pFormat)
3475 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3476 PFORMAT_STRING pCArrayFormat;
3477 ULONG esize;
3479 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3481 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3482 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3484 ERR("invalid format type %x\n", pCStructFormat->type);
3485 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3486 return;
3488 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3489 pCStructFormat->offset_to_array_description;
3490 if (*pCArrayFormat != RPC_FC_CARRAY)
3492 ERR("invalid array format type %x\n", pCStructFormat->type);
3493 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3494 return;
3496 esize = *(const WORD*)(pCArrayFormat+2);
3498 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3499 SizeConformance(pStubMsg);
3501 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3503 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3505 pStubMsg->BufferLength += pCStructFormat->memory_size +
3506 safe_multiply(pStubMsg->MaxCount, esize);
3508 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3509 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3512 /***********************************************************************
3513 * NdrConformantStructMemorySize [RPCRT4.@]
3515 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3516 PFORMAT_STRING pFormat)
3518 FIXME("stub\n");
3519 return 0;
3522 /***********************************************************************
3523 * NdrConformantStructFree [RPCRT4.@]
3525 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3526 unsigned char *pMemory,
3527 PFORMAT_STRING pFormat)
3529 FIXME("stub\n");
3532 /***********************************************************************
3533 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3535 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3536 unsigned char *pMemory,
3537 PFORMAT_STRING pFormat)
3539 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3540 PFORMAT_STRING pCVArrayFormat;
3541 ULONG esize, bufsize;
3543 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3545 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3546 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3548 ERR("invalid format type %x\n", pCVStructFormat->type);
3549 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3550 return NULL;
3553 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3554 pCVStructFormat->offset_to_array_description;
3555 switch (*pCVArrayFormat)
3557 case RPC_FC_CVARRAY:
3558 esize = *(const WORD*)(pCVArrayFormat+2);
3560 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3561 pCVArrayFormat + 4, 0);
3562 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3563 pCVArrayFormat, 0);
3564 break;
3565 case RPC_FC_C_CSTRING:
3566 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3567 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3568 esize = sizeof(char);
3569 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3570 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3571 pCVArrayFormat + 2, 0);
3572 else
3573 pStubMsg->MaxCount = pStubMsg->ActualCount;
3574 break;
3575 case RPC_FC_C_WSTRING:
3576 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3577 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3578 esize = sizeof(WCHAR);
3579 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3580 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3581 pCVArrayFormat + 2, 0);
3582 else
3583 pStubMsg->MaxCount = pStubMsg->ActualCount;
3584 break;
3585 default:
3586 ERR("invalid array format type %x\n", *pCVArrayFormat);
3587 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3588 return NULL;
3591 WriteConformance(pStubMsg);
3593 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3595 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3597 /* write constant sized part */
3598 pStubMsg->BufferMark = pStubMsg->Buffer;
3599 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3600 pStubMsg->Buffer += pCVStructFormat->memory_size;
3602 WriteVariance(pStubMsg);
3604 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3606 /* write array part */
3607 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3608 pStubMsg->Buffer += bufsize;
3610 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3612 STD_OVERFLOW_CHECK(pStubMsg);
3614 return NULL;
3617 /***********************************************************************
3618 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3620 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3621 unsigned char **ppMemory,
3622 PFORMAT_STRING pFormat,
3623 unsigned char fMustAlloc)
3625 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3626 PFORMAT_STRING pCVArrayFormat;
3627 ULONG esize, bufsize;
3628 unsigned char cvarray_type;
3630 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3632 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3633 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3635 ERR("invalid format type %x\n", pCVStructFormat->type);
3636 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3637 return NULL;
3640 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3641 pCVStructFormat->offset_to_array_description;
3642 cvarray_type = *pCVArrayFormat;
3643 switch (cvarray_type)
3645 case RPC_FC_CVARRAY:
3646 esize = *(const WORD*)(pCVArrayFormat+2);
3647 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3648 break;
3649 case RPC_FC_C_CSTRING:
3650 esize = sizeof(char);
3651 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3652 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3653 else
3654 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3655 break;
3656 case RPC_FC_C_WSTRING:
3657 esize = sizeof(WCHAR);
3658 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3659 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3660 else
3661 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3662 break;
3663 default:
3664 ERR("invalid array format type %x\n", *pCVArrayFormat);
3665 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3666 return NULL;
3669 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3671 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3673 /* work out how much memory to allocate if we need to do so */
3674 if (!*ppMemory || fMustAlloc)
3676 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3677 *ppMemory = NdrAllocate(pStubMsg, size);
3680 /* copy the constant data */
3681 pStubMsg->BufferMark = pStubMsg->Buffer;
3682 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3683 pStubMsg->Buffer += pCVStructFormat->memory_size;
3685 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3687 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3689 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3690 (cvarray_type == RPC_FC_C_WSTRING))
3692 ULONG i;
3693 /* strings must always have null terminating bytes */
3694 if (bufsize < esize)
3696 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3697 RpcRaiseException(RPC_S_INVALID_BOUND);
3698 return NULL;
3700 for (i = bufsize - esize; i < bufsize; i++)
3701 if (pStubMsg->Buffer[i] != 0)
3703 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3704 i, pStubMsg->Buffer[i]);
3705 RpcRaiseException(RPC_S_INVALID_BOUND);
3706 return NULL;
3710 /* copy the array data */
3711 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3712 bufsize);
3713 pStubMsg->Buffer += bufsize;
3715 if (cvarray_type == RPC_FC_C_CSTRING)
3716 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3717 else if (cvarray_type == RPC_FC_C_WSTRING)
3718 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3720 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3722 return NULL;
3725 /***********************************************************************
3726 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3728 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3729 unsigned char *pMemory,
3730 PFORMAT_STRING pFormat)
3732 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3733 PFORMAT_STRING pCVArrayFormat;
3734 ULONG esize;
3736 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3738 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3739 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3741 ERR("invalid format type %x\n", pCVStructFormat->type);
3742 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3743 return;
3746 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3747 pCVStructFormat->offset_to_array_description;
3748 switch (*pCVArrayFormat)
3750 case RPC_FC_CVARRAY:
3751 esize = *(const WORD*)(pCVArrayFormat+2);
3753 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3754 pCVArrayFormat + 4, 0);
3755 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3756 pCVArrayFormat, 0);
3757 break;
3758 case RPC_FC_C_CSTRING:
3759 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3760 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3761 esize = sizeof(char);
3762 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3763 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3764 pCVArrayFormat + 2, 0);
3765 else
3766 pStubMsg->MaxCount = pStubMsg->ActualCount;
3767 break;
3768 case RPC_FC_C_WSTRING:
3769 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3770 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3771 esize = sizeof(WCHAR);
3772 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3773 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3774 pCVArrayFormat + 2, 0);
3775 else
3776 pStubMsg->MaxCount = pStubMsg->ActualCount;
3777 break;
3778 default:
3779 ERR("invalid array format type %x\n", *pCVArrayFormat);
3780 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3781 return;
3784 SizeConformance(pStubMsg);
3786 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3788 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3790 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3791 SizeVariance(pStubMsg);
3792 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3794 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3797 /***********************************************************************
3798 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3800 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3801 PFORMAT_STRING pFormat)
3803 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3804 PFORMAT_STRING pCVArrayFormat;
3805 ULONG esize;
3806 unsigned char cvarray_type;
3808 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3810 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3811 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3813 ERR("invalid format type %x\n", pCVStructFormat->type);
3814 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3815 return 0;
3818 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3819 pCVStructFormat->offset_to_array_description;
3820 cvarray_type = *pCVArrayFormat;
3821 switch (cvarray_type)
3823 case RPC_FC_CVARRAY:
3824 esize = *(const WORD*)(pCVArrayFormat+2);
3825 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3826 break;
3827 case RPC_FC_C_CSTRING:
3828 esize = sizeof(char);
3829 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3830 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3831 else
3832 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3833 break;
3834 case RPC_FC_C_WSTRING:
3835 esize = sizeof(WCHAR);
3836 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3837 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3838 else
3839 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3840 break;
3841 default:
3842 ERR("invalid array format type %x\n", *pCVArrayFormat);
3843 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3844 return 0;
3847 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3849 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3851 pStubMsg->Buffer += pCVStructFormat->memory_size;
3852 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3853 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3855 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3857 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3859 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3862 /***********************************************************************
3863 * NdrConformantVaryingStructFree [RPCRT4.@]
3865 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3866 unsigned char *pMemory,
3867 PFORMAT_STRING pFormat)
3869 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3870 PFORMAT_STRING pCVArrayFormat;
3871 ULONG esize;
3873 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3875 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3876 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3878 ERR("invalid format type %x\n", pCVStructFormat->type);
3879 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3880 return;
3883 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3884 pCVStructFormat->offset_to_array_description;
3885 switch (*pCVArrayFormat)
3887 case RPC_FC_CVARRAY:
3888 esize = *(const WORD*)(pCVArrayFormat+2);
3890 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3891 pCVArrayFormat + 4, 0);
3892 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3893 pCVArrayFormat, 0);
3894 break;
3895 case RPC_FC_C_CSTRING:
3896 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3897 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3898 esize = sizeof(char);
3899 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3900 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3901 pCVArrayFormat + 2, 0);
3902 else
3903 pStubMsg->MaxCount = pStubMsg->ActualCount;
3904 break;
3905 case RPC_FC_C_WSTRING:
3906 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3907 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3908 esize = sizeof(WCHAR);
3909 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3910 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3911 pCVArrayFormat + 2, 0);
3912 else
3913 pStubMsg->MaxCount = pStubMsg->ActualCount;
3914 break;
3915 default:
3916 ERR("invalid array format type %x\n", *pCVArrayFormat);
3917 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3918 return;
3921 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3923 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3926 #include "pshpack1.h"
3927 typedef struct
3929 unsigned char type;
3930 unsigned char alignment;
3931 unsigned short total_size;
3932 } NDR_SMFARRAY_FORMAT;
3934 typedef struct
3936 unsigned char type;
3937 unsigned char alignment;
3938 unsigned long total_size;
3939 } NDR_LGFARRAY_FORMAT;
3940 #include "poppack.h"
3942 /***********************************************************************
3943 * NdrFixedArrayMarshall [RPCRT4.@]
3945 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3946 unsigned char *pMemory,
3947 PFORMAT_STRING pFormat)
3949 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3950 unsigned long total_size;
3952 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3954 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3955 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3957 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3958 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3959 return NULL;
3962 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3964 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3966 total_size = pSmFArrayFormat->total_size;
3967 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3969 else
3971 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3972 total_size = pLgFArrayFormat->total_size;
3973 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3976 memcpy(pStubMsg->Buffer, pMemory, total_size);
3977 pStubMsg->BufferMark = pStubMsg->Buffer;
3978 pStubMsg->Buffer += total_size;
3980 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3982 return NULL;
3985 /***********************************************************************
3986 * NdrFixedArrayUnmarshall [RPCRT4.@]
3988 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3989 unsigned char **ppMemory,
3990 PFORMAT_STRING pFormat,
3991 unsigned char fMustAlloc)
3993 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3994 unsigned long total_size;
3996 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3998 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3999 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4001 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4002 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4003 return NULL;
4006 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4008 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4010 total_size = pSmFArrayFormat->total_size;
4011 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4013 else
4015 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4016 total_size = pLgFArrayFormat->total_size;
4017 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4020 if (fMustAlloc || !*ppMemory)
4021 *ppMemory = NdrAllocate(pStubMsg, total_size);
4022 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
4023 pStubMsg->BufferMark = pStubMsg->Buffer;
4024 pStubMsg->Buffer += total_size;
4026 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
4028 return NULL;
4031 /***********************************************************************
4032 * NdrFixedArrayBufferSize [RPCRT4.@]
4034 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4035 unsigned char *pMemory,
4036 PFORMAT_STRING pFormat)
4038 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4039 unsigned long total_size;
4041 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4043 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4044 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4046 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4047 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4048 return;
4051 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4053 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4055 total_size = pSmFArrayFormat->total_size;
4056 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4058 else
4060 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4061 total_size = pLgFArrayFormat->total_size;
4062 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4064 pStubMsg->BufferLength += total_size;
4066 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4069 /***********************************************************************
4070 * NdrFixedArrayMemorySize [RPCRT4.@]
4072 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4073 PFORMAT_STRING pFormat)
4075 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4076 ULONG total_size;
4078 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4080 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4081 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4083 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4084 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4085 return 0;
4088 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4090 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4092 total_size = pSmFArrayFormat->total_size;
4093 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4095 else
4097 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4098 total_size = pLgFArrayFormat->total_size;
4099 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4101 pStubMsg->BufferMark = pStubMsg->Buffer;
4102 pStubMsg->Buffer += total_size;
4103 pStubMsg->MemorySize += total_size;
4105 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4107 return total_size;
4110 /***********************************************************************
4111 * NdrFixedArrayFree [RPCRT4.@]
4113 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4114 unsigned char *pMemory,
4115 PFORMAT_STRING pFormat)
4117 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4119 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4121 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4122 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4124 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4125 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4126 return;
4129 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4130 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4131 else
4133 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4134 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4137 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4140 /***********************************************************************
4141 * NdrVaryingArrayMarshall [RPCRT4.@]
4143 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4144 unsigned char *pMemory,
4145 PFORMAT_STRING pFormat)
4147 unsigned char alignment;
4148 DWORD elements, esize;
4149 ULONG bufsize;
4151 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4153 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4154 (pFormat[0] != RPC_FC_LGVARRAY))
4156 ERR("invalid format type %x\n", pFormat[0]);
4157 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4158 return NULL;
4161 alignment = pFormat[1] + 1;
4163 if (pFormat[0] == RPC_FC_SMVARRAY)
4165 pFormat += 2;
4166 pFormat += sizeof(WORD);
4167 elements = *(const WORD*)pFormat;
4168 pFormat += sizeof(WORD);
4170 else
4172 pFormat += 2;
4173 pFormat += sizeof(DWORD);
4174 elements = *(const DWORD*)pFormat;
4175 pFormat += sizeof(DWORD);
4178 esize = *(const WORD*)pFormat;
4179 pFormat += sizeof(WORD);
4181 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4182 if ((pStubMsg->ActualCount > elements) ||
4183 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4185 RpcRaiseException(RPC_S_INVALID_BOUND);
4186 return NULL;
4189 WriteVariance(pStubMsg);
4191 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4193 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4194 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
4195 pStubMsg->BufferMark = pStubMsg->Buffer;
4196 pStubMsg->Buffer += bufsize;
4198 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4200 STD_OVERFLOW_CHECK(pStubMsg);
4202 return NULL;
4205 /***********************************************************************
4206 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4208 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4209 unsigned char **ppMemory,
4210 PFORMAT_STRING pFormat,
4211 unsigned char fMustAlloc)
4213 unsigned char alignment;
4214 DWORD size, elements, esize;
4215 ULONG bufsize;
4217 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4219 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4220 (pFormat[0] != RPC_FC_LGVARRAY))
4222 ERR("invalid format type %x\n", pFormat[0]);
4223 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4224 return NULL;
4227 alignment = pFormat[1] + 1;
4229 if (pFormat[0] == RPC_FC_SMVARRAY)
4231 pFormat += 2;
4232 size = *(const WORD*)pFormat;
4233 pFormat += sizeof(WORD);
4234 elements = *(const WORD*)pFormat;
4235 pFormat += sizeof(WORD);
4237 else
4239 pFormat += 2;
4240 size = *(const DWORD*)pFormat;
4241 pFormat += sizeof(DWORD);
4242 elements = *(const DWORD*)pFormat;
4243 pFormat += sizeof(DWORD);
4246 esize = *(const WORD*)pFormat;
4247 pFormat += sizeof(WORD);
4249 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4251 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4253 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4255 if (!*ppMemory || fMustAlloc)
4256 *ppMemory = NdrAllocate(pStubMsg, size);
4257 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
4258 pStubMsg->Buffer += bufsize;
4260 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
4262 return NULL;
4265 /***********************************************************************
4266 * NdrVaryingArrayBufferSize [RPCRT4.@]
4268 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4269 unsigned char *pMemory,
4270 PFORMAT_STRING pFormat)
4272 unsigned char alignment;
4273 DWORD elements, esize;
4275 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4277 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4278 (pFormat[0] != RPC_FC_LGVARRAY))
4280 ERR("invalid format type %x\n", pFormat[0]);
4281 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4282 return;
4285 alignment = pFormat[1] + 1;
4287 if (pFormat[0] == RPC_FC_SMVARRAY)
4289 pFormat += 2;
4290 pFormat += sizeof(WORD);
4291 elements = *(const WORD*)pFormat;
4292 pFormat += sizeof(WORD);
4294 else
4296 pFormat += 2;
4297 pFormat += sizeof(DWORD);
4298 elements = *(const DWORD*)pFormat;
4299 pFormat += sizeof(DWORD);
4302 esize = *(const WORD*)pFormat;
4303 pFormat += sizeof(WORD);
4305 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4306 if ((pStubMsg->ActualCount > elements) ||
4307 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4309 RpcRaiseException(RPC_S_INVALID_BOUND);
4310 return;
4313 SizeVariance(pStubMsg);
4315 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4317 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
4319 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4322 /***********************************************************************
4323 * NdrVaryingArrayMemorySize [RPCRT4.@]
4325 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4326 PFORMAT_STRING pFormat)
4328 unsigned char alignment;
4329 DWORD size, elements, esize;
4331 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4333 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4334 (pFormat[0] != RPC_FC_LGVARRAY))
4336 ERR("invalid format type %x\n", pFormat[0]);
4337 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4338 return 0;
4341 alignment = pFormat[1] + 1;
4343 if (pFormat[0] == RPC_FC_SMVARRAY)
4345 pFormat += 2;
4346 size = *(const WORD*)pFormat;
4347 pFormat += sizeof(WORD);
4348 elements = *(const WORD*)pFormat;
4349 pFormat += sizeof(WORD);
4351 else
4353 pFormat += 2;
4354 size = *(const DWORD*)pFormat;
4355 pFormat += sizeof(DWORD);
4356 elements = *(const DWORD*)pFormat;
4357 pFormat += sizeof(DWORD);
4360 esize = *(const WORD*)pFormat;
4361 pFormat += sizeof(WORD);
4363 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4365 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4367 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
4368 pStubMsg->MemorySize += size;
4370 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4372 return pStubMsg->MemorySize;
4375 /***********************************************************************
4376 * NdrVaryingArrayFree [RPCRT4.@]
4378 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4379 unsigned char *pMemory,
4380 PFORMAT_STRING pFormat)
4382 unsigned char alignment;
4383 DWORD elements;
4385 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4387 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4388 (pFormat[0] != RPC_FC_LGVARRAY))
4390 ERR("invalid format type %x\n", pFormat[0]);
4391 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4392 return;
4395 alignment = pFormat[1] + 1;
4397 if (pFormat[0] == RPC_FC_SMVARRAY)
4399 pFormat += 2;
4400 pFormat += sizeof(WORD);
4401 elements = *(const WORD*)pFormat;
4402 pFormat += sizeof(WORD);
4404 else
4406 pFormat += 2;
4407 pFormat += sizeof(DWORD);
4408 elements = *(const DWORD*)pFormat;
4409 pFormat += sizeof(DWORD);
4412 pFormat += sizeof(WORD);
4414 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4415 if ((pStubMsg->ActualCount > elements) ||
4416 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4418 RpcRaiseException(RPC_S_INVALID_BOUND);
4419 return;
4422 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4425 /***********************************************************************
4426 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4428 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4429 unsigned char *pMemory,
4430 PFORMAT_STRING pFormat)
4432 FIXME("stub\n");
4433 return NULL;
4436 /***********************************************************************
4437 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4439 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4440 unsigned char **ppMemory,
4441 PFORMAT_STRING pFormat,
4442 unsigned char fMustAlloc)
4444 FIXME("stub\n");
4445 return NULL;
4448 /***********************************************************************
4449 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4451 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4452 unsigned char *pMemory,
4453 PFORMAT_STRING pFormat)
4455 FIXME("stub\n");
4458 /***********************************************************************
4459 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4461 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4462 PFORMAT_STRING pFormat)
4464 FIXME("stub\n");
4465 return 0;
4468 /***********************************************************************
4469 * NdrEncapsulatedUnionFree [RPCRT4.@]
4471 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4472 unsigned char *pMemory,
4473 PFORMAT_STRING pFormat)
4475 FIXME("stub\n");
4478 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4479 unsigned long discriminant,
4480 PFORMAT_STRING pFormat)
4482 unsigned short num_arms, arm, type;
4484 num_arms = *(const SHORT*)pFormat & 0x0fff;
4485 pFormat += 2;
4486 for(arm = 0; arm < num_arms; arm++)
4488 if(discriminant == *(const ULONG*)pFormat)
4490 pFormat += 4;
4491 break;
4493 pFormat += 6;
4496 type = *(const unsigned short*)pFormat;
4497 TRACE("type %04x\n", type);
4498 if(arm == num_arms) /* default arm extras */
4500 if(type == 0xffff)
4502 ERR("no arm for 0x%lx and no default case\n", discriminant);
4503 RpcRaiseException(RPC_S_INVALID_TAG);
4504 return NULL;
4506 if(type == 0)
4508 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4509 return NULL;
4512 return pFormat;
4515 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
4516 ULONG value,
4517 PFORMAT_STRING pFormat)
4519 pFormat += *(const SHORT*)pFormat;
4520 pFormat += 2;
4522 return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
4525 /***********************************************************************
4526 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4528 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4529 unsigned char *pMemory,
4530 PFORMAT_STRING pFormat)
4532 unsigned short type;
4533 unsigned char switch_type;
4535 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4536 pFormat++;
4538 switch_type = *pFormat;
4539 pFormat++;
4541 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4542 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4543 /* Marshall discriminant */
4544 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4546 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4547 if(!pFormat)
4548 return NULL;
4550 type = *(const unsigned short*)pFormat;
4551 if((type & 0xff00) == 0x8000)
4553 unsigned char basetype = LOBYTE(type);
4554 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4556 else
4558 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4559 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4560 if (m)
4562 unsigned char *saved_buffer = NULL;
4563 int pointer_buffer_mark_set = 0;
4564 switch(*desc)
4566 case RPC_FC_RP:
4567 case RPC_FC_UP:
4568 case RPC_FC_OP:
4569 case RPC_FC_FP:
4570 ALIGN_POINTER(pStubMsg->Buffer, 4);
4571 saved_buffer = pStubMsg->Buffer;
4572 if (pStubMsg->PointerBufferMark)
4574 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4575 pStubMsg->PointerBufferMark = NULL;
4576 pointer_buffer_mark_set = 1;
4578 else
4579 pStubMsg->Buffer += 4; /* for pointer ID */
4581 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4582 if (pointer_buffer_mark_set)
4584 STD_OVERFLOW_CHECK(pStubMsg);
4585 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4586 pStubMsg->Buffer = saved_buffer + 4;
4588 break;
4589 default:
4590 m(pStubMsg, pMemory, desc);
4593 else FIXME("no marshaller for embedded type %02x\n", *desc);
4595 STD_OVERFLOW_CHECK(pStubMsg);
4596 return NULL;
4599 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4600 PFORMAT_STRING *ppFormat)
4602 long discriminant = 0;
4604 switch(**ppFormat)
4606 case RPC_FC_BYTE:
4607 case RPC_FC_CHAR:
4608 case RPC_FC_SMALL:
4609 case RPC_FC_USMALL:
4610 discriminant = *(UCHAR *)pStubMsg->Buffer;
4611 pStubMsg->Buffer += sizeof(UCHAR);
4612 break;
4613 case RPC_FC_WCHAR:
4614 case RPC_FC_SHORT:
4615 case RPC_FC_USHORT:
4616 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4617 discriminant = *(USHORT *)pStubMsg->Buffer;
4618 pStubMsg->Buffer += sizeof(USHORT);
4619 break;
4620 case RPC_FC_LONG:
4621 case RPC_FC_ULONG:
4622 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4623 discriminant = *(ULONG *)pStubMsg->Buffer;
4624 pStubMsg->Buffer += sizeof(ULONG);
4625 break;
4626 default:
4627 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4629 (*ppFormat)++;
4631 if (pStubMsg->fHasNewCorrDesc)
4632 *ppFormat += 6;
4633 else
4634 *ppFormat += 4;
4635 return discriminant;
4638 /**********************************************************************
4639 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4641 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4642 unsigned char **ppMemory,
4643 PFORMAT_STRING pFormat,
4644 unsigned char fMustAlloc)
4646 long discriminant;
4647 unsigned short type, size;
4649 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4650 pFormat++;
4652 /* Unmarshall discriminant */
4653 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4654 TRACE("unmarshalled discriminant %lx\n", discriminant);
4656 pFormat += *(const SHORT*)pFormat;
4658 size = *(const unsigned short*)pFormat;
4659 pFormat += 2;
4661 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4662 if(!pFormat)
4663 return NULL;
4665 if(!*ppMemory || fMustAlloc)
4666 *ppMemory = NdrAllocate(pStubMsg, size);
4668 type = *(const unsigned short*)pFormat;
4669 if((type & 0xff00) == 0x8000)
4671 unsigned char basetype = LOBYTE(type);
4672 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4674 else
4676 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4677 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4678 if (m)
4680 unsigned char *saved_buffer = NULL;
4681 int pointer_buffer_mark_set = 0;
4682 switch(*desc)
4684 case RPC_FC_RP:
4685 case RPC_FC_UP:
4686 case RPC_FC_OP:
4687 case RPC_FC_FP:
4688 **(void***)ppMemory = NULL;
4689 ALIGN_POINTER(pStubMsg->Buffer, 4);
4690 saved_buffer = pStubMsg->Buffer;
4691 if (pStubMsg->PointerBufferMark)
4693 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4694 pStubMsg->PointerBufferMark = NULL;
4695 pointer_buffer_mark_set = 1;
4697 else
4698 pStubMsg->Buffer += 4; /* for pointer ID */
4700 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, fMustAlloc);
4701 if (pointer_buffer_mark_set)
4703 STD_OVERFLOW_CHECK(pStubMsg);
4704 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4705 pStubMsg->Buffer = saved_buffer + 4;
4707 break;
4708 default:
4709 m(pStubMsg, ppMemory, desc, fMustAlloc);
4712 else FIXME("no marshaller for embedded type %02x\n", *desc);
4714 return NULL;
4717 /***********************************************************************
4718 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4720 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4721 unsigned char *pMemory,
4722 PFORMAT_STRING pFormat)
4724 unsigned short type;
4725 unsigned char switch_type;
4727 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4728 pFormat++;
4730 switch_type = *pFormat;
4731 pFormat++;
4733 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4734 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4735 /* Add discriminant size */
4736 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4738 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4739 if(!pFormat)
4740 return;
4742 type = *(const unsigned short*)pFormat;
4743 if((type & 0xff00) == 0x8000)
4745 unsigned char basetype = LOBYTE(type);
4746 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4748 else
4750 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4751 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4752 if (m)
4754 switch(*desc)
4756 case RPC_FC_RP:
4757 case RPC_FC_UP:
4758 case RPC_FC_OP:
4759 case RPC_FC_FP:
4760 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4761 pStubMsg->BufferLength += 4; /* for pointer ID */
4762 if (!pStubMsg->IgnoreEmbeddedPointers)
4764 int saved_buffer_length = pStubMsg->BufferLength;
4765 pStubMsg->BufferLength = pStubMsg->PointerLength;
4766 pStubMsg->PointerLength = 0;
4767 if(!pStubMsg->BufferLength)
4768 ERR("BufferLength == 0??\n");
4769 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4770 pStubMsg->PointerLength = pStubMsg->BufferLength;
4771 pStubMsg->BufferLength = saved_buffer_length;
4773 break;
4774 default:
4775 m(pStubMsg, pMemory, desc);
4778 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4780 return;
4783 /***********************************************************************
4784 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4786 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4787 PFORMAT_STRING pFormat)
4789 ULONG discriminant;
4790 unsigned short type, size;
4792 pFormat++;
4793 /* Unmarshall discriminant */
4794 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4795 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
4797 pFormat += *(const SHORT*)pFormat;
4799 size = *(const unsigned short*)pFormat;
4800 pFormat += 2;
4802 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4803 if(!pFormat)
4804 return 0;
4806 pStubMsg->Memory += size;
4808 type = *(const unsigned short*)pFormat;
4809 if((type & 0xff00) == 0x8000)
4811 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4813 else
4815 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4816 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4817 unsigned char *saved_buffer;
4818 if (m)
4820 switch(*desc)
4822 case RPC_FC_RP:
4823 case RPC_FC_UP:
4824 case RPC_FC_OP:
4825 case RPC_FC_FP:
4826 ALIGN_POINTER(pStubMsg->Buffer, 4);
4827 saved_buffer = pStubMsg->Buffer;
4828 pStubMsg->Buffer += 4;
4829 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4830 pStubMsg->MemorySize += 4;
4831 if (!pStubMsg->IgnoreEmbeddedPointers)
4832 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4833 break;
4834 default:
4835 return m(pStubMsg, desc);
4838 else FIXME("no marshaller for embedded type %02x\n", *desc);
4841 TRACE("size %d\n", size);
4842 return size;
4845 /***********************************************************************
4846 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4848 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4849 unsigned char *pMemory,
4850 PFORMAT_STRING pFormat)
4852 FIXME("stub\n");
4855 /***********************************************************************
4856 * NdrByteCountPointerMarshall [RPCRT4.@]
4858 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4859 unsigned char *pMemory,
4860 PFORMAT_STRING pFormat)
4862 FIXME("stub\n");
4863 return NULL;
4866 /***********************************************************************
4867 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4869 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4870 unsigned char **ppMemory,
4871 PFORMAT_STRING pFormat,
4872 unsigned char fMustAlloc)
4874 FIXME("stub\n");
4875 return NULL;
4878 /***********************************************************************
4879 * NdrByteCountPointerBufferSize [RPCRT4.@]
4881 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4882 unsigned char *pMemory,
4883 PFORMAT_STRING pFormat)
4885 FIXME("stub\n");
4888 /***********************************************************************
4889 * NdrByteCountPointerMemorySize [RPCRT4.@]
4891 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4892 PFORMAT_STRING pFormat)
4894 FIXME("stub\n");
4895 return 0;
4898 /***********************************************************************
4899 * NdrByteCountPointerFree [RPCRT4.@]
4901 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4902 unsigned char *pMemory,
4903 PFORMAT_STRING pFormat)
4905 FIXME("stub\n");
4908 /***********************************************************************
4909 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4911 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4912 unsigned char *pMemory,
4913 PFORMAT_STRING pFormat)
4915 FIXME("stub\n");
4916 return NULL;
4919 /***********************************************************************
4920 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4922 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4923 unsigned char **ppMemory,
4924 PFORMAT_STRING pFormat,
4925 unsigned char fMustAlloc)
4927 FIXME("stub\n");
4928 return NULL;
4931 /***********************************************************************
4932 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4934 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4935 unsigned char *pMemory,
4936 PFORMAT_STRING pFormat)
4938 FIXME("stub\n");
4941 /***********************************************************************
4942 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4944 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4945 PFORMAT_STRING pFormat)
4947 FIXME("stub\n");
4948 return 0;
4951 /***********************************************************************
4952 * NdrXmitOrRepAsFree [RPCRT4.@]
4954 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4955 unsigned char *pMemory,
4956 PFORMAT_STRING pFormat)
4958 FIXME("stub\n");
4961 #include "pshpack1.h"
4962 typedef struct
4964 unsigned char type;
4965 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
4966 ULONG low_value;
4967 ULONG high_value;
4968 } NDR_RANGE;
4969 #include "poppack.h"
4971 /***********************************************************************
4972 * NdrRangeMarshall [internal]
4974 unsigned char *WINAPI NdrRangeMarshall(
4975 PMIDL_STUB_MESSAGE pStubMsg,
4976 unsigned char *pMemory,
4977 PFORMAT_STRING pFormat)
4979 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
4980 unsigned char base_type;
4982 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4984 if (pRange->type != RPC_FC_RANGE)
4986 ERR("invalid format type %x\n", pRange->type);
4987 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4988 return NULL;
4991 base_type = pRange->flags_type & 0xf;
4993 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
4996 /***********************************************************************
4997 * NdrRangeUnmarshall
4999 unsigned char *WINAPI NdrRangeUnmarshall(
5000 PMIDL_STUB_MESSAGE pStubMsg,
5001 unsigned char **ppMemory,
5002 PFORMAT_STRING pFormat,
5003 unsigned char fMustAlloc)
5005 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5006 unsigned char base_type;
5008 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5010 if (pRange->type != RPC_FC_RANGE)
5012 ERR("invalid format type %x\n", pRange->type);
5013 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5014 return NULL;
5016 base_type = pRange->flags_type & 0xf;
5018 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5019 base_type, pRange->low_value, pRange->high_value);
5021 #define RANGE_UNMARSHALL(type, format_spec) \
5022 do \
5024 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5025 if (fMustAlloc || !*ppMemory) \
5026 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5027 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5028 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5030 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5031 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5032 (type)pRange->high_value); \
5033 RpcRaiseException(RPC_S_INVALID_BOUND); \
5034 return NULL; \
5036 TRACE("*ppMemory: %p\n", *ppMemory); \
5037 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5038 pStubMsg->Buffer += sizeof(type); \
5039 } while (0)
5041 switch(base_type)
5043 case RPC_FC_CHAR:
5044 case RPC_FC_SMALL:
5045 RANGE_UNMARSHALL(UCHAR, "%d");
5046 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5047 break;
5048 case RPC_FC_BYTE:
5049 case RPC_FC_USMALL:
5050 RANGE_UNMARSHALL(CHAR, "%u");
5051 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5052 break;
5053 case RPC_FC_WCHAR: /* FIXME: valid? */
5054 case RPC_FC_USHORT:
5055 RANGE_UNMARSHALL(USHORT, "%u");
5056 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5057 break;
5058 case RPC_FC_SHORT:
5059 RANGE_UNMARSHALL(SHORT, "%d");
5060 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5061 break;
5062 case RPC_FC_LONG:
5063 RANGE_UNMARSHALL(LONG, "%d");
5064 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5065 break;
5066 case RPC_FC_ULONG:
5067 RANGE_UNMARSHALL(ULONG, "%u");
5068 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5069 break;
5070 case RPC_FC_ENUM16:
5071 case RPC_FC_ENUM32:
5072 FIXME("Unhandled enum type\n");
5073 break;
5074 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5075 case RPC_FC_FLOAT:
5076 case RPC_FC_DOUBLE:
5077 case RPC_FC_HYPER:
5078 default:
5079 ERR("invalid range base type: 0x%02x\n", base_type);
5080 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5083 return NULL;
5086 /***********************************************************************
5087 * NdrRangeBufferSize [internal]
5089 void WINAPI NdrRangeBufferSize(
5090 PMIDL_STUB_MESSAGE pStubMsg,
5091 unsigned char *pMemory,
5092 PFORMAT_STRING pFormat)
5094 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5095 unsigned char base_type;
5097 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5099 if (pRange->type != RPC_FC_RANGE)
5101 ERR("invalid format type %x\n", pRange->type);
5102 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5104 base_type = pRange->flags_type & 0xf;
5106 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5109 /***********************************************************************
5110 * NdrRangeMemorySize [internal]
5112 ULONG WINAPI NdrRangeMemorySize(
5113 PMIDL_STUB_MESSAGE pStubMsg,
5114 PFORMAT_STRING pFormat)
5116 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5117 unsigned char base_type;
5119 if (pRange->type != RPC_FC_RANGE)
5121 ERR("invalid format type %x\n", pRange->type);
5122 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5123 return 0;
5125 base_type = pRange->flags_type & 0xf;
5127 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5130 /***********************************************************************
5131 * NdrRangeFree [internal]
5133 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5134 unsigned char *pMemory,
5135 PFORMAT_STRING pFormat)
5137 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5139 /* nothing to do */
5142 /***********************************************************************
5143 * NdrBaseTypeMarshall [internal]
5145 static unsigned char *WINAPI NdrBaseTypeMarshall(
5146 PMIDL_STUB_MESSAGE pStubMsg,
5147 unsigned char *pMemory,
5148 PFORMAT_STRING pFormat)
5150 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5152 switch(*pFormat)
5154 case RPC_FC_BYTE:
5155 case RPC_FC_CHAR:
5156 case RPC_FC_SMALL:
5157 case RPC_FC_USMALL:
5158 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
5159 pStubMsg->Buffer += sizeof(UCHAR);
5160 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
5161 break;
5162 case RPC_FC_WCHAR:
5163 case RPC_FC_SHORT:
5164 case RPC_FC_USHORT:
5165 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5166 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
5167 pStubMsg->Buffer += sizeof(USHORT);
5168 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5169 break;
5170 case RPC_FC_LONG:
5171 case RPC_FC_ULONG:
5172 case RPC_FC_ERROR_STATUS_T:
5173 case RPC_FC_ENUM32:
5174 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5175 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
5176 pStubMsg->Buffer += sizeof(ULONG);
5177 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5178 break;
5179 case RPC_FC_FLOAT:
5180 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
5181 *(float *)pStubMsg->Buffer = *(float *)pMemory;
5182 pStubMsg->Buffer += sizeof(float);
5183 break;
5184 case RPC_FC_DOUBLE:
5185 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
5186 *(double *)pStubMsg->Buffer = *(double *)pMemory;
5187 pStubMsg->Buffer += sizeof(double);
5188 break;
5189 case RPC_FC_HYPER:
5190 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
5191 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
5192 pStubMsg->Buffer += sizeof(ULONGLONG);
5193 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5194 break;
5195 case RPC_FC_ENUM16:
5196 /* only 16-bits on the wire, so do a sanity check */
5197 if (*(UINT *)pMemory > USHRT_MAX)
5198 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5199 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5200 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5201 pStubMsg->Buffer += sizeof(USHORT);
5202 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5203 break;
5204 default:
5205 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5208 STD_OVERFLOW_CHECK(pStubMsg);
5210 /* FIXME: what is the correct return value? */
5211 return NULL;
5214 /***********************************************************************
5215 * NdrBaseTypeUnmarshall [internal]
5217 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5218 PMIDL_STUB_MESSAGE pStubMsg,
5219 unsigned char **ppMemory,
5220 PFORMAT_STRING pFormat,
5221 unsigned char fMustAlloc)
5223 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5225 #define BASE_TYPE_UNMARSHALL(type) \
5226 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5227 if (fMustAlloc || !*ppMemory) \
5228 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5229 TRACE("*ppMemory: %p\n", *ppMemory); \
5230 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5231 pStubMsg->Buffer += sizeof(type);
5233 switch(*pFormat)
5235 case RPC_FC_BYTE:
5236 case RPC_FC_CHAR:
5237 case RPC_FC_SMALL:
5238 case RPC_FC_USMALL:
5239 BASE_TYPE_UNMARSHALL(UCHAR);
5240 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
5241 break;
5242 case RPC_FC_WCHAR:
5243 case RPC_FC_SHORT:
5244 case RPC_FC_USHORT:
5245 BASE_TYPE_UNMARSHALL(USHORT);
5246 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5247 break;
5248 case RPC_FC_LONG:
5249 case RPC_FC_ULONG:
5250 case RPC_FC_ERROR_STATUS_T:
5251 case RPC_FC_ENUM32:
5252 BASE_TYPE_UNMARSHALL(ULONG);
5253 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5254 break;
5255 case RPC_FC_FLOAT:
5256 BASE_TYPE_UNMARSHALL(float);
5257 TRACE("value: %f\n", **(float **)ppMemory);
5258 break;
5259 case RPC_FC_DOUBLE:
5260 BASE_TYPE_UNMARSHALL(double);
5261 TRACE("value: %f\n", **(double **)ppMemory);
5262 break;
5263 case RPC_FC_HYPER:
5264 BASE_TYPE_UNMARSHALL(ULONGLONG);
5265 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
5266 break;
5267 case RPC_FC_ENUM16:
5268 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5269 if (fMustAlloc || !*ppMemory)
5270 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
5271 TRACE("*ppMemory: %p\n", *ppMemory);
5272 /* 16-bits on the wire, but int in memory */
5273 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
5274 pStubMsg->Buffer += sizeof(USHORT);
5275 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
5276 break;
5277 default:
5278 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5280 #undef BASE_TYPE_UNMARSHALL
5282 /* FIXME: what is the correct return value? */
5284 return NULL;
5287 /***********************************************************************
5288 * NdrBaseTypeBufferSize [internal]
5290 static void WINAPI NdrBaseTypeBufferSize(
5291 PMIDL_STUB_MESSAGE pStubMsg,
5292 unsigned char *pMemory,
5293 PFORMAT_STRING pFormat)
5295 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5297 switch(*pFormat)
5299 case RPC_FC_BYTE:
5300 case RPC_FC_CHAR:
5301 case RPC_FC_SMALL:
5302 case RPC_FC_USMALL:
5303 pStubMsg->BufferLength += sizeof(UCHAR);
5304 break;
5305 case RPC_FC_WCHAR:
5306 case RPC_FC_SHORT:
5307 case RPC_FC_USHORT:
5308 case RPC_FC_ENUM16:
5309 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
5310 pStubMsg->BufferLength += sizeof(USHORT);
5311 break;
5312 case RPC_FC_LONG:
5313 case RPC_FC_ULONG:
5314 case RPC_FC_ENUM32:
5315 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
5316 pStubMsg->BufferLength += sizeof(ULONG);
5317 break;
5318 case RPC_FC_FLOAT:
5319 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
5320 pStubMsg->BufferLength += sizeof(float);
5321 break;
5322 case RPC_FC_DOUBLE:
5323 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
5324 pStubMsg->BufferLength += sizeof(double);
5325 break;
5326 case RPC_FC_HYPER:
5327 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
5328 pStubMsg->BufferLength += sizeof(ULONGLONG);
5329 break;
5330 case RPC_FC_ERROR_STATUS_T:
5331 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
5332 pStubMsg->BufferLength += sizeof(error_status_t);
5333 break;
5334 default:
5335 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5339 /***********************************************************************
5340 * NdrBaseTypeMemorySize [internal]
5342 static ULONG WINAPI NdrBaseTypeMemorySize(
5343 PMIDL_STUB_MESSAGE pStubMsg,
5344 PFORMAT_STRING pFormat)
5346 switch(*pFormat)
5348 case RPC_FC_BYTE:
5349 case RPC_FC_CHAR:
5350 case RPC_FC_SMALL:
5351 case RPC_FC_USMALL:
5352 pStubMsg->Buffer += sizeof(UCHAR);
5353 pStubMsg->MemorySize += sizeof(UCHAR);
5354 return sizeof(UCHAR);
5355 case RPC_FC_WCHAR:
5356 case RPC_FC_SHORT:
5357 case RPC_FC_USHORT:
5358 pStubMsg->Buffer += sizeof(USHORT);
5359 pStubMsg->MemorySize += sizeof(USHORT);
5360 return sizeof(USHORT);
5361 case RPC_FC_LONG:
5362 case RPC_FC_ULONG:
5363 pStubMsg->Buffer += sizeof(ULONG);
5364 pStubMsg->MemorySize += sizeof(ULONG);
5365 return sizeof(ULONG);
5366 case RPC_FC_FLOAT:
5367 pStubMsg->Buffer += sizeof(float);
5368 pStubMsg->MemorySize += sizeof(float);
5369 return sizeof(float);
5370 case RPC_FC_DOUBLE:
5371 pStubMsg->Buffer += sizeof(double);
5372 pStubMsg->MemorySize += sizeof(double);
5373 return sizeof(double);
5374 case RPC_FC_HYPER:
5375 pStubMsg->Buffer += sizeof(ULONGLONG);
5376 pStubMsg->MemorySize += sizeof(ULONGLONG);
5377 return sizeof(ULONGLONG);
5378 case RPC_FC_ERROR_STATUS_T:
5379 pStubMsg->Buffer += sizeof(error_status_t);
5380 pStubMsg->MemorySize += sizeof(error_status_t);
5381 return sizeof(error_status_t);
5382 case RPC_FC_ENUM16:
5383 case RPC_FC_ENUM32:
5384 pStubMsg->Buffer += sizeof(INT);
5385 pStubMsg->MemorySize += sizeof(INT);
5386 return sizeof(INT);
5387 default:
5388 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5389 return 0;
5393 /***********************************************************************
5394 * NdrBaseTypeFree [internal]
5396 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
5397 unsigned char *pMemory,
5398 PFORMAT_STRING pFormat)
5400 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5402 /* nothing to do */
5405 /***********************************************************************
5406 * NdrContextHandleBufferSize [internal]
5408 static void WINAPI NdrContextHandleBufferSize(
5409 PMIDL_STUB_MESSAGE pStubMsg,
5410 unsigned char *pMemory,
5411 PFORMAT_STRING pFormat)
5413 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5415 if (*pFormat != RPC_FC_BIND_CONTEXT)
5417 ERR("invalid format type %x\n", *pFormat);
5418 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5420 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5421 pStubMsg->BufferLength += cbNDRContext;
5424 /***********************************************************************
5425 * NdrContextHandleMarshall [internal]
5427 static unsigned char *WINAPI NdrContextHandleMarshall(
5428 PMIDL_STUB_MESSAGE pStubMsg,
5429 unsigned char *pMemory,
5430 PFORMAT_STRING pFormat)
5432 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5434 if (*pFormat != RPC_FC_BIND_CONTEXT)
5436 ERR("invalid format type %x\n", *pFormat);
5437 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5440 if (pFormat[1] & 0x80)
5441 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
5442 else
5443 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
5445 return NULL;
5448 /***********************************************************************
5449 * NdrContextHandleUnmarshall [internal]
5451 static unsigned char *WINAPI NdrContextHandleUnmarshall(
5452 PMIDL_STUB_MESSAGE pStubMsg,
5453 unsigned char **ppMemory,
5454 PFORMAT_STRING pFormat,
5455 unsigned char fMustAlloc)
5457 if (*pFormat != RPC_FC_BIND_CONTEXT)
5459 ERR("invalid format type %x\n", *pFormat);
5460 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5463 **(NDR_CCONTEXT **)ppMemory = NULL;
5464 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
5466 return NULL;
5469 /***********************************************************************
5470 * NdrClientContextMarshall [RPCRT4.@]
5472 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5473 NDR_CCONTEXT ContextHandle,
5474 int fCheck)
5476 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
5478 ALIGN_POINTER(pStubMsg->Buffer, 4);
5480 /* FIXME: what does fCheck do? */
5481 NDRCContextMarshall(ContextHandle,
5482 pStubMsg->Buffer);
5484 pStubMsg->Buffer += cbNDRContext;
5487 /***********************************************************************
5488 * NdrClientContextUnmarshall [RPCRT4.@]
5490 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5491 NDR_CCONTEXT * pContextHandle,
5492 RPC_BINDING_HANDLE BindHandle)
5494 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
5496 ALIGN_POINTER(pStubMsg->Buffer, 4);
5498 NDRCContextUnmarshall(pContextHandle,
5499 BindHandle,
5500 pStubMsg->Buffer,
5501 pStubMsg->RpcMsg->DataRepresentation);
5503 pStubMsg->Buffer += cbNDRContext;
5506 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5507 NDR_SCONTEXT ContextHandle,
5508 NDR_RUNDOWN RundownRoutine )
5510 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
5513 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
5515 FIXME("(%p): stub\n", pStubMsg);
5516 return NULL;
5519 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
5520 unsigned char* pMemory,
5521 PFORMAT_STRING pFormat)
5523 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
5526 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
5527 PFORMAT_STRING pFormat)
5529 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5530 return NULL;
5533 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5534 NDR_SCONTEXT ContextHandle,
5535 NDR_RUNDOWN RundownRoutine,
5536 PFORMAT_STRING pFormat)
5538 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
5541 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5542 PFORMAT_STRING pFormat)
5544 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
5545 return NULL;
5548 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5550 typedef struct ndr_context_handle
5552 DWORD attributes;
5553 GUID uuid;
5554 } ndr_context_handle;
5556 struct context_handle_entry
5558 struct list entry;
5559 DWORD magic;
5560 RPC_BINDING_HANDLE handle;
5561 ndr_context_handle wire_data;
5564 static struct list context_handle_list = LIST_INIT(context_handle_list);
5566 static CRITICAL_SECTION ndr_context_cs;
5567 static CRITICAL_SECTION_DEBUG ndr_context_debug =
5569 0, 0, &ndr_context_cs,
5570 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
5571 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
5573 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
5575 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
5577 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
5579 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
5580 return NULL;
5581 return che;
5584 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
5586 struct context_handle_entry *che;
5587 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
5588 if (IsEqualGUID(&che->wire_data.uuid, uuid))
5589 return che;
5590 return NULL;
5593 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
5595 struct context_handle_entry *che;
5596 RPC_BINDING_HANDLE handle = NULL;
5598 TRACE("%p\n", CContext);
5600 EnterCriticalSection(&ndr_context_cs);
5601 che = get_context_entry(CContext);
5602 if (che)
5603 handle = che->handle;
5604 LeaveCriticalSection(&ndr_context_cs);
5606 if (!handle)
5607 RpcRaiseException(ERROR_INVALID_HANDLE);
5608 return handle;
5611 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
5613 struct context_handle_entry *che;
5615 TRACE("%p %p\n", CContext, pBuff);
5617 if (CContext)
5619 EnterCriticalSection(&ndr_context_cs);
5620 che = get_context_entry(CContext);
5621 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
5622 LeaveCriticalSection(&ndr_context_cs);
5624 else
5626 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
5627 wire_data->attributes = 0;
5628 wire_data->uuid = GUID_NULL;
5632 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
5633 RPC_BINDING_HANDLE hBinding,
5634 ndr_context_handle *chi)
5636 struct context_handle_entry *che = NULL;
5638 /* a null UUID means we should free the context handle */
5639 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
5641 if (*CContext)
5643 che = get_context_entry(*CContext);
5644 if (!che)
5645 return ERROR_INVALID_HANDLE;
5646 list_remove(&che->entry);
5647 RpcBindingFree(&che->handle);
5648 HeapFree(GetProcessHeap(), 0, che);
5649 che = NULL;
5652 /* if there's no existing entry matching the GUID, allocate one */
5653 else if (!(che = context_entry_from_guid(&chi->uuid)))
5655 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
5656 if (!che)
5657 return ERROR_NOT_ENOUGH_MEMORY;
5658 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
5659 RpcBindingCopy(hBinding, &che->handle);
5660 list_add_tail(&context_handle_list, &che->entry);
5661 memcpy(&che->wire_data, chi, sizeof *chi);
5664 *CContext = che;
5666 return ERROR_SUCCESS;
5669 /***********************************************************************
5670 * NDRCContextUnmarshall [RPCRT4.@]
5672 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
5673 RPC_BINDING_HANDLE hBinding,
5674 void *pBuff, ULONG DataRepresentation)
5676 UINT r;
5678 TRACE("*%p=(%p) %p %p %08x\n",
5679 CContext, *CContext, hBinding, pBuff, DataRepresentation);
5681 EnterCriticalSection(&ndr_context_cs);
5682 r = ndr_update_context_handle(CContext, hBinding, pBuff);
5683 LeaveCriticalSection(&ndr_context_cs);
5684 if (r)
5685 RpcRaiseException(r);
5688 /***********************************************************************
5689 * NDRSContextMarshall [RPCRT4.@]
5691 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
5692 void *pBuff,
5693 NDR_RUNDOWN userRunDownIn)
5695 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
5698 /***********************************************************************
5699 * NDRSContextMarshallEx [RPCRT4.@]
5701 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
5702 NDR_SCONTEXT CContext,
5703 void *pBuff,
5704 NDR_RUNDOWN userRunDownIn)
5706 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
5709 /***********************************************************************
5710 * NDRSContextMarshall2 [RPCRT4.@]
5712 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
5713 NDR_SCONTEXT CContext,
5714 void *pBuff,
5715 NDR_RUNDOWN userRunDownIn,
5716 void *CtxGuard, ULONG Flags)
5718 FIXME("(%p %p %p %p %p %u): stub\n",
5719 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5722 /***********************************************************************
5723 * NDRSContextUnmarshall [RPCRT4.@]
5725 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5726 ULONG DataRepresentation)
5728 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
5729 return NULL;
5732 /***********************************************************************
5733 * NDRSContextUnmarshallEx [RPCRT4.@]
5735 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5736 void *pBuff,
5737 ULONG DataRepresentation)
5739 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
5740 return NULL;
5743 /***********************************************************************
5744 * NDRSContextUnmarshall2 [RPCRT4.@]
5746 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5747 void *pBuff,
5748 ULONG DataRepresentation,
5749 void *CtxGuard, ULONG Flags)
5751 FIXME("(%p %p %08x %p %u): stub\n",
5752 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
5753 return NULL;