winex11.drv: Make sure the drawable rect is always updated and use it where appropriate.
[wine/testsucceed.git] / dlls / rpcrt4 / ndr_marshall.c
blobf5aee7691b8f54a94232375625f415509a00b0ca
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 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
124 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
125 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
126 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
127 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
128 /* 0x10 */
129 NdrBaseTypeMarshall,
130 /* 0x11 */
131 NdrPointerMarshall, NdrPointerMarshall,
132 NdrPointerMarshall, NdrPointerMarshall,
133 /* 0x15 */
134 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
135 NdrConformantStructMarshall, NdrConformantStructMarshall,
136 NdrConformantVaryingStructMarshall,
137 NdrComplexStructMarshall,
138 /* 0x1b */
139 NdrConformantArrayMarshall,
140 NdrConformantVaryingArrayMarshall,
141 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
142 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
143 NdrComplexArrayMarshall,
144 /* 0x22 */
145 NdrConformantStringMarshall, 0, 0,
146 NdrConformantStringMarshall,
147 NdrNonConformantStringMarshall, 0, 0, 0,
148 /* 0x2a */
149 NdrEncapsulatedUnionMarshall,
150 NdrNonEncapsulatedUnionMarshall,
151 NdrByteCountPointerMarshall,
152 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
153 /* 0x2f */
154 NdrInterfacePointerMarshall,
155 /* 0xb0 */
156 0, 0, 0, 0,
157 NdrUserMarshalMarshall
159 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
161 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
162 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
163 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
164 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
165 /* 0x10 */
166 NdrBaseTypeUnmarshall,
167 /* 0x11 */
168 NdrPointerUnmarshall, NdrPointerUnmarshall,
169 NdrPointerUnmarshall, NdrPointerUnmarshall,
170 /* 0x15 */
171 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
172 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
173 NdrConformantVaryingStructUnmarshall,
174 NdrComplexStructUnmarshall,
175 /* 0x1b */
176 NdrConformantArrayUnmarshall,
177 NdrConformantVaryingArrayUnmarshall,
178 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
179 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
180 NdrComplexArrayUnmarshall,
181 /* 0x22 */
182 NdrConformantStringUnmarshall, 0, 0,
183 NdrConformantStringUnmarshall,
184 NdrNonConformantStringUnmarshall, 0, 0, 0,
185 /* 0x2a */
186 NdrEncapsulatedUnionUnmarshall,
187 NdrNonEncapsulatedUnionUnmarshall,
188 NdrByteCountPointerUnmarshall,
189 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
190 /* 0x2f */
191 NdrInterfacePointerUnmarshall,
192 /* 0xb0 */
193 0, 0, 0, 0,
194 NdrUserMarshalUnmarshall
196 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
198 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
199 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
200 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
201 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
202 /* 0x10 */
203 NdrBaseTypeBufferSize,
204 /* 0x11 */
205 NdrPointerBufferSize, NdrPointerBufferSize,
206 NdrPointerBufferSize, NdrPointerBufferSize,
207 /* 0x15 */
208 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
209 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
210 NdrConformantVaryingStructBufferSize,
211 NdrComplexStructBufferSize,
212 /* 0x1b */
213 NdrConformantArrayBufferSize,
214 NdrConformantVaryingArrayBufferSize,
215 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
216 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
217 NdrComplexArrayBufferSize,
218 /* 0x22 */
219 NdrConformantStringBufferSize, 0, 0,
220 NdrConformantStringBufferSize,
221 NdrNonConformantStringBufferSize, 0, 0, 0,
222 /* 0x2a */
223 NdrEncapsulatedUnionBufferSize,
224 NdrNonEncapsulatedUnionBufferSize,
225 NdrByteCountPointerBufferSize,
226 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
227 /* 0x2f */
228 NdrInterfacePointerBufferSize,
229 /* 0xb0 */
230 0, 0, 0, 0,
231 NdrUserMarshalBufferSize
233 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
235 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
236 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
237 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
238 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
239 /* 0x10 */
240 NdrBaseTypeMemorySize,
241 /* 0x11 */
242 NdrPointerMemorySize, NdrPointerMemorySize,
243 NdrPointerMemorySize, NdrPointerMemorySize,
244 /* 0x15 */
245 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
246 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
247 NdrConformantVaryingStructMemorySize,
248 NdrComplexStructMemorySize,
249 /* 0x1b */
250 NdrConformantArrayMemorySize,
251 NdrConformantVaryingArrayMemorySize,
252 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
253 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
254 NdrComplexArrayMemorySize,
255 /* 0x22 */
256 NdrConformantStringMemorySize, 0, 0,
257 NdrConformantStringMemorySize,
258 NdrNonConformantStringMemorySize, 0, 0, 0,
259 /* 0x2a */
260 NdrEncapsulatedUnionMemorySize,
261 NdrNonEncapsulatedUnionMemorySize,
262 NdrByteCountPointerMemorySize,
263 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
264 /* 0x2f */
265 NdrInterfacePointerMemorySize,
266 /* 0xb0 */
267 0, 0, 0, 0,
268 NdrUserMarshalMemorySize
270 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
272 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
273 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
274 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
275 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
276 /* 0x10 */
277 NdrBaseTypeFree,
278 /* 0x11 */
279 NdrPointerFree, NdrPointerFree,
280 NdrPointerFree, NdrPointerFree,
281 /* 0x15 */
282 NdrSimpleStructFree, NdrSimpleStructFree,
283 NdrConformantStructFree, NdrConformantStructFree,
284 NdrConformantVaryingStructFree,
285 NdrComplexStructFree,
286 /* 0x1b */
287 NdrConformantArrayFree,
288 NdrConformantVaryingArrayFree,
289 NdrFixedArrayFree, NdrFixedArrayFree,
290 NdrVaryingArrayFree, NdrVaryingArrayFree,
291 NdrComplexArrayFree,
292 /* 0x22 */
293 0, 0, 0,
294 0, 0, 0, 0, 0,
295 /* 0x2a */
296 NdrEncapsulatedUnionFree,
297 NdrNonEncapsulatedUnionFree,
299 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
300 /* 0x2f */
301 NdrInterfacePointerFree,
302 /* 0xb0 */
303 0, 0, 0, 0,
304 NdrUserMarshalFree
307 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
309 /* hmm, this is probably supposed to do more? */
310 return pStubMsg->pfnAllocate(len);
313 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
315 pStubMsg->pfnFree(Pointer);
318 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
320 return (*(const ULONG *)pFormat != -1);
323 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
325 ALIGN_POINTER(pStubMsg->Buffer, 4);
326 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
327 pStubMsg->Buffer += 4;
328 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
329 if (pStubMsg->fHasNewCorrDesc)
330 return pFormat+6;
331 else
332 return pFormat+4;
335 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
337 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
339 pStubMsg->Offset = 0;
340 pStubMsg->ActualCount = pStubMsg->MaxCount;
341 goto done;
344 ALIGN_POINTER(pStubMsg->Buffer, 4);
345 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
346 pStubMsg->Buffer += 4;
347 TRACE("offset is %d\n", pStubMsg->Offset);
348 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
349 pStubMsg->Buffer += 4;
350 TRACE("variance is %d\n", pStubMsg->ActualCount);
352 if ((pStubMsg->ActualCount > MaxValue) ||
353 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
355 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
356 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
357 RpcRaiseException(RPC_S_INVALID_BOUND);
358 return NULL;
361 done:
362 if (pStubMsg->fHasNewCorrDesc)
363 return pFormat+6;
364 else
365 return pFormat+4;
368 /* writes the conformance value to the buffer */
369 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
371 ALIGN_POINTER(pStubMsg->Buffer, 4);
372 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
373 pStubMsg->Buffer += 4;
376 /* writes the variance values to the buffer */
377 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
379 ALIGN_POINTER(pStubMsg->Buffer, 4);
380 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
381 pStubMsg->Buffer += 4;
382 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
383 pStubMsg->Buffer += 4;
386 /* requests buffer space for the conformance value */
387 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
389 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
390 pStubMsg->BufferLength += 4;
393 /* requests buffer space for the variance values */
394 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
396 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
397 pStubMsg->BufferLength += 8;
400 PFORMAT_STRING ComputeConformanceOrVariance(
401 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
402 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
404 BYTE dtype = pFormat[0] & 0xf;
405 short ofs = *(const short *)&pFormat[2];
406 LPVOID ptr = NULL;
407 DWORD data = 0;
409 if (!IsConformanceOrVariancePresent(pFormat)) {
410 /* null descriptor */
411 *pCount = def;
412 goto finish_conf;
415 switch (pFormat[0] & 0xf0) {
416 case RPC_FC_NORMAL_CONFORMANCE:
417 TRACE("normal conformance, ofs=%d\n", ofs);
418 ptr = pMemory;
419 break;
420 case RPC_FC_POINTER_CONFORMANCE:
421 TRACE("pointer conformance, ofs=%d\n", ofs);
422 ptr = pStubMsg->Memory;
423 break;
424 case RPC_FC_TOP_LEVEL_CONFORMANCE:
425 TRACE("toplevel conformance, ofs=%d\n", ofs);
426 if (pStubMsg->StackTop) {
427 ptr = pStubMsg->StackTop;
429 else {
430 /* -Os mode, *pCount is already set */
431 goto finish_conf;
433 break;
434 case RPC_FC_CONSTANT_CONFORMANCE:
435 data = ofs | ((DWORD)pFormat[1] << 16);
436 TRACE("constant conformance, val=%d\n", data);
437 *pCount = data;
438 goto finish_conf;
439 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
440 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
441 if (pStubMsg->StackTop) {
442 ptr = pStubMsg->StackTop;
444 else {
445 /* ? */
446 goto done_conf_grab;
448 break;
449 default:
450 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
453 switch (pFormat[1]) {
454 case RPC_FC_DEREFERENCE:
455 ptr = *(LPVOID*)((char *)ptr + ofs);
456 break;
457 case RPC_FC_CALLBACK:
459 unsigned char *old_stack_top = pStubMsg->StackTop;
460 pStubMsg->StackTop = ptr;
462 /* ofs is index into StubDesc->apfnExprEval */
463 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
464 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
466 pStubMsg->StackTop = old_stack_top;
468 /* the callback function always stores the computed value in MaxCount */
469 *pCount = pStubMsg->MaxCount;
470 goto finish_conf;
472 default:
473 ptr = (char *)ptr + ofs;
474 break;
477 switch (dtype) {
478 case RPC_FC_LONG:
479 case RPC_FC_ULONG:
480 data = *(DWORD*)ptr;
481 break;
482 case RPC_FC_SHORT:
483 data = *(SHORT*)ptr;
484 break;
485 case RPC_FC_USHORT:
486 data = *(USHORT*)ptr;
487 break;
488 case RPC_FC_CHAR:
489 case RPC_FC_SMALL:
490 data = *(CHAR*)ptr;
491 break;
492 case RPC_FC_BYTE:
493 case RPC_FC_USMALL:
494 data = *(UCHAR*)ptr;
495 break;
496 default:
497 FIXME("unknown conformance data type %x\n", dtype);
498 goto done_conf_grab;
500 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
502 done_conf_grab:
503 switch (pFormat[1]) {
504 case RPC_FC_DEREFERENCE: /* already handled */
505 case 0: /* no op */
506 *pCount = data;
507 break;
508 case RPC_FC_ADD_1:
509 *pCount = data + 1;
510 break;
511 case RPC_FC_SUB_1:
512 *pCount = data - 1;
513 break;
514 case RPC_FC_MULT_2:
515 *pCount = data * 2;
516 break;
517 case RPC_FC_DIV_2:
518 *pCount = data / 2;
519 break;
520 default:
521 FIXME("unknown conformance op %d\n", pFormat[1]);
522 goto finish_conf;
525 finish_conf:
526 TRACE("resulting conformance is %ld\n", *pCount);
527 if (pStubMsg->fHasNewCorrDesc)
528 return pFormat+6;
529 else
530 return pFormat+4;
533 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
534 * the result overflows 32-bits */
535 inline static ULONG safe_multiply(ULONG a, ULONG b)
537 ULONGLONG ret = (ULONGLONG)a * b;
538 if (ret > 0xffffffff)
540 RpcRaiseException(RPC_S_INVALID_BOUND);
541 return 0;
543 return ret;
548 * NdrConformantString:
550 * What MS calls a ConformantString is, in DCE terminology,
551 * a Varying-Conformant String.
553 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
554 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
555 * into unmarshalled string)
556 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
557 * [
558 * data: CHARTYPE[maxlen]
559 * ]
560 * ], where CHARTYPE is the appropriate character type (specified externally)
564 /***********************************************************************
565 * NdrConformantStringMarshall [RPCRT4.@]
567 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
568 unsigned char *pszMessage, PFORMAT_STRING pFormat)
570 ULONG esize, size;
572 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
574 if (*pFormat == RPC_FC_C_CSTRING) {
575 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
576 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
577 esize = 1;
579 else if (*pFormat == RPC_FC_C_WSTRING) {
580 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
581 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
582 esize = 2;
584 else {
585 ERR("Unhandled string type: %#x\n", *pFormat);
586 /* FIXME: raise an exception. */
587 return NULL;
590 if (pFormat[1] == RPC_FC_STRING_SIZED)
591 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
592 else
593 pStubMsg->MaxCount = pStubMsg->ActualCount;
594 pStubMsg->Offset = 0;
595 WriteConformance(pStubMsg);
596 WriteVariance(pStubMsg);
598 size = safe_multiply(esize, pStubMsg->ActualCount);
599 memcpy(pStubMsg->Buffer, pszMessage, size); /* the string itself */
600 pStubMsg->Buffer += size;
602 STD_OVERFLOW_CHECK(pStubMsg);
604 /* success */
605 return NULL; /* is this always right? */
608 /***********************************************************************
609 * NdrConformantStringBufferSize [RPCRT4.@]
611 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
612 unsigned char* pMemory, PFORMAT_STRING pFormat)
614 ULONG esize;
616 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
618 SizeConformance(pStubMsg);
619 SizeVariance(pStubMsg);
621 if (*pFormat == RPC_FC_C_CSTRING) {
622 TRACE("string=%s\n", debugstr_a((char*)pMemory));
623 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
624 esize = 1;
626 else if (*pFormat == RPC_FC_C_WSTRING) {
627 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
628 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
629 esize = 2;
631 else {
632 ERR("Unhandled string type: %#x\n", *pFormat);
633 /* FIXME: raise an exception */
634 return;
637 if (pFormat[1] == RPC_FC_STRING_SIZED)
638 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
639 else
640 pStubMsg->MaxCount = pStubMsg->ActualCount;
642 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
645 /************************************************************************
646 * NdrConformantStringMemorySize [RPCRT4.@]
648 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
649 PFORMAT_STRING pFormat )
651 ULONG rslt = 0;
653 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
655 assert(pStubMsg && pFormat);
657 if (*pFormat == RPC_FC_C_CSTRING) {
658 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
660 else if (*pFormat == RPC_FC_C_WSTRING) {
661 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
663 else {
664 ERR("Unhandled string type: %#x\n", *pFormat);
665 /* FIXME: raise an exception */
668 if (pFormat[1] != RPC_FC_PAD) {
669 FIXME("sized string format=%d\n", pFormat[1]);
672 TRACE(" --> %u\n", rslt);
673 return rslt;
676 /************************************************************************
677 * NdrConformantStringUnmarshall [RPCRT4.@]
679 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
680 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
682 ULONG bufsize, memsize, esize, i;
684 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
685 pStubMsg, *ppMemory, pFormat, fMustAlloc);
687 assert(pFormat && ppMemory && pStubMsg);
689 ReadConformance(pStubMsg, NULL);
690 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
692 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
693 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
694 else {
695 ERR("Unhandled string type: %#x\n", *pFormat);
696 /* FIXME: raise an exception */
697 esize = 0;
700 memsize = safe_multiply(esize, pStubMsg->MaxCount);
701 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
703 /* strings must always have null terminating bytes */
704 if (bufsize < esize)
706 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
707 RpcRaiseException(RPC_S_INVALID_BOUND);
708 return NULL;
710 for (i = bufsize - esize; i < bufsize; i++)
711 if (pStubMsg->Buffer[i] != 0)
713 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
714 i, pStubMsg->Buffer[i]);
715 RpcRaiseException(RPC_S_INVALID_BOUND);
716 return NULL;
719 if (fMustAlloc || !*ppMemory)
720 *ppMemory = NdrAllocate(pStubMsg, memsize);
722 memcpy(*ppMemory, pStubMsg->Buffer, bufsize);
724 pStubMsg->Buffer += bufsize;
726 if (*pFormat == RPC_FC_C_CSTRING) {
727 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
729 else if (*pFormat == RPC_FC_C_WSTRING) {
730 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
733 return NULL; /* FIXME: is this always right? */
736 /***********************************************************************
737 * NdrNonConformantStringMarshall [RPCRT4.@]
739 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
740 unsigned char *pMemory,
741 PFORMAT_STRING pFormat)
743 FIXME("stub\n");
744 return NULL;
747 /***********************************************************************
748 * NdrNonConformantStringUnmarshall [RPCRT4.@]
750 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
751 unsigned char **ppMemory,
752 PFORMAT_STRING pFormat,
753 unsigned char fMustAlloc)
755 FIXME("stub\n");
756 return NULL;
759 /***********************************************************************
760 * NdrNonConformantStringBufferSize [RPCRT4.@]
762 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
763 unsigned char *pMemory,
764 PFORMAT_STRING pFormat)
766 FIXME("stub\n");
769 /***********************************************************************
770 * NdrNonConformantStringMemorySize [RPCRT4.@]
772 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
773 PFORMAT_STRING pFormat)
775 FIXME("stub\n");
776 return 0;
779 static inline void dump_pointer_attr(unsigned char attr)
781 if (attr & RPC_FC_P_ALLOCALLNODES)
782 TRACE(" RPC_FC_P_ALLOCALLNODES");
783 if (attr & RPC_FC_P_DONTFREE)
784 TRACE(" RPC_FC_P_DONTFREE");
785 if (attr & RPC_FC_P_ONSTACK)
786 TRACE(" RPC_FC_P_ONSTACK");
787 if (attr & RPC_FC_P_SIMPLEPOINTER)
788 TRACE(" RPC_FC_P_SIMPLEPOINTER");
789 if (attr & RPC_FC_P_DEREF)
790 TRACE(" RPC_FC_P_DEREF");
791 TRACE("\n");
794 /***********************************************************************
795 * PointerMarshall [internal]
797 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
798 unsigned char *Buffer,
799 unsigned char *Pointer,
800 PFORMAT_STRING pFormat)
802 unsigned type = pFormat[0], attr = pFormat[1];
803 PFORMAT_STRING desc;
804 NDR_MARSHALL m;
805 ULONG pointer_id;
806 int pointer_needs_marshaling;
808 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
809 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
810 pFormat += 2;
811 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
812 else desc = pFormat + *(const SHORT*)pFormat;
814 switch (type) {
815 case RPC_FC_RP: /* ref pointer (always non-null) */
816 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
817 if (!Pointer)
818 RpcRaiseException(RPC_X_NULL_REF_POINTER);
819 #endif
820 pointer_needs_marshaling = 1;
821 break;
822 case RPC_FC_UP: /* unique pointer */
823 case RPC_FC_OP: /* object pointer - same as unique here */
824 if (Pointer)
825 pointer_needs_marshaling = 1;
826 else
827 pointer_needs_marshaling = 0;
828 pointer_id = (ULONG)Pointer;
829 TRACE("writing 0x%08x to buffer\n", pointer_id);
830 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
831 break;
832 case RPC_FC_FP:
833 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
834 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
835 TRACE("writing 0x%08x to buffer\n", pointer_id);
836 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
837 break;
838 default:
839 FIXME("unhandled ptr type=%02x\n", type);
840 RpcRaiseException(RPC_X_BAD_STUB_DATA);
841 return;
844 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
846 if (pointer_needs_marshaling) {
847 if (attr & RPC_FC_P_DEREF) {
848 Pointer = *(unsigned char**)Pointer;
849 TRACE("deref => %p\n", Pointer);
851 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
852 if (m) m(pStubMsg, Pointer, desc);
853 else FIXME("no marshaller for data type=%02x\n", *desc);
856 STD_OVERFLOW_CHECK(pStubMsg);
859 /***********************************************************************
860 * PointerUnmarshall [internal]
862 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
863 unsigned char *Buffer,
864 unsigned char **pPointer,
865 PFORMAT_STRING pFormat,
866 unsigned char fMustAlloc)
868 unsigned type = pFormat[0], attr = pFormat[1];
869 PFORMAT_STRING desc;
870 NDR_UNMARSHALL m;
871 DWORD pointer_id = 0;
872 int pointer_needs_unmarshaling;
874 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
875 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
876 pFormat += 2;
877 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
878 else desc = pFormat + *(const SHORT*)pFormat;
880 switch (type) {
881 case RPC_FC_RP: /* ref pointer (always non-null) */
882 pointer_needs_unmarshaling = 1;
883 break;
884 case RPC_FC_UP: /* unique pointer */
885 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
886 TRACE("pointer_id is 0x%08x\n", pointer_id);
887 if (pointer_id)
888 pointer_needs_unmarshaling = 1;
889 else {
890 *pPointer = NULL;
891 pointer_needs_unmarshaling = 0;
893 break;
894 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
895 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
896 TRACE("pointer_id is 0x%08x\n", pointer_id);
897 if (!fMustAlloc && *pPointer)
899 FIXME("free object pointer %p\n", *pPointer);
900 *pPointer = NULL;
902 if (pointer_id)
903 pointer_needs_unmarshaling = 1;
904 else
905 pointer_needs_unmarshaling = 0;
906 break;
907 case RPC_FC_FP:
908 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
909 TRACE("pointer_id is 0x%08x\n", pointer_id);
910 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
911 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
912 break;
913 default:
914 FIXME("unhandled ptr type=%02x\n", type);
915 RpcRaiseException(RPC_X_BAD_STUB_DATA);
916 return;
919 if (pointer_needs_unmarshaling) {
920 if (attr & RPC_FC_P_DEREF) {
921 if (!*pPointer || fMustAlloc)
922 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
923 pPointer = *(unsigned char***)pPointer;
924 TRACE("deref => %p\n", pPointer);
926 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
927 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
928 else FIXME("no unmarshaller for data type=%02x\n", *desc);
930 if (type == RPC_FC_FP)
931 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
932 *pPointer);
935 TRACE("pointer=%p\n", *pPointer);
938 /***********************************************************************
939 * PointerBufferSize [internal]
941 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
942 unsigned char *Pointer,
943 PFORMAT_STRING pFormat)
945 unsigned type = pFormat[0], attr = pFormat[1];
946 PFORMAT_STRING desc;
947 NDR_BUFFERSIZE m;
948 int pointer_needs_sizing;
949 ULONG pointer_id;
951 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
952 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
953 pFormat += 2;
954 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
955 else desc = pFormat + *(const SHORT*)pFormat;
957 switch (type) {
958 case RPC_FC_RP: /* ref pointer (always non-null) */
959 break;
960 case RPC_FC_OP:
961 case RPC_FC_UP:
962 /* NULL pointer has no further representation */
963 if (!Pointer)
964 return;
965 break;
966 case RPC_FC_FP:
967 pointer_needs_sizing = !NdrFullPointerQueryPointer(
968 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
969 if (!pointer_needs_sizing)
970 return;
971 break;
972 default:
973 FIXME("unhandled ptr type=%02x\n", type);
974 RpcRaiseException(RPC_X_BAD_STUB_DATA);
975 return;
978 if (attr & RPC_FC_P_DEREF) {
979 Pointer = *(unsigned char**)Pointer;
980 TRACE("deref => %p\n", Pointer);
983 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
984 if (m) m(pStubMsg, Pointer, desc);
985 else FIXME("no buffersizer for data type=%02x\n", *desc);
988 /***********************************************************************
989 * PointerMemorySize [internal]
991 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
992 unsigned char *Buffer,
993 PFORMAT_STRING pFormat)
995 unsigned type = pFormat[0], attr = pFormat[1];
996 PFORMAT_STRING desc;
997 NDR_MEMORYSIZE m;
999 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
1000 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1001 pFormat += 2;
1002 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1003 else desc = pFormat + *(const SHORT*)pFormat;
1005 switch (type) {
1006 case RPC_FC_RP: /* ref pointer (always non-null) */
1007 break;
1008 default:
1009 FIXME("unhandled ptr type=%02x\n", type);
1010 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1013 if (attr & RPC_FC_P_DEREF) {
1014 TRACE("deref\n");
1017 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1018 if (m) m(pStubMsg, desc);
1019 else FIXME("no memorysizer for data type=%02x\n", *desc);
1021 return 0;
1024 /***********************************************************************
1025 * PointerFree [internal]
1027 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1028 unsigned char *Pointer,
1029 PFORMAT_STRING pFormat)
1031 unsigned type = pFormat[0], attr = pFormat[1];
1032 PFORMAT_STRING desc;
1033 NDR_FREE m;
1035 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1036 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1037 if (attr & RPC_FC_P_DONTFREE) return;
1038 pFormat += 2;
1039 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1040 else desc = pFormat + *(const SHORT*)pFormat;
1042 if (!Pointer) return;
1044 if (type == RPC_FC_FP) {
1045 int pointer_needs_freeing = NdrFullPointerFree(
1046 pStubMsg->FullPtrXlatTables, Pointer);
1047 if (!pointer_needs_freeing)
1048 return;
1051 if (attr & RPC_FC_P_DEREF) {
1052 Pointer = *(unsigned char**)Pointer;
1053 TRACE("deref => %p\n", Pointer);
1056 m = NdrFreer[*desc & NDR_TABLE_MASK];
1057 if (m) m(pStubMsg, Pointer, desc);
1059 /* hmm... is this sensible?
1060 * perhaps we should check if the memory comes from NdrAllocate,
1061 * and deallocate only if so - checking if the pointer is between
1062 * BufferStart and BufferEnd is probably no good since the buffer
1063 * may be reallocated when the server wants to marshal the reply */
1064 switch (*desc) {
1065 case RPC_FC_BOGUS_STRUCT:
1066 case RPC_FC_BOGUS_ARRAY:
1067 case RPC_FC_USER_MARSHAL:
1068 case RPC_FC_CARRAY:
1069 case RPC_FC_CVARRAY:
1070 break;
1071 default:
1072 FIXME("unhandled data type=%02x\n", *desc);
1073 break;
1074 case RPC_FC_C_CSTRING:
1075 case RPC_FC_C_WSTRING:
1076 if (pStubMsg->ReuseBuffer) goto notfree;
1077 break;
1078 case RPC_FC_IP:
1079 goto notfree;
1082 if (attr & RPC_FC_P_ONSTACK) {
1083 TRACE("not freeing stack ptr %p\n", Pointer);
1084 return;
1086 TRACE("freeing %p\n", Pointer);
1087 NdrFree(pStubMsg, Pointer);
1088 return;
1089 notfree:
1090 TRACE("not freeing %p\n", Pointer);
1093 /***********************************************************************
1094 * EmbeddedPointerMarshall
1096 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1097 unsigned char *pMemory,
1098 PFORMAT_STRING pFormat)
1100 unsigned char *Mark = pStubMsg->BufferMark;
1101 unsigned long Offset = pStubMsg->Offset;
1102 unsigned ofs, rep, count, stride, xofs;
1103 unsigned i;
1105 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1107 if (*pFormat != RPC_FC_PP) return NULL;
1108 pFormat += 2;
1110 while (pFormat[0] != RPC_FC_END) {
1111 switch (pFormat[0]) {
1112 default:
1113 FIXME("unknown repeat type %d\n", pFormat[0]);
1114 case RPC_FC_NO_REPEAT:
1115 rep = 1;
1116 stride = 0;
1117 ofs = 0;
1118 count = 1;
1119 xofs = 0;
1120 pFormat += 2;
1121 break;
1122 case RPC_FC_FIXED_REPEAT:
1123 rep = *(const WORD*)&pFormat[2];
1124 stride = *(const WORD*)&pFormat[4];
1125 ofs = *(const WORD*)&pFormat[6];
1126 count = *(const WORD*)&pFormat[8];
1127 xofs = 0;
1128 pFormat += 10;
1129 break;
1130 case RPC_FC_VARIABLE_REPEAT:
1131 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1132 stride = *(const WORD*)&pFormat[2];
1133 ofs = *(const WORD*)&pFormat[4];
1134 count = *(const WORD*)&pFormat[6];
1135 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1136 pFormat += 8;
1137 break;
1139 for (i = 0; i < rep; i++) {
1140 PFORMAT_STRING info = pFormat;
1141 unsigned char *membase = pMemory + (i * stride);
1142 unsigned char *bufbase = Mark + (i * stride);
1143 unsigned u;
1144 /* ofs doesn't seem to matter in this context */
1145 for (u=0; u<count; u++,info+=8) {
1146 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1147 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1148 unsigned char *saved_memory = pStubMsg->Memory;
1150 pStubMsg->Memory = pMemory;
1151 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1152 pStubMsg->Memory = saved_memory;
1155 pFormat += 8 * count;
1158 STD_OVERFLOW_CHECK(pStubMsg);
1160 return NULL;
1163 /***********************************************************************
1164 * EmbeddedPointerUnmarshall
1166 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1167 unsigned char **ppMemory,
1168 PFORMAT_STRING pFormat,
1169 unsigned char fMustAlloc)
1171 unsigned char *Mark = pStubMsg->BufferMark;
1172 unsigned long Offset = pStubMsg->Offset;
1173 unsigned ofs, rep, count, stride, xofs;
1174 unsigned i;
1176 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1178 if (*pFormat != RPC_FC_PP) return NULL;
1179 pFormat += 2;
1181 while (pFormat[0] != RPC_FC_END) {
1182 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1183 switch (pFormat[0]) {
1184 default:
1185 FIXME("unknown repeat type %d\n", pFormat[0]);
1186 case RPC_FC_NO_REPEAT:
1187 rep = 1;
1188 stride = 0;
1189 ofs = 0;
1190 count = 1;
1191 xofs = 0;
1192 pFormat += 2;
1193 break;
1194 case RPC_FC_FIXED_REPEAT:
1195 rep = *(const WORD*)&pFormat[2];
1196 stride = *(const WORD*)&pFormat[4];
1197 ofs = *(const WORD*)&pFormat[6];
1198 count = *(const WORD*)&pFormat[8];
1199 xofs = 0;
1200 pFormat += 10;
1201 break;
1202 case RPC_FC_VARIABLE_REPEAT:
1203 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1204 stride = *(const WORD*)&pFormat[2];
1205 ofs = *(const WORD*)&pFormat[4];
1206 count = *(const WORD*)&pFormat[6];
1207 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1208 pFormat += 8;
1209 break;
1211 /* ofs doesn't seem to matter in this context */
1212 for (i = 0; i < rep; i++) {
1213 PFORMAT_STRING info = pFormat;
1214 unsigned char *membase = *ppMemory + (i * stride);
1215 unsigned char *bufbase = Mark + (i * stride);
1216 unsigned u;
1217 for (u=0; u<count; u++,info+=8) {
1218 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1219 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1220 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1223 pFormat += 8 * count;
1226 return NULL;
1229 /***********************************************************************
1230 * EmbeddedPointerBufferSize
1232 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1233 unsigned char *pMemory,
1234 PFORMAT_STRING pFormat)
1236 unsigned long Offset = pStubMsg->Offset;
1237 unsigned ofs, rep, count, stride, xofs;
1238 unsigned i;
1240 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1242 if (pStubMsg->IgnoreEmbeddedPointers) return;
1244 if (*pFormat != RPC_FC_PP) return;
1245 pFormat += 2;
1247 while (pFormat[0] != RPC_FC_END) {
1248 switch (pFormat[0]) {
1249 default:
1250 FIXME("unknown repeat type %d\n", pFormat[0]);
1251 case RPC_FC_NO_REPEAT:
1252 rep = 1;
1253 stride = 0;
1254 ofs = 0;
1255 count = 1;
1256 xofs = 0;
1257 pFormat += 2;
1258 break;
1259 case RPC_FC_FIXED_REPEAT:
1260 rep = *(const WORD*)&pFormat[2];
1261 stride = *(const WORD*)&pFormat[4];
1262 ofs = *(const WORD*)&pFormat[6];
1263 count = *(const WORD*)&pFormat[8];
1264 xofs = 0;
1265 pFormat += 10;
1266 break;
1267 case RPC_FC_VARIABLE_REPEAT:
1268 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1269 stride = *(const WORD*)&pFormat[2];
1270 ofs = *(const WORD*)&pFormat[4];
1271 count = *(const WORD*)&pFormat[6];
1272 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1273 pFormat += 8;
1274 break;
1276 /* ofs doesn't seem to matter in this context */
1277 for (i = 0; i < rep; i++) {
1278 PFORMAT_STRING info = pFormat;
1279 unsigned char *membase = pMemory + (i * stride);
1280 unsigned u;
1281 for (u=0; u<count; u++,info+=8) {
1282 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1283 unsigned char *saved_memory = pStubMsg->Memory;
1285 pStubMsg->Memory = pMemory;
1286 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1287 pStubMsg->Memory = saved_memory;
1290 pFormat += 8 * count;
1294 /***********************************************************************
1295 * EmbeddedPointerMemorySize [internal]
1297 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1298 PFORMAT_STRING pFormat)
1300 unsigned long Offset = pStubMsg->Offset;
1301 unsigned char *Mark = pStubMsg->BufferMark;
1302 unsigned ofs, rep, count, stride, xofs;
1303 unsigned i;
1305 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1307 if (*pFormat != RPC_FC_PP) return 0;
1308 pFormat += 2;
1310 while (pFormat[0] != RPC_FC_END) {
1311 switch (pFormat[0]) {
1312 default:
1313 FIXME("unknown repeat type %d\n", pFormat[0]);
1314 case RPC_FC_NO_REPEAT:
1315 rep = 1;
1316 stride = 0;
1317 ofs = 0;
1318 count = 1;
1319 xofs = 0;
1320 pFormat += 2;
1321 break;
1322 case RPC_FC_FIXED_REPEAT:
1323 rep = *(const WORD*)&pFormat[2];
1324 stride = *(const WORD*)&pFormat[4];
1325 ofs = *(const WORD*)&pFormat[6];
1326 count = *(const WORD*)&pFormat[8];
1327 xofs = 0;
1328 pFormat += 10;
1329 break;
1330 case RPC_FC_VARIABLE_REPEAT:
1331 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1332 stride = *(const WORD*)&pFormat[2];
1333 ofs = *(const WORD*)&pFormat[4];
1334 count = *(const WORD*)&pFormat[6];
1335 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1336 pFormat += 8;
1337 break;
1339 /* ofs doesn't seem to matter in this context */
1340 for (i = 0; i < rep; i++) {
1341 PFORMAT_STRING info = pFormat;
1342 unsigned char *bufbase = Mark + (i * stride);
1343 unsigned u;
1344 for (u=0; u<count; u++,info+=8) {
1345 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1346 PointerMemorySize(pStubMsg, bufptr, info+4);
1349 pFormat += 8 * count;
1352 return 0;
1355 /***********************************************************************
1356 * EmbeddedPointerFree [internal]
1358 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1359 unsigned char *pMemory,
1360 PFORMAT_STRING pFormat)
1362 unsigned long Offset = pStubMsg->Offset;
1363 unsigned ofs, rep, count, stride, xofs;
1364 unsigned i;
1366 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1367 if (*pFormat != RPC_FC_PP) return;
1368 pFormat += 2;
1370 while (pFormat[0] != RPC_FC_END) {
1371 switch (pFormat[0]) {
1372 default:
1373 FIXME("unknown repeat type %d\n", pFormat[0]);
1374 case RPC_FC_NO_REPEAT:
1375 rep = 1;
1376 stride = 0;
1377 ofs = 0;
1378 count = 1;
1379 xofs = 0;
1380 pFormat += 2;
1381 break;
1382 case RPC_FC_FIXED_REPEAT:
1383 rep = *(const WORD*)&pFormat[2];
1384 stride = *(const WORD*)&pFormat[4];
1385 ofs = *(const WORD*)&pFormat[6];
1386 count = *(const WORD*)&pFormat[8];
1387 xofs = 0;
1388 pFormat += 10;
1389 break;
1390 case RPC_FC_VARIABLE_REPEAT:
1391 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1392 stride = *(const WORD*)&pFormat[2];
1393 ofs = *(const WORD*)&pFormat[4];
1394 count = *(const WORD*)&pFormat[6];
1395 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1396 pFormat += 8;
1397 break;
1399 /* ofs doesn't seem to matter in this context */
1400 for (i = 0; i < rep; i++) {
1401 PFORMAT_STRING info = pFormat;
1402 unsigned char *membase = pMemory + (i * stride);
1403 unsigned u;
1404 for (u=0; u<count; u++,info+=8) {
1405 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1406 unsigned char *saved_memory = pStubMsg->Memory;
1408 pStubMsg->Memory = pMemory;
1409 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1410 pStubMsg->Memory = saved_memory;
1413 pFormat += 8 * count;
1417 /***********************************************************************
1418 * NdrPointerMarshall [RPCRT4.@]
1420 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1421 unsigned char *pMemory,
1422 PFORMAT_STRING pFormat)
1424 unsigned char *Buffer;
1426 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1428 /* incremement the buffer here instead of in PointerMarshall,
1429 * as that is used by embedded pointers which already handle the incrementing
1430 * the buffer, and shouldn't write any additional pointer data to the wire */
1431 if (*pFormat != RPC_FC_RP)
1433 ALIGN_POINTER(pStubMsg->Buffer, 4);
1434 Buffer = pStubMsg->Buffer;
1435 pStubMsg->Buffer += 4;
1437 else
1438 Buffer = pStubMsg->Buffer;
1440 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1442 STD_OVERFLOW_CHECK(pStubMsg);
1444 return NULL;
1447 /***********************************************************************
1448 * NdrPointerUnmarshall [RPCRT4.@]
1450 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1451 unsigned char **ppMemory,
1452 PFORMAT_STRING pFormat,
1453 unsigned char fMustAlloc)
1455 unsigned char *Buffer;
1457 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1459 /* incremement the buffer here instead of in PointerUnmarshall,
1460 * as that is used by embedded pointers which already handle the incrementing
1461 * the buffer, and shouldn't read any additional pointer data from the
1462 * buffer */
1463 if (*pFormat != RPC_FC_RP)
1465 ALIGN_POINTER(pStubMsg->Buffer, 4);
1466 Buffer = pStubMsg->Buffer;
1467 pStubMsg->Buffer += 4;
1469 else
1470 Buffer = pStubMsg->Buffer;
1472 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1474 return NULL;
1477 /***********************************************************************
1478 * NdrPointerBufferSize [RPCRT4.@]
1480 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1481 unsigned char *pMemory,
1482 PFORMAT_STRING pFormat)
1484 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1486 /* incremement the buffer length here instead of in PointerBufferSize,
1487 * as that is used by embedded pointers which already handle the buffer
1488 * length, and shouldn't write anything more to the wire */
1489 if (*pFormat != RPC_FC_RP)
1491 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1492 pStubMsg->BufferLength += 4;
1495 PointerBufferSize(pStubMsg, pMemory, pFormat);
1498 /***********************************************************************
1499 * NdrPointerMemorySize [RPCRT4.@]
1501 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1502 PFORMAT_STRING pFormat)
1504 /* unsigned size = *(LPWORD)(pFormat+2); */
1505 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1506 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1507 return 0;
1510 /***********************************************************************
1511 * NdrPointerFree [RPCRT4.@]
1513 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1514 unsigned char *pMemory,
1515 PFORMAT_STRING pFormat)
1517 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1518 PointerFree(pStubMsg, pMemory, pFormat);
1521 /***********************************************************************
1522 * NdrSimpleTypeMarshall [RPCRT4.@]
1524 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1525 unsigned char FormatChar )
1527 FIXME("stub\n");
1530 /***********************************************************************
1531 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1533 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1534 unsigned char FormatChar )
1536 FIXME("stub\n");
1539 /***********************************************************************
1540 * NdrSimpleStructMarshall [RPCRT4.@]
1542 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1543 unsigned char *pMemory,
1544 PFORMAT_STRING pFormat)
1546 unsigned size = *(const WORD*)(pFormat+2);
1547 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1549 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1551 memcpy(pStubMsg->Buffer, pMemory, size);
1552 pStubMsg->BufferMark = pStubMsg->Buffer;
1553 pStubMsg->Buffer += size;
1555 if (pFormat[0] != RPC_FC_STRUCT)
1556 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1558 STD_OVERFLOW_CHECK(pStubMsg);
1560 return NULL;
1563 /***********************************************************************
1564 * NdrSimpleStructUnmarshall [RPCRT4.@]
1566 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1567 unsigned char **ppMemory,
1568 PFORMAT_STRING pFormat,
1569 unsigned char fMustAlloc)
1571 unsigned size = *(const WORD*)(pFormat+2);
1572 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1574 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1576 if (fMustAlloc) {
1577 *ppMemory = NdrAllocate(pStubMsg, size);
1578 memcpy(*ppMemory, pStubMsg->Buffer, size);
1579 } else {
1580 if (!pStubMsg->IsClient && !*ppMemory)
1581 /* for servers, we just point straight into the RPC buffer */
1582 *ppMemory = pStubMsg->Buffer;
1583 else
1584 /* for clients, memory should be provided by caller */
1585 memcpy(*ppMemory, pStubMsg->Buffer, size);
1588 pStubMsg->BufferMark = pStubMsg->Buffer;
1589 pStubMsg->Buffer += size;
1591 if (pFormat[0] != RPC_FC_STRUCT)
1592 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1594 return NULL;
1597 /***********************************************************************
1598 * NdrSimpleStructBufferSize [RPCRT4.@]
1600 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1601 unsigned char *pMemory,
1602 PFORMAT_STRING pFormat)
1604 unsigned size = *(const WORD*)(pFormat+2);
1605 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1607 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1609 pStubMsg->BufferLength += size;
1610 if (pFormat[0] != RPC_FC_STRUCT)
1611 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1614 /***********************************************************************
1615 * NdrSimpleStructMemorySize [RPCRT4.@]
1617 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1618 PFORMAT_STRING pFormat)
1620 unsigned short size = *(const WORD *)(pFormat+2);
1622 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1624 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1625 pStubMsg->MemorySize += size;
1626 pStubMsg->Buffer += size;
1628 if (pFormat[0] != RPC_FC_STRUCT)
1629 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1630 return size;
1633 /***********************************************************************
1634 * NdrSimpleStructFree [RPCRT4.@]
1636 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1637 unsigned char *pMemory,
1638 PFORMAT_STRING pFormat)
1640 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1641 if (pFormat[0] != RPC_FC_STRUCT)
1642 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1646 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1647 PFORMAT_STRING pFormat)
1649 switch (*pFormat) {
1650 case RPC_FC_STRUCT:
1651 case RPC_FC_PSTRUCT:
1652 case RPC_FC_CSTRUCT:
1653 case RPC_FC_BOGUS_STRUCT:
1654 case RPC_FC_SMFARRAY:
1655 case RPC_FC_SMVARRAY:
1656 return *(const WORD*)&pFormat[2];
1657 case RPC_FC_USER_MARSHAL:
1658 return *(const WORD*)&pFormat[4];
1659 case RPC_FC_NON_ENCAPSULATED_UNION:
1660 pFormat += 2;
1661 if (pStubMsg->fHasNewCorrDesc)
1662 pFormat += 6;
1663 else
1664 pFormat += 4;
1666 pFormat += *(const SHORT*)pFormat;
1667 return *(const SHORT*)pFormat;
1668 case RPC_FC_IP:
1669 return sizeof(void *);
1670 default:
1671 FIXME("unhandled embedded type %02x\n", *pFormat);
1673 return 0;
1677 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1678 PFORMAT_STRING pFormat)
1680 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1682 if (!m)
1684 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1685 return 0;
1688 return m(pStubMsg, pFormat);
1692 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1693 unsigned char *pMemory,
1694 PFORMAT_STRING pFormat,
1695 PFORMAT_STRING pPointer)
1697 PFORMAT_STRING desc;
1698 NDR_MARSHALL m;
1699 unsigned long size;
1701 while (*pFormat != RPC_FC_END) {
1702 switch (*pFormat) {
1703 case RPC_FC_BYTE:
1704 case RPC_FC_CHAR:
1705 case RPC_FC_SMALL:
1706 case RPC_FC_USMALL:
1707 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1708 memcpy(pStubMsg->Buffer, pMemory, 1);
1709 pStubMsg->Buffer += 1;
1710 pMemory += 1;
1711 break;
1712 case RPC_FC_WCHAR:
1713 case RPC_FC_SHORT:
1714 case RPC_FC_USHORT:
1715 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1716 memcpy(pStubMsg->Buffer, pMemory, 2);
1717 pStubMsg->Buffer += 2;
1718 pMemory += 2;
1719 break;
1720 case RPC_FC_LONG:
1721 case RPC_FC_ULONG:
1722 case RPC_FC_ENUM32:
1723 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
1724 memcpy(pStubMsg->Buffer, pMemory, 4);
1725 pStubMsg->Buffer += 4;
1726 pMemory += 4;
1727 break;
1728 case RPC_FC_HYPER:
1729 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1730 memcpy(pStubMsg->Buffer, pMemory, 8);
1731 pStubMsg->Buffer += 8;
1732 pMemory += 8;
1733 break;
1734 case RPC_FC_POINTER:
1735 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1736 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1737 pPointer += 4;
1738 pMemory += 4;
1739 break;
1740 case RPC_FC_ALIGNM4:
1741 ALIGN_POINTER(pMemory, 4);
1742 break;
1743 case RPC_FC_ALIGNM8:
1744 ALIGN_POINTER(pMemory, 8);
1745 break;
1746 case RPC_FC_STRUCTPAD1:
1747 case RPC_FC_STRUCTPAD2:
1748 case RPC_FC_STRUCTPAD3:
1749 case RPC_FC_STRUCTPAD4:
1750 case RPC_FC_STRUCTPAD5:
1751 case RPC_FC_STRUCTPAD6:
1752 case RPC_FC_STRUCTPAD7:
1753 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1754 break;
1755 case RPC_FC_EMBEDDED_COMPLEX:
1756 pMemory += pFormat[1];
1757 pFormat += 2;
1758 desc = pFormat + *(const SHORT*)pFormat;
1759 size = EmbeddedComplexSize(pStubMsg, desc);
1760 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1761 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1762 if (m) m(pStubMsg, pMemory, desc);
1763 else FIXME("no marshaller for embedded type %02x\n", *desc);
1764 pMemory += size;
1765 pFormat += 2;
1766 continue;
1767 case RPC_FC_PAD:
1768 break;
1769 default:
1770 FIXME("unhandled format 0x%02x\n", *pFormat);
1772 pFormat++;
1775 return pMemory;
1778 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1779 unsigned char *pMemory,
1780 PFORMAT_STRING pFormat,
1781 PFORMAT_STRING pPointer)
1783 PFORMAT_STRING desc;
1784 NDR_UNMARSHALL m;
1785 unsigned long size;
1787 while (*pFormat != RPC_FC_END) {
1788 switch (*pFormat) {
1789 case RPC_FC_BYTE:
1790 case RPC_FC_CHAR:
1791 case RPC_FC_SMALL:
1792 case RPC_FC_USMALL:
1793 memcpy(pMemory, pStubMsg->Buffer, 1);
1794 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1795 pStubMsg->Buffer += 1;
1796 pMemory += 1;
1797 break;
1798 case RPC_FC_WCHAR:
1799 case RPC_FC_SHORT:
1800 case RPC_FC_USHORT:
1801 memcpy(pMemory, pStubMsg->Buffer, 2);
1802 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1803 pStubMsg->Buffer += 2;
1804 pMemory += 2;
1805 break;
1806 case RPC_FC_LONG:
1807 case RPC_FC_ULONG:
1808 case RPC_FC_ENUM32:
1809 memcpy(pMemory, pStubMsg->Buffer, 4);
1810 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
1811 pStubMsg->Buffer += 4;
1812 pMemory += 4;
1813 break;
1814 case RPC_FC_HYPER:
1815 memcpy(pMemory, pStubMsg->Buffer, 8);
1816 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1817 pStubMsg->Buffer += 8;
1818 pMemory += 8;
1819 break;
1820 case RPC_FC_POINTER:
1821 TRACE("pointer => %p\n", pMemory);
1822 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1823 pPointer += 4;
1824 pMemory += 4;
1825 break;
1826 case RPC_FC_ALIGNM4:
1827 ALIGN_POINTER(pMemory, 4);
1828 break;
1829 case RPC_FC_ALIGNM8:
1830 ALIGN_POINTER(pMemory, 8);
1831 break;
1832 case RPC_FC_STRUCTPAD1:
1833 case RPC_FC_STRUCTPAD2:
1834 case RPC_FC_STRUCTPAD3:
1835 case RPC_FC_STRUCTPAD4:
1836 case RPC_FC_STRUCTPAD5:
1837 case RPC_FC_STRUCTPAD6:
1838 case RPC_FC_STRUCTPAD7:
1839 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1840 break;
1841 case RPC_FC_EMBEDDED_COMPLEX:
1842 pMemory += pFormat[1];
1843 pFormat += 2;
1844 desc = pFormat + *(const SHORT*)pFormat;
1845 size = EmbeddedComplexSize(pStubMsg, desc);
1846 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1847 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1848 memset(pMemory, 0, size); /* just in case */
1849 if (m) m(pStubMsg, &pMemory, desc, FALSE);
1850 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1851 pMemory += size;
1852 pFormat += 2;
1853 continue;
1854 case RPC_FC_PAD:
1855 break;
1856 default:
1857 FIXME("unhandled format %d\n", *pFormat);
1859 pFormat++;
1862 return pMemory;
1865 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1866 unsigned char *pMemory,
1867 PFORMAT_STRING pFormat,
1868 PFORMAT_STRING pPointer)
1870 PFORMAT_STRING desc;
1871 NDR_BUFFERSIZE m;
1872 unsigned long size;
1874 while (*pFormat != RPC_FC_END) {
1875 switch (*pFormat) {
1876 case RPC_FC_BYTE:
1877 case RPC_FC_CHAR:
1878 case RPC_FC_SMALL:
1879 case RPC_FC_USMALL:
1880 pStubMsg->BufferLength += 1;
1881 pMemory += 1;
1882 break;
1883 case RPC_FC_WCHAR:
1884 case RPC_FC_SHORT:
1885 case RPC_FC_USHORT:
1886 pStubMsg->BufferLength += 2;
1887 pMemory += 2;
1888 break;
1889 case RPC_FC_LONG:
1890 case RPC_FC_ULONG:
1891 case RPC_FC_ENUM32:
1892 pStubMsg->BufferLength += 4;
1893 pMemory += 4;
1894 break;
1895 case RPC_FC_HYPER:
1896 pStubMsg->BufferLength += 8;
1897 pMemory += 8;
1898 break;
1899 case RPC_FC_POINTER:
1900 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1901 pPointer += 4;
1902 pMemory += 4;
1903 break;
1904 case RPC_FC_ALIGNM4:
1905 ALIGN_POINTER(pMemory, 4);
1906 break;
1907 case RPC_FC_ALIGNM8:
1908 ALIGN_POINTER(pMemory, 8);
1909 break;
1910 case RPC_FC_STRUCTPAD1:
1911 case RPC_FC_STRUCTPAD2:
1912 case RPC_FC_STRUCTPAD3:
1913 case RPC_FC_STRUCTPAD4:
1914 case RPC_FC_STRUCTPAD5:
1915 case RPC_FC_STRUCTPAD6:
1916 case RPC_FC_STRUCTPAD7:
1917 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1918 break;
1919 case RPC_FC_EMBEDDED_COMPLEX:
1920 pMemory += pFormat[1];
1921 pFormat += 2;
1922 desc = pFormat + *(const SHORT*)pFormat;
1923 size = EmbeddedComplexSize(pStubMsg, desc);
1924 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1925 if (m) m(pStubMsg, pMemory, desc);
1926 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1927 pMemory += size;
1928 pFormat += 2;
1929 continue;
1930 case RPC_FC_PAD:
1931 break;
1932 default:
1933 FIXME("unhandled format 0x%02x\n", *pFormat);
1935 pFormat++;
1938 return pMemory;
1941 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1942 unsigned char *pMemory,
1943 PFORMAT_STRING pFormat,
1944 PFORMAT_STRING pPointer)
1946 PFORMAT_STRING desc;
1947 NDR_FREE m;
1948 unsigned long size;
1950 while (*pFormat != RPC_FC_END) {
1951 switch (*pFormat) {
1952 case RPC_FC_BYTE:
1953 case RPC_FC_CHAR:
1954 case RPC_FC_SMALL:
1955 case RPC_FC_USMALL:
1956 pMemory += 1;
1957 break;
1958 case RPC_FC_WCHAR:
1959 case RPC_FC_SHORT:
1960 case RPC_FC_USHORT:
1961 pMemory += 2;
1962 break;
1963 case RPC_FC_LONG:
1964 case RPC_FC_ULONG:
1965 case RPC_FC_ENUM32:
1966 pMemory += 4;
1967 break;
1968 case RPC_FC_HYPER:
1969 pMemory += 8;
1970 break;
1971 case RPC_FC_POINTER:
1972 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1973 pPointer += 4;
1974 pMemory += 4;
1975 break;
1976 case RPC_FC_ALIGNM4:
1977 ALIGN_POINTER(pMemory, 4);
1978 break;
1979 case RPC_FC_ALIGNM8:
1980 ALIGN_POINTER(pMemory, 8);
1981 break;
1982 case RPC_FC_STRUCTPAD1:
1983 case RPC_FC_STRUCTPAD2:
1984 case RPC_FC_STRUCTPAD3:
1985 case RPC_FC_STRUCTPAD4:
1986 case RPC_FC_STRUCTPAD5:
1987 case RPC_FC_STRUCTPAD6:
1988 case RPC_FC_STRUCTPAD7:
1989 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1990 break;
1991 case RPC_FC_EMBEDDED_COMPLEX:
1992 pMemory += pFormat[1];
1993 pFormat += 2;
1994 desc = pFormat + *(const SHORT*)pFormat;
1995 size = EmbeddedComplexSize(pStubMsg, desc);
1996 m = NdrFreer[*desc & NDR_TABLE_MASK];
1997 if (m) m(pStubMsg, pMemory, desc);
1998 else FIXME("no freer for embedded type %02x\n", *desc);
1999 pMemory += size;
2000 pFormat += 2;
2001 continue;
2002 case RPC_FC_PAD:
2003 break;
2004 default:
2005 FIXME("unhandled format 0x%02x\n", *pFormat);
2007 pFormat++;
2010 return pMemory;
2013 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2014 PFORMAT_STRING pFormat)
2016 PFORMAT_STRING desc;
2017 unsigned long size = 0;
2019 while (*pFormat != RPC_FC_END) {
2020 switch (*pFormat) {
2021 case RPC_FC_BYTE:
2022 case RPC_FC_CHAR:
2023 case RPC_FC_SMALL:
2024 case RPC_FC_USMALL:
2025 size += 1;
2026 pStubMsg->Buffer += 1;
2027 break;
2028 case RPC_FC_WCHAR:
2029 case RPC_FC_SHORT:
2030 case RPC_FC_USHORT:
2031 size += 2;
2032 pStubMsg->Buffer += 2;
2033 break;
2034 case RPC_FC_LONG:
2035 case RPC_FC_ULONG:
2036 case RPC_FC_ENUM32:
2037 size += 4;
2038 pStubMsg->Buffer += 4;
2039 break;
2040 case RPC_FC_HYPER:
2041 size += 8;
2042 pStubMsg->Buffer += 8;
2043 break;
2044 case RPC_FC_POINTER:
2045 size += 4;
2046 pStubMsg->Buffer += 4;
2047 break;
2048 case RPC_FC_ALIGNM4:
2049 ALIGN_LENGTH(size, 4);
2050 ALIGN_POINTER(pStubMsg->Buffer, 4);
2051 break;
2052 case RPC_FC_ALIGNM8:
2053 ALIGN_LENGTH(size, 8);
2054 ALIGN_POINTER(pStubMsg->Buffer, 8);
2055 break;
2056 case RPC_FC_STRUCTPAD1:
2057 case RPC_FC_STRUCTPAD2:
2058 case RPC_FC_STRUCTPAD3:
2059 case RPC_FC_STRUCTPAD4:
2060 case RPC_FC_STRUCTPAD5:
2061 case RPC_FC_STRUCTPAD6:
2062 case RPC_FC_STRUCTPAD7:
2063 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2064 break;
2065 case RPC_FC_EMBEDDED_COMPLEX:
2066 size += pFormat[1];
2067 pFormat += 2;
2068 desc = pFormat + *(const SHORT*)pFormat;
2069 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2070 pFormat += 2;
2071 continue;
2072 case RPC_FC_PAD:
2073 break;
2074 default:
2075 FIXME("unhandled format 0x%02x\n", *pFormat);
2077 pFormat++;
2080 return size;
2083 /***********************************************************************
2084 * NdrComplexStructMarshall [RPCRT4.@]
2086 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2087 unsigned char *pMemory,
2088 PFORMAT_STRING pFormat)
2090 PFORMAT_STRING conf_array = NULL;
2091 PFORMAT_STRING pointer_desc = NULL;
2092 unsigned char *OldMemory = pStubMsg->Memory;
2094 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2096 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2098 pFormat += 4;
2099 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2100 pFormat += 2;
2101 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2102 pFormat += 2;
2104 pStubMsg->Memory = pMemory;
2106 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2108 if (conf_array)
2109 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2111 pStubMsg->Memory = OldMemory;
2113 STD_OVERFLOW_CHECK(pStubMsg);
2115 return NULL;
2118 /***********************************************************************
2119 * NdrComplexStructUnmarshall [RPCRT4.@]
2121 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2122 unsigned char **ppMemory,
2123 PFORMAT_STRING pFormat,
2124 unsigned char fMustAlloc)
2126 unsigned size = *(const WORD*)(pFormat+2);
2127 PFORMAT_STRING conf_array = NULL;
2128 PFORMAT_STRING pointer_desc = NULL;
2129 unsigned char *pMemory;
2131 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2133 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2135 if (fMustAlloc || !*ppMemory)
2137 *ppMemory = NdrAllocate(pStubMsg, size);
2138 memset(*ppMemory, 0, size);
2141 pFormat += 4;
2142 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2143 pFormat += 2;
2144 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2145 pFormat += 2;
2147 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2149 if (conf_array)
2150 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2152 return NULL;
2155 /***********************************************************************
2156 * NdrComplexStructBufferSize [RPCRT4.@]
2158 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2159 unsigned char *pMemory,
2160 PFORMAT_STRING pFormat)
2162 PFORMAT_STRING conf_array = NULL;
2163 PFORMAT_STRING pointer_desc = NULL;
2164 unsigned char *OldMemory = pStubMsg->Memory;
2166 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2168 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2170 pFormat += 4;
2171 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2172 pFormat += 2;
2173 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2174 pFormat += 2;
2176 pStubMsg->Memory = pMemory;
2178 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2180 if (conf_array)
2181 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2183 pStubMsg->Memory = OldMemory;
2186 /***********************************************************************
2187 * NdrComplexStructMemorySize [RPCRT4.@]
2189 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2190 PFORMAT_STRING pFormat)
2192 unsigned size = *(const WORD*)(pFormat+2);
2193 PFORMAT_STRING conf_array = NULL;
2194 PFORMAT_STRING pointer_desc = NULL;
2196 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2198 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2200 pFormat += 4;
2201 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2202 pFormat += 2;
2203 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2204 pFormat += 2;
2206 ComplexStructMemorySize(pStubMsg, pFormat);
2208 if (conf_array)
2209 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2211 return size;
2214 /***********************************************************************
2215 * NdrComplexStructFree [RPCRT4.@]
2217 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2218 unsigned char *pMemory,
2219 PFORMAT_STRING pFormat)
2221 PFORMAT_STRING conf_array = NULL;
2222 PFORMAT_STRING pointer_desc = NULL;
2223 unsigned char *OldMemory = pStubMsg->Memory;
2225 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2227 pFormat += 4;
2228 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2229 pFormat += 2;
2230 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2231 pFormat += 2;
2233 pStubMsg->Memory = pMemory;
2235 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2237 if (conf_array)
2238 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2240 pStubMsg->Memory = OldMemory;
2243 /***********************************************************************
2244 * NdrConformantArrayMarshall [RPCRT4.@]
2246 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2247 unsigned char *pMemory,
2248 PFORMAT_STRING pFormat)
2250 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2251 unsigned char alignment = pFormat[1] + 1;
2253 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2254 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2256 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2258 WriteConformance(pStubMsg);
2260 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2262 size = safe_multiply(esize, pStubMsg->MaxCount);
2263 memcpy(pStubMsg->Buffer, pMemory, size);
2264 pStubMsg->BufferMark = pStubMsg->Buffer;
2265 pStubMsg->Buffer += size;
2267 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2269 STD_OVERFLOW_CHECK(pStubMsg);
2271 return NULL;
2274 /***********************************************************************
2275 * NdrConformantArrayUnmarshall [RPCRT4.@]
2277 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2278 unsigned char **ppMemory,
2279 PFORMAT_STRING pFormat,
2280 unsigned char fMustAlloc)
2282 DWORD size, esize = *(const WORD*)(pFormat+2);
2283 unsigned char alignment = pFormat[1] + 1;
2285 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2286 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2288 pFormat = ReadConformance(pStubMsg, pFormat+4);
2290 size = safe_multiply(esize, pStubMsg->MaxCount);
2292 if (fMustAlloc || !*ppMemory)
2293 *ppMemory = NdrAllocate(pStubMsg, size);
2295 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2297 memcpy(*ppMemory, pStubMsg->Buffer, size);
2299 pStubMsg->BufferMark = pStubMsg->Buffer;
2300 pStubMsg->Buffer += size;
2302 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2304 return NULL;
2307 /***********************************************************************
2308 * NdrConformantArrayBufferSize [RPCRT4.@]
2310 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2311 unsigned char *pMemory,
2312 PFORMAT_STRING pFormat)
2314 DWORD size, esize = *(const WORD*)(pFormat+2);
2315 unsigned char alignment = pFormat[1] + 1;
2317 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2318 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2320 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2322 SizeConformance(pStubMsg);
2324 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2326 size = safe_multiply(esize, pStubMsg->MaxCount);
2327 /* conformance value plus array */
2328 pStubMsg->BufferLength += size;
2330 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2333 /***********************************************************************
2334 * NdrConformantArrayMemorySize [RPCRT4.@]
2336 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2337 PFORMAT_STRING pFormat)
2339 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2340 unsigned char alignment = pFormat[1] + 1;
2342 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2343 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2345 pFormat = ReadConformance(pStubMsg, pFormat+4);
2346 size = safe_multiply(esize, pStubMsg->MaxCount);
2347 pStubMsg->MemorySize += size;
2349 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2350 pStubMsg->BufferMark = pStubMsg->Buffer;
2351 pStubMsg->Buffer += size;
2353 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2355 return pStubMsg->MemorySize;
2358 /***********************************************************************
2359 * NdrConformantArrayFree [RPCRT4.@]
2361 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2362 unsigned char *pMemory,
2363 PFORMAT_STRING pFormat)
2365 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2366 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2368 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2370 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2374 /***********************************************************************
2375 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2377 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2378 unsigned char* pMemory,
2379 PFORMAT_STRING pFormat )
2381 ULONG bufsize;
2382 unsigned char alignment = pFormat[1] + 1;
2383 DWORD esize = *(const WORD*)(pFormat+2);
2385 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2387 if (pFormat[0] != RPC_FC_CVARRAY)
2389 ERR("invalid format type %x\n", pFormat[0]);
2390 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2391 return NULL;
2394 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2395 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2397 WriteConformance(pStubMsg);
2398 WriteVariance(pStubMsg);
2400 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2402 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2404 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2405 pStubMsg->BufferMark = pStubMsg->Buffer;
2406 pStubMsg->Buffer += bufsize;
2408 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2410 STD_OVERFLOW_CHECK(pStubMsg);
2412 return NULL;
2416 /***********************************************************************
2417 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2419 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2420 unsigned char** ppMemory,
2421 PFORMAT_STRING pFormat,
2422 unsigned char fMustAlloc )
2424 ULONG bufsize, memsize;
2425 unsigned char alignment = pFormat[1] + 1;
2426 DWORD esize = *(const WORD*)(pFormat+2);
2428 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2430 if (pFormat[0] != RPC_FC_CVARRAY)
2432 ERR("invalid format type %x\n", pFormat[0]);
2433 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2434 return NULL;
2437 pFormat = ReadConformance(pStubMsg, pFormat+4);
2438 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2440 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2442 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2443 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2445 if (!*ppMemory || fMustAlloc)
2446 *ppMemory = NdrAllocate(pStubMsg, memsize);
2447 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
2448 pStubMsg->Buffer += bufsize;
2450 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2452 return NULL;
2456 /***********************************************************************
2457 * NdrConformantVaryingArrayFree [RPCRT4.@]
2459 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2460 unsigned char* pMemory,
2461 PFORMAT_STRING pFormat )
2463 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2465 if (pFormat[0] != RPC_FC_CVARRAY)
2467 ERR("invalid format type %x\n", pFormat[0]);
2468 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2469 return;
2472 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2473 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2475 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2479 /***********************************************************************
2480 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2482 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2483 unsigned char* pMemory, PFORMAT_STRING pFormat )
2485 unsigned char alignment = pFormat[1] + 1;
2486 DWORD esize = *(const WORD*)(pFormat+2);
2488 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2490 if (pFormat[0] != RPC_FC_CVARRAY)
2492 ERR("invalid format type %x\n", pFormat[0]);
2493 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2494 return;
2497 /* compute size */
2498 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2499 /* compute length */
2500 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2502 SizeConformance(pStubMsg);
2503 SizeVariance(pStubMsg);
2505 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2507 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2509 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2513 /***********************************************************************
2514 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2516 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2517 PFORMAT_STRING pFormat )
2519 FIXME( "stub\n" );
2520 return 0;
2524 /***********************************************************************
2525 * NdrComplexArrayMarshall [RPCRT4.@]
2527 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2528 unsigned char *pMemory,
2529 PFORMAT_STRING pFormat)
2531 ULONG i, count, def;
2532 BOOL variance_present;
2533 unsigned char alignment;
2535 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2537 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2539 ERR("invalid format type %x\n", pFormat[0]);
2540 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2541 return NULL;
2544 alignment = pFormat[1] + 1;
2546 def = *(const WORD*)&pFormat[2];
2547 pFormat += 4;
2549 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2550 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2552 variance_present = IsConformanceOrVariancePresent(pFormat);
2553 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2554 TRACE("variance = %d\n", pStubMsg->ActualCount);
2556 WriteConformance(pStubMsg);
2557 if (variance_present)
2558 WriteVariance(pStubMsg);
2560 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2562 count = pStubMsg->ActualCount;
2563 for (i = 0; i < count; i++)
2564 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2566 STD_OVERFLOW_CHECK(pStubMsg);
2568 return NULL;
2571 /***********************************************************************
2572 * NdrComplexArrayUnmarshall [RPCRT4.@]
2574 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2575 unsigned char **ppMemory,
2576 PFORMAT_STRING pFormat,
2577 unsigned char fMustAlloc)
2579 ULONG i, count, esize, memsize;
2580 unsigned char alignment;
2581 unsigned char *pMemory;
2582 unsigned char *Buffer;
2584 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2586 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2588 ERR("invalid format type %x\n", pFormat[0]);
2589 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2590 return NULL;
2593 alignment = pFormat[1] + 1;
2595 pFormat += 4;
2597 pFormat = ReadConformance(pStubMsg, pFormat);
2598 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2600 Buffer = pStubMsg->Buffer;
2601 pStubMsg->MemorySize = 0;
2602 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2603 pStubMsg->Buffer = Buffer;
2605 /* do multiply here instead of inside if block to verify MaxCount */
2606 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2607 if (fMustAlloc || !*ppMemory)
2609 *ppMemory = NdrAllocate(pStubMsg, memsize);
2610 memset(*ppMemory, 0, memsize);
2613 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2615 pMemory = *ppMemory;
2616 count = pStubMsg->ActualCount;
2617 for (i = 0; i < count; i++)
2618 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2620 return NULL;
2623 /***********************************************************************
2624 * NdrComplexArrayBufferSize [RPCRT4.@]
2626 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2627 unsigned char *pMemory,
2628 PFORMAT_STRING pFormat)
2630 ULONG i, count, def;
2631 unsigned char alignment;
2632 BOOL variance_present;
2634 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2636 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2638 ERR("invalid format type %x\n", pFormat[0]);
2639 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2640 return;
2643 alignment = pFormat[1] + 1;
2645 def = *(const WORD*)&pFormat[2];
2646 pFormat += 4;
2648 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2649 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2650 SizeConformance(pStubMsg);
2652 variance_present = IsConformanceOrVariancePresent(pFormat);
2653 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2654 TRACE("variance = %d\n", pStubMsg->ActualCount);
2656 if (variance_present)
2657 SizeVariance(pStubMsg);
2659 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2661 count = pStubMsg->ActualCount;
2662 for (i = 0; i < count; i++)
2663 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2666 /***********************************************************************
2667 * NdrComplexArrayMemorySize [RPCRT4.@]
2669 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2670 PFORMAT_STRING pFormat)
2672 ULONG i, count, esize, SavedMemorySize, MemorySize;
2673 unsigned char alignment;
2674 unsigned char *Buffer;
2676 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2678 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2680 ERR("invalid format type %x\n", pFormat[0]);
2681 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2682 return 0;
2685 alignment = pFormat[1] + 1;
2687 pFormat += 4;
2689 pFormat = ReadConformance(pStubMsg, pFormat);
2690 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2692 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2694 SavedMemorySize = pStubMsg->MemorySize;
2696 Buffer = pStubMsg->Buffer;
2697 pStubMsg->MemorySize = 0;
2698 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2699 pStubMsg->Buffer = Buffer;
2701 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
2703 count = pStubMsg->ActualCount;
2704 for (i = 0; i < count; i++)
2705 ComplexStructMemorySize(pStubMsg, pFormat);
2707 pStubMsg->MemorySize = SavedMemorySize;
2709 pStubMsg->MemorySize += MemorySize;
2710 return MemorySize;
2713 /***********************************************************************
2714 * NdrComplexArrayFree [RPCRT4.@]
2716 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2717 unsigned char *pMemory,
2718 PFORMAT_STRING pFormat)
2720 ULONG i, count, def;
2722 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2724 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2726 ERR("invalid format type %x\n", pFormat[0]);
2727 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2728 return;
2731 def = *(const WORD*)&pFormat[2];
2732 pFormat += 4;
2734 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2735 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2737 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2738 TRACE("variance = %d\n", pStubMsg->ActualCount);
2740 count = pStubMsg->ActualCount;
2741 for (i = 0; i < count; i++)
2742 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2745 static ULONG UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2747 return MAKELONG(pStubMsg->dwDestContext,
2748 pStubMsg->RpcMsg->DataRepresentation);
2751 #define USER_MARSHAL_PTR_PREFIX \
2752 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2753 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2755 /***********************************************************************
2756 * NdrUserMarshalMarshall [RPCRT4.@]
2758 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2759 unsigned char *pMemory,
2760 PFORMAT_STRING pFormat)
2762 unsigned flags = pFormat[1];
2763 unsigned index = *(const WORD*)&pFormat[2];
2764 ULONG uflag = UserMarshalFlags(pStubMsg);
2765 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2766 TRACE("index=%d\n", index);
2768 if (flags & USER_MARSHAL_POINTER)
2770 ALIGN_POINTER(pStubMsg->Buffer, 4);
2771 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2772 pStubMsg->Buffer += 4;
2773 ALIGN_POINTER(pStubMsg->Buffer, 8);
2775 else
2776 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2778 pStubMsg->Buffer =
2779 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2780 &uflag, pStubMsg->Buffer, pMemory);
2782 STD_OVERFLOW_CHECK(pStubMsg);
2784 return NULL;
2787 /***********************************************************************
2788 * NdrUserMarshalUnmarshall [RPCRT4.@]
2790 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2791 unsigned char **ppMemory,
2792 PFORMAT_STRING pFormat,
2793 unsigned char fMustAlloc)
2795 unsigned flags = pFormat[1];
2796 unsigned index = *(const WORD*)&pFormat[2];
2797 DWORD memsize = *(const WORD*)&pFormat[4];
2798 ULONG uflag = UserMarshalFlags(pStubMsg);
2799 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2800 TRACE("index=%d\n", index);
2802 if (flags & USER_MARSHAL_POINTER)
2804 ALIGN_POINTER(pStubMsg->Buffer, 4);
2805 /* skip pointer prefix */
2806 pStubMsg->Buffer += 4;
2807 ALIGN_POINTER(pStubMsg->Buffer, 8);
2809 else
2810 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2812 if (fMustAlloc || !*ppMemory)
2813 *ppMemory = NdrAllocate(pStubMsg, memsize);
2815 pStubMsg->Buffer =
2816 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2817 &uflag, pStubMsg->Buffer, *ppMemory);
2819 return NULL;
2822 /***********************************************************************
2823 * NdrUserMarshalBufferSize [RPCRT4.@]
2825 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2826 unsigned char *pMemory,
2827 PFORMAT_STRING pFormat)
2829 unsigned flags = pFormat[1];
2830 unsigned index = *(const WORD*)&pFormat[2];
2831 DWORD bufsize = *(const WORD*)&pFormat[6];
2832 ULONG uflag = UserMarshalFlags(pStubMsg);
2833 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2834 TRACE("index=%d\n", index);
2836 if (flags & USER_MARSHAL_POINTER)
2838 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2839 /* skip pointer prefix */
2840 pStubMsg->BufferLength += 4;
2841 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2843 else
2844 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2846 if (bufsize) {
2847 TRACE("size=%d\n", bufsize);
2848 pStubMsg->BufferLength += bufsize;
2849 return;
2852 pStubMsg->BufferLength =
2853 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2854 &uflag, pStubMsg->BufferLength, pMemory);
2857 /***********************************************************************
2858 * NdrUserMarshalMemorySize [RPCRT4.@]
2860 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2861 PFORMAT_STRING pFormat)
2863 unsigned flags = pFormat[1];
2864 unsigned index = *(const WORD*)&pFormat[2];
2865 DWORD memsize = *(const WORD*)&pFormat[4];
2866 DWORD bufsize = *(const WORD*)&pFormat[6];
2868 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2869 TRACE("index=%d\n", index);
2871 pStubMsg->MemorySize += memsize;
2873 if (flags & USER_MARSHAL_POINTER)
2875 ALIGN_POINTER(pStubMsg->Buffer, 4);
2876 /* skip pointer prefix */
2877 pStubMsg->Buffer += 4;
2878 ALIGN_POINTER(pStubMsg->Buffer, 8);
2880 else
2881 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2883 pStubMsg->Buffer += bufsize;
2885 return pStubMsg->MemorySize;
2888 /***********************************************************************
2889 * NdrUserMarshalFree [RPCRT4.@]
2891 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2892 unsigned char *pMemory,
2893 PFORMAT_STRING pFormat)
2895 /* unsigned flags = pFormat[1]; */
2896 unsigned index = *(const WORD*)&pFormat[2];
2897 ULONG uflag = UserMarshalFlags(pStubMsg);
2898 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2899 TRACE("index=%d\n", index);
2901 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2902 &uflag, pMemory);
2905 /***********************************************************************
2906 * NdrClearOutParameters [RPCRT4.@]
2908 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2909 PFORMAT_STRING pFormat,
2910 void *ArgAddr)
2912 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2915 /***********************************************************************
2916 * NdrConvert [RPCRT4.@]
2918 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2920 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2921 /* FIXME: since this stub doesn't do any converting, the proper behavior
2922 is to raise an exception */
2925 /***********************************************************************
2926 * NdrConvert2 [RPCRT4.@]
2928 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
2930 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
2931 pStubMsg, pFormat, NumberParams);
2932 /* FIXME: since this stub doesn't do any converting, the proper behavior
2933 is to raise an exception */
2936 typedef struct _NDR_CSTRUCT_FORMAT
2938 unsigned char type;
2939 unsigned char alignment;
2940 unsigned short memory_size;
2941 short offset_to_array_description;
2942 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2944 /***********************************************************************
2945 * NdrConformantStructMarshall [RPCRT4.@]
2947 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2948 unsigned char *pMemory,
2949 PFORMAT_STRING pFormat)
2951 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
2952 PFORMAT_STRING pCArrayFormat;
2953 ULONG esize, bufsize;
2955 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2957 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2958 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2960 ERR("invalid format type %x\n", pCStructFormat->type);
2961 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2962 return NULL;
2965 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
2966 pCStructFormat->offset_to_array_description;
2967 if (*pCArrayFormat != RPC_FC_CARRAY)
2969 ERR("invalid array format type %x\n", pCStructFormat->type);
2970 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2971 return NULL;
2973 esize = *(const WORD*)(pCArrayFormat+2);
2975 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2976 pCArrayFormat + 4, 0);
2978 WriteConformance(pStubMsg);
2980 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2982 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2984 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
2985 /* copy constant sized part of struct */
2986 pStubMsg->BufferMark = pStubMsg->Buffer;
2987 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
2988 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
2990 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2991 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2993 STD_OVERFLOW_CHECK(pStubMsg);
2995 return NULL;
2998 /***********************************************************************
2999 * NdrConformantStructUnmarshall [RPCRT4.@]
3001 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3002 unsigned char **ppMemory,
3003 PFORMAT_STRING pFormat,
3004 unsigned char fMustAlloc)
3006 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3007 PFORMAT_STRING pCArrayFormat;
3008 ULONG esize, bufsize;
3010 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3012 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3013 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3015 ERR("invalid format type %x\n", pCStructFormat->type);
3016 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3017 return NULL;
3019 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3020 pCStructFormat->offset_to_array_description;
3021 if (*pCArrayFormat != RPC_FC_CARRAY)
3023 ERR("invalid array format type %x\n", pCStructFormat->type);
3024 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3025 return NULL;
3027 esize = *(const WORD*)(pCArrayFormat+2);
3029 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3031 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3033 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3035 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3036 /* work out how much memory to allocate if we need to do so */
3037 if (!*ppMemory || fMustAlloc)
3039 SIZE_T size = pCStructFormat->memory_size + bufsize;
3040 *ppMemory = NdrAllocate(pStubMsg, size);
3043 /* now copy the data */
3044 pStubMsg->BufferMark = pStubMsg->Buffer;
3045 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
3046 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3048 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3049 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3051 return NULL;
3054 /***********************************************************************
3055 * NdrConformantStructBufferSize [RPCRT4.@]
3057 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3058 unsigned char *pMemory,
3059 PFORMAT_STRING pFormat)
3061 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3062 PFORMAT_STRING pCArrayFormat;
3063 ULONG esize;
3065 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3067 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3068 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3070 ERR("invalid format type %x\n", pCStructFormat->type);
3071 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3072 return;
3074 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3075 pCStructFormat->offset_to_array_description;
3076 if (*pCArrayFormat != RPC_FC_CARRAY)
3078 ERR("invalid array format type %x\n", pCStructFormat->type);
3079 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3080 return;
3082 esize = *(const WORD*)(pCArrayFormat+2);
3084 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3085 SizeConformance(pStubMsg);
3087 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3089 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3091 pStubMsg->BufferLength += pCStructFormat->memory_size +
3092 safe_multiply(pStubMsg->MaxCount, esize);
3094 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3095 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3098 /***********************************************************************
3099 * NdrConformantStructMemorySize [RPCRT4.@]
3101 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3102 PFORMAT_STRING pFormat)
3104 FIXME("stub\n");
3105 return 0;
3108 /***********************************************************************
3109 * NdrConformantStructFree [RPCRT4.@]
3111 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3112 unsigned char *pMemory,
3113 PFORMAT_STRING pFormat)
3115 FIXME("stub\n");
3118 /***********************************************************************
3119 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3121 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3122 unsigned char *pMemory,
3123 PFORMAT_STRING pFormat)
3125 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3126 PFORMAT_STRING pCVArrayFormat;
3127 ULONG esize, bufsize;
3129 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3131 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3132 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3134 ERR("invalid format type %x\n", pCVStructFormat->type);
3135 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3136 return NULL;
3139 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3140 pCVStructFormat->offset_to_array_description;
3141 switch (*pCVArrayFormat)
3143 case RPC_FC_CVARRAY:
3144 esize = *(const WORD*)(pCVArrayFormat+2);
3146 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3147 pCVArrayFormat + 4, 0);
3148 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3149 pCVArrayFormat, 0);
3150 break;
3151 case RPC_FC_C_CSTRING:
3152 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3153 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3154 esize = sizeof(char);
3155 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3156 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3157 pCVArrayFormat + 2, 0);
3158 else
3159 pStubMsg->MaxCount = pStubMsg->ActualCount;
3160 break;
3161 case RPC_FC_C_WSTRING:
3162 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3163 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3164 esize = sizeof(WCHAR);
3165 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3166 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3167 pCVArrayFormat + 2, 0);
3168 else
3169 pStubMsg->MaxCount = pStubMsg->ActualCount;
3170 break;
3171 default:
3172 ERR("invalid array format type %x\n", *pCVArrayFormat);
3173 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3174 return NULL;
3177 WriteConformance(pStubMsg);
3179 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3181 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3183 /* write constant sized part */
3184 pStubMsg->BufferMark = pStubMsg->Buffer;
3185 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3186 pStubMsg->Buffer += pCVStructFormat->memory_size;
3188 WriteVariance(pStubMsg);
3190 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3192 /* write array part */
3193 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3194 pStubMsg->Buffer += bufsize;
3196 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3198 STD_OVERFLOW_CHECK(pStubMsg);
3200 return NULL;
3203 /***********************************************************************
3204 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3206 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3207 unsigned char **ppMemory,
3208 PFORMAT_STRING pFormat,
3209 unsigned char fMustAlloc)
3211 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3212 PFORMAT_STRING pCVArrayFormat;
3213 ULONG esize, bufsize;
3214 unsigned char cvarray_type;
3216 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3218 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3219 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3221 ERR("invalid format type %x\n", pCVStructFormat->type);
3222 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3223 return NULL;
3226 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3227 pCVStructFormat->offset_to_array_description;
3228 cvarray_type = *pCVArrayFormat;
3229 switch (cvarray_type)
3231 case RPC_FC_CVARRAY:
3232 esize = *(const WORD*)(pCVArrayFormat+2);
3233 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3234 break;
3235 case RPC_FC_C_CSTRING:
3236 esize = sizeof(char);
3237 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3238 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3239 else
3240 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3241 break;
3242 case RPC_FC_C_WSTRING:
3243 esize = sizeof(WCHAR);
3244 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3245 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3246 else
3247 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3248 break;
3249 default:
3250 ERR("invalid array format type %x\n", *pCVArrayFormat);
3251 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3252 return NULL;
3255 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3257 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3259 /* work out how much memory to allocate if we need to do so */
3260 if (!*ppMemory || fMustAlloc)
3262 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3263 *ppMemory = NdrAllocate(pStubMsg, size);
3266 /* copy the constant data */
3267 pStubMsg->BufferMark = pStubMsg->Buffer;
3268 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3269 pStubMsg->Buffer += pCVStructFormat->memory_size;
3271 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3273 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3275 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3276 (cvarray_type == RPC_FC_C_WSTRING))
3278 ULONG i;
3279 /* strings must always have null terminating bytes */
3280 if (bufsize < esize)
3282 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
3283 RpcRaiseException(RPC_S_INVALID_BOUND);
3284 return NULL;
3286 for (i = bufsize - esize; i < bufsize; i++)
3287 if (pStubMsg->Buffer[i] != 0)
3289 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3290 i, pStubMsg->Buffer[i]);
3291 RpcRaiseException(RPC_S_INVALID_BOUND);
3292 return NULL;
3296 /* copy the array data */
3297 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3298 bufsize);
3299 pStubMsg->Buffer += bufsize;
3301 if (cvarray_type == RPC_FC_C_CSTRING)
3302 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3303 else if (cvarray_type == RPC_FC_C_WSTRING)
3304 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3306 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3308 return NULL;
3311 /***********************************************************************
3312 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3314 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3315 unsigned char *pMemory,
3316 PFORMAT_STRING pFormat)
3318 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3319 PFORMAT_STRING pCVArrayFormat;
3320 ULONG esize;
3322 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3324 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3325 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3327 ERR("invalid format type %x\n", pCVStructFormat->type);
3328 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3329 return;
3332 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3333 pCVStructFormat->offset_to_array_description;
3334 switch (*pCVArrayFormat)
3336 case RPC_FC_CVARRAY:
3337 esize = *(const WORD*)(pCVArrayFormat+2);
3339 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3340 pCVArrayFormat + 4, 0);
3341 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3342 pCVArrayFormat, 0);
3343 break;
3344 case RPC_FC_C_CSTRING:
3345 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3346 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3347 esize = sizeof(char);
3348 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3349 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3350 pCVArrayFormat + 2, 0);
3351 else
3352 pStubMsg->MaxCount = pStubMsg->ActualCount;
3353 break;
3354 case RPC_FC_C_WSTRING:
3355 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3356 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3357 esize = sizeof(WCHAR);
3358 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3359 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3360 pCVArrayFormat + 2, 0);
3361 else
3362 pStubMsg->MaxCount = pStubMsg->ActualCount;
3363 break;
3364 default:
3365 ERR("invalid array format type %x\n", *pCVArrayFormat);
3366 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3367 return;
3370 SizeConformance(pStubMsg);
3372 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3374 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3376 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3377 SizeVariance(pStubMsg);
3378 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3380 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3383 /***********************************************************************
3384 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3386 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3387 PFORMAT_STRING pFormat)
3389 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3390 PFORMAT_STRING pCVArrayFormat;
3391 ULONG esize;
3392 unsigned char cvarray_type;
3394 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3396 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3397 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3399 ERR("invalid format type %x\n", pCVStructFormat->type);
3400 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3401 return 0;
3404 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3405 pCVStructFormat->offset_to_array_description;
3406 cvarray_type = *pCVArrayFormat;
3407 switch (cvarray_type)
3409 case RPC_FC_CVARRAY:
3410 esize = *(const WORD*)(pCVArrayFormat+2);
3411 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3412 break;
3413 case RPC_FC_C_CSTRING:
3414 esize = sizeof(char);
3415 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3416 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3417 else
3418 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3419 break;
3420 case RPC_FC_C_WSTRING:
3421 esize = sizeof(WCHAR);
3422 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3423 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3424 else
3425 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3426 break;
3427 default:
3428 ERR("invalid array format type %x\n", *pCVArrayFormat);
3429 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3430 return 0;
3433 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3435 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3437 pStubMsg->Buffer += pCVStructFormat->memory_size;
3438 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3439 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3441 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3443 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3445 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3448 /***********************************************************************
3449 * NdrConformantVaryingStructFree [RPCRT4.@]
3451 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3452 unsigned char *pMemory,
3453 PFORMAT_STRING pFormat)
3455 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3456 PFORMAT_STRING pCVArrayFormat;
3457 ULONG esize;
3459 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3461 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3462 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3464 ERR("invalid format type %x\n", pCVStructFormat->type);
3465 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3466 return;
3469 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3470 pCVStructFormat->offset_to_array_description;
3471 switch (*pCVArrayFormat)
3473 case RPC_FC_CVARRAY:
3474 esize = *(const WORD*)(pCVArrayFormat+2);
3476 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3477 pCVArrayFormat + 4, 0);
3478 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3479 pCVArrayFormat, 0);
3480 break;
3481 case RPC_FC_C_CSTRING:
3482 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3483 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3484 esize = sizeof(char);
3485 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3486 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3487 pCVArrayFormat + 2, 0);
3488 else
3489 pStubMsg->MaxCount = pStubMsg->ActualCount;
3490 break;
3491 case RPC_FC_C_WSTRING:
3492 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3493 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3494 esize = sizeof(WCHAR);
3495 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3496 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3497 pCVArrayFormat + 2, 0);
3498 else
3499 pStubMsg->MaxCount = pStubMsg->ActualCount;
3500 break;
3501 default:
3502 ERR("invalid array format type %x\n", *pCVArrayFormat);
3503 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3504 return;
3507 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3509 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3512 typedef struct
3514 unsigned char type;
3515 unsigned char alignment;
3516 unsigned short total_size;
3517 } NDR_SMFARRAY_FORMAT;
3519 typedef struct
3521 unsigned char type;
3522 unsigned char alignment;
3523 unsigned long total_size;
3524 } NDR_LGFARRAY_FORMAT;
3526 /***********************************************************************
3527 * NdrFixedArrayMarshall [RPCRT4.@]
3529 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3530 unsigned char *pMemory,
3531 PFORMAT_STRING pFormat)
3533 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3534 unsigned long total_size;
3536 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3538 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3539 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3541 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3542 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3543 return NULL;
3546 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3548 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3550 total_size = pSmFArrayFormat->total_size;
3551 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3553 else
3555 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3556 total_size = pLgFArrayFormat->total_size;
3557 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3560 memcpy(pStubMsg->Buffer, pMemory, total_size);
3561 pStubMsg->BufferMark = pStubMsg->Buffer;
3562 pStubMsg->Buffer += total_size;
3564 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3566 return NULL;
3569 /***********************************************************************
3570 * NdrFixedArrayUnmarshall [RPCRT4.@]
3572 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3573 unsigned char **ppMemory,
3574 PFORMAT_STRING pFormat,
3575 unsigned char fMustAlloc)
3577 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3578 unsigned long total_size;
3580 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3582 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3583 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3585 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3586 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3587 return NULL;
3590 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3592 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3594 total_size = pSmFArrayFormat->total_size;
3595 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3597 else
3599 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3600 total_size = pLgFArrayFormat->total_size;
3601 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3604 if (fMustAlloc || !*ppMemory)
3605 *ppMemory = NdrAllocate(pStubMsg, total_size);
3606 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3607 pStubMsg->BufferMark = pStubMsg->Buffer;
3608 pStubMsg->Buffer += total_size;
3610 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3612 return NULL;
3615 /***********************************************************************
3616 * NdrFixedArrayBufferSize [RPCRT4.@]
3618 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3619 unsigned char *pMemory,
3620 PFORMAT_STRING pFormat)
3622 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3623 unsigned long total_size;
3625 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3627 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3628 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3630 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3631 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3632 return;
3635 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3637 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3639 total_size = pSmFArrayFormat->total_size;
3640 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3642 else
3644 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3645 total_size = pLgFArrayFormat->total_size;
3646 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3648 pStubMsg->BufferLength += total_size;
3650 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3653 /***********************************************************************
3654 * NdrFixedArrayMemorySize [RPCRT4.@]
3656 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3657 PFORMAT_STRING pFormat)
3659 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3660 ULONG total_size;
3662 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3664 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3665 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3667 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3668 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3669 return 0;
3672 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3674 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3676 total_size = pSmFArrayFormat->total_size;
3677 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3679 else
3681 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3682 total_size = pLgFArrayFormat->total_size;
3683 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3685 pStubMsg->BufferMark = pStubMsg->Buffer;
3686 pStubMsg->Buffer += total_size;
3687 pStubMsg->MemorySize += total_size;
3689 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3691 return total_size;
3694 /***********************************************************************
3695 * NdrFixedArrayFree [RPCRT4.@]
3697 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3698 unsigned char *pMemory,
3699 PFORMAT_STRING pFormat)
3701 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3703 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3705 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3706 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3708 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3709 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3710 return;
3713 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3714 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3715 else
3717 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3718 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3721 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3724 /***********************************************************************
3725 * NdrVaryingArrayMarshall [RPCRT4.@]
3727 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3728 unsigned char *pMemory,
3729 PFORMAT_STRING pFormat)
3731 unsigned char alignment;
3732 DWORD elements, esize;
3733 ULONG bufsize;
3735 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3737 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3738 (pFormat[0] != RPC_FC_LGVARRAY))
3740 ERR("invalid format type %x\n", pFormat[0]);
3741 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3742 return NULL;
3745 alignment = pFormat[1] + 1;
3747 if (pFormat[0] == RPC_FC_SMVARRAY)
3749 pFormat += 2;
3750 pFormat += sizeof(WORD);
3751 elements = *(const WORD*)pFormat;
3752 pFormat += sizeof(WORD);
3754 else
3756 pFormat += 2;
3757 pFormat += sizeof(DWORD);
3758 elements = *(const DWORD*)pFormat;
3759 pFormat += sizeof(DWORD);
3762 esize = *(const WORD*)pFormat;
3763 pFormat += sizeof(WORD);
3765 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3766 if ((pStubMsg->ActualCount > elements) ||
3767 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3769 RpcRaiseException(RPC_S_INVALID_BOUND);
3770 return NULL;
3773 WriteVariance(pStubMsg);
3775 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3777 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3778 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
3779 pStubMsg->BufferMark = pStubMsg->Buffer;
3780 pStubMsg->Buffer += bufsize;
3782 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3784 STD_OVERFLOW_CHECK(pStubMsg);
3786 return NULL;
3789 /***********************************************************************
3790 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3792 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3793 unsigned char **ppMemory,
3794 PFORMAT_STRING pFormat,
3795 unsigned char fMustAlloc)
3797 unsigned char alignment;
3798 DWORD size, elements, esize;
3799 ULONG bufsize;
3801 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3803 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3804 (pFormat[0] != RPC_FC_LGVARRAY))
3806 ERR("invalid format type %x\n", pFormat[0]);
3807 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3808 return NULL;
3811 alignment = pFormat[1] + 1;
3813 if (pFormat[0] == RPC_FC_SMVARRAY)
3815 pFormat += 2;
3816 size = *(const WORD*)pFormat;
3817 pFormat += sizeof(WORD);
3818 elements = *(const WORD*)pFormat;
3819 pFormat += sizeof(WORD);
3821 else
3823 pFormat += 2;
3824 size = *(const DWORD*)pFormat;
3825 pFormat += sizeof(DWORD);
3826 elements = *(const DWORD*)pFormat;
3827 pFormat += sizeof(DWORD);
3830 esize = *(const WORD*)pFormat;
3831 pFormat += sizeof(WORD);
3833 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3835 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3837 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3839 if (!*ppMemory || fMustAlloc)
3840 *ppMemory = NdrAllocate(pStubMsg, size);
3841 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
3842 pStubMsg->Buffer += bufsize;
3844 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3846 return NULL;
3849 /***********************************************************************
3850 * NdrVaryingArrayBufferSize [RPCRT4.@]
3852 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3853 unsigned char *pMemory,
3854 PFORMAT_STRING pFormat)
3856 unsigned char alignment;
3857 DWORD elements, esize;
3859 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3861 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3862 (pFormat[0] != RPC_FC_LGVARRAY))
3864 ERR("invalid format type %x\n", pFormat[0]);
3865 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3866 return;
3869 alignment = pFormat[1] + 1;
3871 if (pFormat[0] == RPC_FC_SMVARRAY)
3873 pFormat += 2;
3874 pFormat += sizeof(WORD);
3875 elements = *(const WORD*)pFormat;
3876 pFormat += sizeof(WORD);
3878 else
3880 pFormat += 2;
3881 pFormat += sizeof(DWORD);
3882 elements = *(const DWORD*)pFormat;
3883 pFormat += sizeof(DWORD);
3886 esize = *(const WORD*)pFormat;
3887 pFormat += sizeof(WORD);
3889 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3890 if ((pStubMsg->ActualCount > elements) ||
3891 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3893 RpcRaiseException(RPC_S_INVALID_BOUND);
3894 return;
3897 SizeVariance(pStubMsg);
3899 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3901 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
3903 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3906 /***********************************************************************
3907 * NdrVaryingArrayMemorySize [RPCRT4.@]
3909 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3910 PFORMAT_STRING pFormat)
3912 unsigned char alignment;
3913 DWORD size, elements, esize;
3915 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3917 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3918 (pFormat[0] != RPC_FC_LGVARRAY))
3920 ERR("invalid format type %x\n", pFormat[0]);
3921 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3922 return 0;
3925 alignment = pFormat[1] + 1;
3927 if (pFormat[0] == RPC_FC_SMVARRAY)
3929 pFormat += 2;
3930 size = *(const WORD*)pFormat;
3931 pFormat += sizeof(WORD);
3932 elements = *(const WORD*)pFormat;
3933 pFormat += sizeof(WORD);
3935 else
3937 pFormat += 2;
3938 size = *(const DWORD*)pFormat;
3939 pFormat += sizeof(DWORD);
3940 elements = *(const DWORD*)pFormat;
3941 pFormat += sizeof(DWORD);
3944 esize = *(const WORD*)pFormat;
3945 pFormat += sizeof(WORD);
3947 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3949 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3951 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
3952 pStubMsg->MemorySize += size;
3954 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3956 return pStubMsg->MemorySize;
3959 /***********************************************************************
3960 * NdrVaryingArrayFree [RPCRT4.@]
3962 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3963 unsigned char *pMemory,
3964 PFORMAT_STRING pFormat)
3966 unsigned char alignment;
3967 DWORD elements;
3969 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3971 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3972 (pFormat[0] != RPC_FC_LGVARRAY))
3974 ERR("invalid format type %x\n", pFormat[0]);
3975 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3976 return;
3979 alignment = pFormat[1] + 1;
3981 if (pFormat[0] == RPC_FC_SMVARRAY)
3983 pFormat += 2;
3984 pFormat += sizeof(WORD);
3985 elements = *(const WORD*)pFormat;
3986 pFormat += sizeof(WORD);
3988 else
3990 pFormat += 2;
3991 pFormat += sizeof(DWORD);
3992 elements = *(const DWORD*)pFormat;
3993 pFormat += sizeof(DWORD);
3996 pFormat += sizeof(WORD);
3998 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3999 if ((pStubMsg->ActualCount > elements) ||
4000 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4002 RpcRaiseException(RPC_S_INVALID_BOUND);
4003 return;
4006 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4009 /***********************************************************************
4010 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4012 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4013 unsigned char *pMemory,
4014 PFORMAT_STRING pFormat)
4016 FIXME("stub\n");
4017 return NULL;
4020 /***********************************************************************
4021 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4023 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4024 unsigned char **ppMemory,
4025 PFORMAT_STRING pFormat,
4026 unsigned char fMustAlloc)
4028 FIXME("stub\n");
4029 return NULL;
4032 /***********************************************************************
4033 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4035 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4036 unsigned char *pMemory,
4037 PFORMAT_STRING pFormat)
4039 FIXME("stub\n");
4042 /***********************************************************************
4043 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4045 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4046 PFORMAT_STRING pFormat)
4048 FIXME("stub\n");
4049 return 0;
4052 /***********************************************************************
4053 * NdrEncapsulatedUnionFree [RPCRT4.@]
4055 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4056 unsigned char *pMemory,
4057 PFORMAT_STRING pFormat)
4059 FIXME("stub\n");
4062 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4063 unsigned long discriminant,
4064 PFORMAT_STRING pFormat)
4066 unsigned short num_arms, arm, type;
4068 num_arms = *(const SHORT*)pFormat & 0x0fff;
4069 pFormat += 2;
4070 for(arm = 0; arm < num_arms; arm++)
4072 if(discriminant == *(const ULONG*)pFormat)
4074 pFormat += 4;
4075 break;
4077 pFormat += 6;
4080 type = *(const unsigned short*)pFormat;
4081 TRACE("type %04x\n", type);
4082 if(arm == num_arms) /* default arm extras */
4084 if(type == 0xffff)
4086 ERR("no arm for 0x%lx and no default case\n", discriminant);
4087 RpcRaiseException(RPC_S_INVALID_TAG);
4088 return NULL;
4090 if(type == 0)
4092 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4093 return NULL;
4096 return pFormat;
4099 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
4100 ULONG value,
4101 PFORMAT_STRING pFormat)
4103 pFormat += *(const SHORT*)pFormat;
4104 pFormat += 2;
4106 return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
4109 /***********************************************************************
4110 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4112 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4113 unsigned char *pMemory,
4114 PFORMAT_STRING pFormat)
4116 unsigned short type;
4117 unsigned char switch_type;
4119 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4120 pFormat++;
4122 switch_type = *pFormat;
4123 pFormat++;
4125 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4126 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4127 /* Marshall discriminant */
4128 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4130 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4131 if(!pFormat)
4132 return NULL;
4134 type = *(const unsigned short*)pFormat;
4135 if((type & 0xff00) == 0x8000)
4137 unsigned char basetype = LOBYTE(type);
4138 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4140 else
4142 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4143 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4144 if (m)
4146 unsigned char *saved_buffer = NULL;
4147 switch(*desc)
4149 case RPC_FC_RP:
4150 case RPC_FC_UP:
4151 case RPC_FC_OP:
4152 case RPC_FC_FP:
4153 saved_buffer = pStubMsg->Buffer;
4154 pStubMsg->Buffer += 4; /* for pointer ID */
4155 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4156 break;
4157 default:
4158 m(pStubMsg, pMemory, desc);
4161 else FIXME("no marshaller for embedded type %02x\n", *desc);
4163 return NULL;
4166 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4167 PFORMAT_STRING *ppFormat)
4169 long discriminant = 0;
4171 switch(**ppFormat)
4173 case RPC_FC_BYTE:
4174 case RPC_FC_CHAR:
4175 case RPC_FC_SMALL:
4176 case RPC_FC_USMALL:
4177 discriminant = *(UCHAR *)pStubMsg->Buffer;
4178 pStubMsg->Buffer += sizeof(UCHAR);
4179 break;
4180 case RPC_FC_WCHAR:
4181 case RPC_FC_SHORT:
4182 case RPC_FC_USHORT:
4183 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4184 discriminant = *(USHORT *)pStubMsg->Buffer;
4185 pStubMsg->Buffer += sizeof(USHORT);
4186 break;
4187 case RPC_FC_LONG:
4188 case RPC_FC_ULONG:
4189 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4190 discriminant = *(ULONG *)pStubMsg->Buffer;
4191 pStubMsg->Buffer += sizeof(ULONG);
4192 break;
4193 default:
4194 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4196 (*ppFormat)++;
4198 if (pStubMsg->fHasNewCorrDesc)
4199 *ppFormat += 6;
4200 else
4201 *ppFormat += 4;
4202 return discriminant;
4205 /**********************************************************************
4206 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4208 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4209 unsigned char **ppMemory,
4210 PFORMAT_STRING pFormat,
4211 unsigned char fMustAlloc)
4213 long discriminant;
4214 unsigned short type, size;
4216 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4217 pFormat++;
4219 /* Unmarshall discriminant */
4220 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4221 TRACE("unmarshalled discriminant %lx\n", discriminant);
4223 pFormat += *(const SHORT*)pFormat;
4225 size = *(const unsigned short*)pFormat;
4226 pFormat += 2;
4228 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4229 if(!pFormat)
4230 return NULL;
4232 if(!*ppMemory || fMustAlloc)
4233 *ppMemory = NdrAllocate(pStubMsg, size);
4235 type = *(const unsigned short*)pFormat;
4236 if((type & 0xff00) == 0x8000)
4238 unsigned char basetype = LOBYTE(type);
4239 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4241 else
4243 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4244 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4245 if (m)
4247 unsigned char *saved_buffer = NULL;
4248 switch(*desc)
4250 case RPC_FC_RP:
4251 case RPC_FC_UP:
4252 case RPC_FC_OP:
4253 case RPC_FC_FP:
4254 ALIGN_POINTER(pStubMsg->Buffer, 4);
4255 saved_buffer = pStubMsg->Buffer;
4256 pStubMsg->Buffer += 4; /* for pointer ID */
4257 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
4258 break;
4259 default:
4260 m(pStubMsg, ppMemory, desc, fMustAlloc);
4263 else FIXME("no marshaller for embedded type %02x\n", *desc);
4265 return NULL;
4268 /***********************************************************************
4269 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4271 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4272 unsigned char *pMemory,
4273 PFORMAT_STRING pFormat)
4275 unsigned short type;
4276 unsigned char switch_type;
4278 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4279 pFormat++;
4281 switch_type = *pFormat;
4282 pFormat++;
4284 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4285 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4286 /* Add discriminant size */
4287 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4289 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4290 if(!pFormat)
4291 return;
4293 type = *(const unsigned short*)pFormat;
4294 if((type & 0xff00) == 0x8000)
4296 unsigned char basetype = LOBYTE(type);
4297 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4299 else
4301 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4302 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4303 if (m)
4305 switch(*desc)
4307 case RPC_FC_RP:
4308 case RPC_FC_UP:
4309 case RPC_FC_OP:
4310 case RPC_FC_FP:
4311 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4312 pStubMsg->BufferLength += 4; /* for pointer ID */
4313 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4314 break;
4315 default:
4316 m(pStubMsg, pMemory, desc);
4319 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4321 return;
4324 /***********************************************************************
4325 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4327 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4328 PFORMAT_STRING pFormat)
4330 ULONG discriminant;
4331 unsigned short type, size;
4333 pFormat++;
4334 /* Unmarshall discriminant */
4335 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4336 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
4338 pFormat += *(const SHORT*)pFormat;
4340 size = *(const unsigned short*)pFormat;
4341 pFormat += 2;
4343 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4344 if(!pFormat)
4345 return 0;
4347 pStubMsg->Memory += size;
4349 type = *(const unsigned short*)pFormat;
4350 if((type & 0xff00) == 0x8000)
4352 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4354 else
4356 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4357 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4358 unsigned char *saved_buffer;
4359 if (m)
4361 switch(*desc)
4363 case RPC_FC_RP:
4364 case RPC_FC_UP:
4365 case RPC_FC_OP:
4366 case RPC_FC_FP:
4367 ALIGN_POINTER(pStubMsg->Buffer, 4);
4368 saved_buffer = pStubMsg->Buffer;
4369 pStubMsg->Buffer += 4;
4370 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4371 pStubMsg->MemorySize += 4;
4372 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4373 break;
4374 default:
4375 return m(pStubMsg, desc);
4378 else FIXME("no marshaller for embedded type %02x\n", *desc);
4381 TRACE("size %d\n", size);
4382 return size;
4385 /***********************************************************************
4386 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4388 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4389 unsigned char *pMemory,
4390 PFORMAT_STRING pFormat)
4392 FIXME("stub\n");
4395 /***********************************************************************
4396 * NdrByteCountPointerMarshall [RPCRT4.@]
4398 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4399 unsigned char *pMemory,
4400 PFORMAT_STRING pFormat)
4402 FIXME("stub\n");
4403 return NULL;
4406 /***********************************************************************
4407 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4409 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4410 unsigned char **ppMemory,
4411 PFORMAT_STRING pFormat,
4412 unsigned char fMustAlloc)
4414 FIXME("stub\n");
4415 return NULL;
4418 /***********************************************************************
4419 * NdrByteCountPointerBufferSize [RPCRT4.@]
4421 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4422 unsigned char *pMemory,
4423 PFORMAT_STRING pFormat)
4425 FIXME("stub\n");
4428 /***********************************************************************
4429 * NdrByteCountPointerMemorySize [RPCRT4.@]
4431 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4432 PFORMAT_STRING pFormat)
4434 FIXME("stub\n");
4435 return 0;
4438 /***********************************************************************
4439 * NdrByteCountPointerFree [RPCRT4.@]
4441 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4442 unsigned char *pMemory,
4443 PFORMAT_STRING pFormat)
4445 FIXME("stub\n");
4448 /***********************************************************************
4449 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4451 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4452 unsigned char *pMemory,
4453 PFORMAT_STRING pFormat)
4455 FIXME("stub\n");
4456 return NULL;
4459 /***********************************************************************
4460 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4462 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4463 unsigned char **ppMemory,
4464 PFORMAT_STRING pFormat,
4465 unsigned char fMustAlloc)
4467 FIXME("stub\n");
4468 return NULL;
4471 /***********************************************************************
4472 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4474 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4475 unsigned char *pMemory,
4476 PFORMAT_STRING pFormat)
4478 FIXME("stub\n");
4481 /***********************************************************************
4482 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4484 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4485 PFORMAT_STRING pFormat)
4487 FIXME("stub\n");
4488 return 0;
4491 /***********************************************************************
4492 * NdrXmitOrRepAsFree [RPCRT4.@]
4494 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4495 unsigned char *pMemory,
4496 PFORMAT_STRING pFormat)
4498 FIXME("stub\n");
4501 /***********************************************************************
4502 * NdrBaseTypeMarshall [internal]
4504 static unsigned char *WINAPI NdrBaseTypeMarshall(
4505 PMIDL_STUB_MESSAGE pStubMsg,
4506 unsigned char *pMemory,
4507 PFORMAT_STRING pFormat)
4509 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4511 switch(*pFormat)
4513 case RPC_FC_BYTE:
4514 case RPC_FC_CHAR:
4515 case RPC_FC_SMALL:
4516 case RPC_FC_USMALL:
4517 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4518 pStubMsg->Buffer += sizeof(UCHAR);
4519 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4520 break;
4521 case RPC_FC_WCHAR:
4522 case RPC_FC_SHORT:
4523 case RPC_FC_USHORT:
4524 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4525 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4526 pStubMsg->Buffer += sizeof(USHORT);
4527 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4528 break;
4529 case RPC_FC_LONG:
4530 case RPC_FC_ULONG:
4531 case RPC_FC_ERROR_STATUS_T:
4532 case RPC_FC_ENUM32:
4533 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4534 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4535 pStubMsg->Buffer += sizeof(ULONG);
4536 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
4537 break;
4538 case RPC_FC_FLOAT:
4539 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4540 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4541 pStubMsg->Buffer += sizeof(float);
4542 break;
4543 case RPC_FC_DOUBLE:
4544 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4545 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4546 pStubMsg->Buffer += sizeof(double);
4547 break;
4548 case RPC_FC_HYPER:
4549 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4550 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4551 pStubMsg->Buffer += sizeof(ULONGLONG);
4552 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4553 break;
4554 case RPC_FC_ENUM16:
4555 /* only 16-bits on the wire, so do a sanity check */
4556 if (*(UINT *)pMemory > USHRT_MAX)
4557 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4558 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4559 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4560 pStubMsg->Buffer += sizeof(USHORT);
4561 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4562 break;
4563 default:
4564 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4567 STD_OVERFLOW_CHECK(pStubMsg);
4569 /* FIXME: what is the correct return value? */
4570 return NULL;
4573 /***********************************************************************
4574 * NdrBaseTypeUnmarshall [internal]
4576 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4577 PMIDL_STUB_MESSAGE pStubMsg,
4578 unsigned char **ppMemory,
4579 PFORMAT_STRING pFormat,
4580 unsigned char fMustAlloc)
4582 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4584 #define BASE_TYPE_UNMARSHALL(type) \
4585 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4586 if (fMustAlloc || !*ppMemory) \
4587 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4588 TRACE("*ppMemory: %p\n", *ppMemory); \
4589 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4590 pStubMsg->Buffer += sizeof(type);
4592 switch(*pFormat)
4594 case RPC_FC_BYTE:
4595 case RPC_FC_CHAR:
4596 case RPC_FC_SMALL:
4597 case RPC_FC_USMALL:
4598 BASE_TYPE_UNMARSHALL(UCHAR);
4599 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4600 break;
4601 case RPC_FC_WCHAR:
4602 case RPC_FC_SHORT:
4603 case RPC_FC_USHORT:
4604 BASE_TYPE_UNMARSHALL(USHORT);
4605 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4606 break;
4607 case RPC_FC_LONG:
4608 case RPC_FC_ULONG:
4609 case RPC_FC_ERROR_STATUS_T:
4610 case RPC_FC_ENUM32:
4611 BASE_TYPE_UNMARSHALL(ULONG);
4612 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
4613 break;
4614 case RPC_FC_FLOAT:
4615 BASE_TYPE_UNMARSHALL(float);
4616 TRACE("value: %f\n", **(float **)ppMemory);
4617 break;
4618 case RPC_FC_DOUBLE:
4619 BASE_TYPE_UNMARSHALL(double);
4620 TRACE("value: %f\n", **(double **)ppMemory);
4621 break;
4622 case RPC_FC_HYPER:
4623 BASE_TYPE_UNMARSHALL(ULONGLONG);
4624 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4625 break;
4626 case RPC_FC_ENUM16:
4627 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4628 if (fMustAlloc || !*ppMemory)
4629 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
4630 TRACE("*ppMemory: %p\n", *ppMemory);
4631 /* 16-bits on the wire, but int in memory */
4632 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4633 pStubMsg->Buffer += sizeof(USHORT);
4634 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4635 break;
4636 default:
4637 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4639 #undef BASE_TYPE_UNMARSHALL
4641 /* FIXME: what is the correct return value? */
4643 return NULL;
4646 /***********************************************************************
4647 * NdrBaseTypeBufferSize [internal]
4649 static void WINAPI NdrBaseTypeBufferSize(
4650 PMIDL_STUB_MESSAGE pStubMsg,
4651 unsigned char *pMemory,
4652 PFORMAT_STRING pFormat)
4654 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4656 switch(*pFormat)
4658 case RPC_FC_BYTE:
4659 case RPC_FC_CHAR:
4660 case RPC_FC_SMALL:
4661 case RPC_FC_USMALL:
4662 pStubMsg->BufferLength += sizeof(UCHAR);
4663 break;
4664 case RPC_FC_WCHAR:
4665 case RPC_FC_SHORT:
4666 case RPC_FC_USHORT:
4667 case RPC_FC_ENUM16:
4668 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4669 pStubMsg->BufferLength += sizeof(USHORT);
4670 break;
4671 case RPC_FC_LONG:
4672 case RPC_FC_ULONG:
4673 case RPC_FC_ENUM32:
4674 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4675 pStubMsg->BufferLength += sizeof(ULONG);
4676 break;
4677 case RPC_FC_FLOAT:
4678 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4679 pStubMsg->BufferLength += sizeof(float);
4680 break;
4681 case RPC_FC_DOUBLE:
4682 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4683 pStubMsg->BufferLength += sizeof(double);
4684 break;
4685 case RPC_FC_HYPER:
4686 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4687 pStubMsg->BufferLength += sizeof(ULONGLONG);
4688 break;
4689 case RPC_FC_ERROR_STATUS_T:
4690 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4691 pStubMsg->BufferLength += sizeof(error_status_t);
4692 break;
4693 default:
4694 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4698 /***********************************************************************
4699 * NdrBaseTypeMemorySize [internal]
4701 static ULONG WINAPI NdrBaseTypeMemorySize(
4702 PMIDL_STUB_MESSAGE pStubMsg,
4703 PFORMAT_STRING pFormat)
4705 switch(*pFormat)
4707 case RPC_FC_BYTE:
4708 case RPC_FC_CHAR:
4709 case RPC_FC_SMALL:
4710 case RPC_FC_USMALL:
4711 pStubMsg->Buffer += sizeof(UCHAR);
4712 pStubMsg->MemorySize += sizeof(UCHAR);
4713 return sizeof(UCHAR);
4714 case RPC_FC_WCHAR:
4715 case RPC_FC_SHORT:
4716 case RPC_FC_USHORT:
4717 pStubMsg->Buffer += sizeof(USHORT);
4718 pStubMsg->MemorySize += sizeof(USHORT);
4719 return sizeof(USHORT);
4720 case RPC_FC_LONG:
4721 case RPC_FC_ULONG:
4722 pStubMsg->Buffer += sizeof(ULONG);
4723 pStubMsg->MemorySize += sizeof(ULONG);
4724 return sizeof(ULONG);
4725 case RPC_FC_FLOAT:
4726 pStubMsg->Buffer += sizeof(float);
4727 pStubMsg->MemorySize += sizeof(float);
4728 return sizeof(float);
4729 case RPC_FC_DOUBLE:
4730 pStubMsg->Buffer += sizeof(double);
4731 pStubMsg->MemorySize += sizeof(double);
4732 return sizeof(double);
4733 case RPC_FC_HYPER:
4734 pStubMsg->Buffer += sizeof(ULONGLONG);
4735 pStubMsg->MemorySize += sizeof(ULONGLONG);
4736 return sizeof(ULONGLONG);
4737 case RPC_FC_ERROR_STATUS_T:
4738 pStubMsg->Buffer += sizeof(error_status_t);
4739 pStubMsg->MemorySize += sizeof(error_status_t);
4740 return sizeof(error_status_t);
4741 case RPC_FC_ENUM16:
4742 case RPC_FC_ENUM32:
4743 pStubMsg->Buffer += sizeof(INT);
4744 pStubMsg->MemorySize += sizeof(INT);
4745 return sizeof(INT);
4746 default:
4747 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4748 return 0;
4752 /***********************************************************************
4753 * NdrBaseTypeFree [internal]
4755 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4756 unsigned char *pMemory,
4757 PFORMAT_STRING pFormat)
4759 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4761 /* nothing to do */
4764 /***********************************************************************
4765 * NdrClientContextMarshall [RPCRT4.@]
4767 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4768 NDR_CCONTEXT ContextHandle,
4769 int fCheck)
4771 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
4773 ALIGN_POINTER(pStubMsg->Buffer, 4);
4775 /* FIXME: what does fCheck do? */
4776 NDRCContextMarshall(ContextHandle,
4777 pStubMsg->Buffer);
4779 pStubMsg->Buffer += cbNDRContext;
4782 /***********************************************************************
4783 * NdrClientContextUnmarshall [RPCRT4.@]
4785 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4786 NDR_CCONTEXT * pContextHandle,
4787 RPC_BINDING_HANDLE BindHandle)
4789 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
4791 ALIGN_POINTER(pStubMsg->Buffer, 4);
4793 NDRCContextUnmarshall(pContextHandle,
4794 BindHandle,
4795 pStubMsg->Buffer,
4796 pStubMsg->RpcMsg->DataRepresentation);
4798 pStubMsg->Buffer += cbNDRContext;
4801 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4802 NDR_SCONTEXT ContextHandle,
4803 NDR_RUNDOWN RundownRoutine )
4805 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4808 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4810 FIXME("(%p): stub\n", pStubMsg);
4811 return NULL;
4814 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4815 unsigned char* pMemory,
4816 PFORMAT_STRING pFormat)
4818 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
4821 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
4822 PFORMAT_STRING pFormat)
4824 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4825 return NULL;
4828 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4829 NDR_SCONTEXT ContextHandle,
4830 NDR_RUNDOWN RundownRoutine,
4831 PFORMAT_STRING pFormat)
4833 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
4836 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4837 PFORMAT_STRING pFormat)
4839 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4840 return NULL;
4843 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
4845 typedef struct ndr_context_handle
4847 DWORD attributes;
4848 GUID uuid;
4849 } ndr_context_handle;
4851 struct context_handle_entry
4853 struct list entry;
4854 DWORD magic;
4855 RPC_BINDING_HANDLE handle;
4856 ndr_context_handle wire_data;
4859 static struct list context_handle_list = LIST_INIT(context_handle_list);
4861 static CRITICAL_SECTION ndr_context_cs;
4862 static CRITICAL_SECTION_DEBUG ndr_context_debug =
4864 0, 0, &ndr_context_cs,
4865 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
4866 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
4868 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
4870 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
4872 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
4874 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
4875 return NULL;
4876 return che;
4879 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
4881 struct context_handle_entry *che;
4882 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
4883 if (IsEqualGUID(&che->wire_data.uuid, uuid))
4884 return che;
4885 return NULL;
4888 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
4890 struct context_handle_entry *che;
4891 RPC_BINDING_HANDLE handle = NULL;
4893 TRACE("%p\n", CContext);
4895 EnterCriticalSection(&ndr_context_cs);
4896 che = get_context_entry(CContext);
4897 if (che)
4898 handle = che->handle;
4899 LeaveCriticalSection(&ndr_context_cs);
4901 if (!handle)
4902 RpcRaiseException(ERROR_INVALID_HANDLE);
4903 return handle;
4906 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
4908 struct context_handle_entry *che;
4910 TRACE("%p %p\n", CContext, pBuff);
4912 if (CContext)
4914 EnterCriticalSection(&ndr_context_cs);
4915 che = get_context_entry(CContext);
4916 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
4917 LeaveCriticalSection(&ndr_context_cs);
4919 else
4921 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
4922 wire_data->attributes = 0;
4923 wire_data->uuid = GUID_NULL;
4927 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
4928 RPC_BINDING_HANDLE hBinding,
4929 ndr_context_handle *chi)
4931 struct context_handle_entry *che = NULL;
4933 /* a null UUID means we should free the context handle */
4934 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
4936 if (*CContext)
4938 che = get_context_entry(*CContext);
4939 if (!che)
4940 return ERROR_INVALID_HANDLE;
4941 list_remove(&che->entry);
4942 RpcBindingFree(&che->handle);
4943 HeapFree(GetProcessHeap(), 0, che);
4944 che = NULL;
4947 /* if there's no existing entry matching the GUID, allocate one */
4948 else if (!(che = context_entry_from_guid(&chi->uuid)))
4950 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
4951 if (!che)
4952 return ERROR_NOT_ENOUGH_MEMORY;
4953 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
4954 RpcBindingCopy(hBinding, &che->handle);
4955 list_add_tail(&context_handle_list, &che->entry);
4956 memcpy(&che->wire_data, chi, sizeof *chi);
4959 *CContext = che;
4961 return ERROR_SUCCESS;
4964 /***********************************************************************
4965 * NDRCContextUnmarshall [RPCRT4.@]
4967 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
4968 RPC_BINDING_HANDLE hBinding,
4969 void *pBuff, ULONG DataRepresentation)
4971 UINT r;
4973 TRACE("*%p=(%p) %p %p %08x\n",
4974 CContext, *CContext, hBinding, pBuff, DataRepresentation);
4976 EnterCriticalSection(&ndr_context_cs);
4977 r = ndr_update_context_handle(CContext, hBinding, pBuff);
4978 LeaveCriticalSection(&ndr_context_cs);
4979 if (r)
4980 RpcRaiseException(r);
4983 /***********************************************************************
4984 * NDRSContextMarshall [RPCRT4.@]
4986 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
4987 void *pBuff,
4988 NDR_RUNDOWN userRunDownIn)
4990 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
4993 /***********************************************************************
4994 * NDRSContextMarshallEx [RPCRT4.@]
4996 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
4997 NDR_SCONTEXT CContext,
4998 void *pBuff,
4999 NDR_RUNDOWN userRunDownIn)
5001 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
5004 /***********************************************************************
5005 * NDRSContextMarshall2 [RPCRT4.@]
5007 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
5008 NDR_SCONTEXT CContext,
5009 void *pBuff,
5010 NDR_RUNDOWN userRunDownIn,
5011 void *CtxGuard, ULONG Flags)
5013 FIXME("(%p %p %p %p %p %u): stub\n",
5014 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5017 /***********************************************************************
5018 * NDRSContextUnmarshall [RPCRT4.@]
5020 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5021 ULONG DataRepresentation)
5023 FIXME("(%p %08x): stub\n", pBuff, DataRepresentation);
5024 return NULL;
5027 /***********************************************************************
5028 * NDRSContextUnmarshallEx [RPCRT4.@]
5030 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5031 void *pBuff,
5032 ULONG DataRepresentation)
5034 FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation);
5035 return NULL;
5038 /***********************************************************************
5039 * NDRSContextUnmarshall2 [RPCRT4.@]
5041 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5042 void *pBuff,
5043 ULONG DataRepresentation,
5044 void *CtxGuard, ULONG Flags)
5046 FIXME("(%p %p %08x %p %u): stub\n",
5047 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
5048 return NULL;