comctl32: Add missing '\n' to ok() call.
[wine/dibdrv.git] / dlls / rpcrt4 / ndr_marshall.c
blob7c71b3ee8e2ecb345ede392270cbc784347577a5
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/%ld\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 unsigned long 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 %ld\n", pStubMsg->Offset);
348 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
349 pStubMsg->Buffer += 4;
350 TRACE("variance is %ld\n", pStubMsg->ActualCount);
352 if ((pStubMsg->ActualCount > MaxValue) ||
353 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
355 ERR("invalid array bound(s): ActualCount = %ld, Offset = %ld, MaxValue = %ld\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 *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=%ld\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 %ld\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 unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
649 PFORMAT_STRING pFormat )
651 unsigned long 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(" --> %lu\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 %ld\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 %ld, 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 unsigned long 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
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 unsigned long 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 = (unsigned long)Pointer;
829 TRACE("writing 0x%08lx 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%08lx 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
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%08lx\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%08lx\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%08lx\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
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 unsigned long 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 [RPCRT4.@]
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 [RPCRT4.@]
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
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
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 unsigned long 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 unsigned long 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=%ld <= %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=%ld => %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 unsigned long 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 unsigned long 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 unsigned long 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 = %ld\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 = %ld\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 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2670 PFORMAT_STRING pFormat)
2672 ULONG i, count, esize;
2673 unsigned char alignment;
2674 unsigned char *Buffer;
2675 unsigned long SavedMemorySize;
2676 unsigned long MemorySize;
2678 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2680 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2682 ERR("invalid format type %x\n", pFormat[0]);
2683 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2684 return 0;
2687 alignment = pFormat[1] + 1;
2689 pFormat += 4;
2691 pFormat = ReadConformance(pStubMsg, pFormat);
2692 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2694 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2696 SavedMemorySize = pStubMsg->MemorySize;
2698 Buffer = pStubMsg->Buffer;
2699 pStubMsg->MemorySize = 0;
2700 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2701 pStubMsg->Buffer = Buffer;
2703 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
2705 count = pStubMsg->ActualCount;
2706 for (i = 0; i < count; i++)
2707 ComplexStructMemorySize(pStubMsg, pFormat);
2709 pStubMsg->MemorySize = SavedMemorySize;
2711 pStubMsg->MemorySize += MemorySize;
2712 return MemorySize;
2715 /***********************************************************************
2716 * NdrComplexArrayFree [RPCRT4.@]
2718 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2719 unsigned char *pMemory,
2720 PFORMAT_STRING pFormat)
2722 ULONG i, count, def;
2724 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2726 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2728 ERR("invalid format type %x\n", pFormat[0]);
2729 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2730 return;
2733 def = *(const WORD*)&pFormat[2];
2734 pFormat += 4;
2736 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2737 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2739 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2740 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2742 count = pStubMsg->ActualCount;
2743 for (i = 0; i < count; i++)
2744 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2747 static unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2749 return MAKELONG(pStubMsg->dwDestContext,
2750 pStubMsg->RpcMsg->DataRepresentation);
2753 #define USER_MARSHAL_PTR_PREFIX \
2754 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2755 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2757 /***********************************************************************
2758 * NdrUserMarshalMarshall [RPCRT4.@]
2760 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2761 unsigned char *pMemory,
2762 PFORMAT_STRING pFormat)
2764 unsigned flags = pFormat[1];
2765 unsigned index = *(const WORD*)&pFormat[2];
2766 unsigned long uflag = UserMarshalFlags(pStubMsg);
2767 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2768 TRACE("index=%d\n", index);
2770 if (flags & USER_MARSHAL_POINTER)
2772 ALIGN_POINTER(pStubMsg->Buffer, 4);
2773 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2774 pStubMsg->Buffer += 4;
2775 ALIGN_POINTER(pStubMsg->Buffer, 8);
2777 else
2778 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2780 pStubMsg->Buffer =
2781 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2782 &uflag, pStubMsg->Buffer, pMemory);
2784 STD_OVERFLOW_CHECK(pStubMsg);
2786 return NULL;
2789 /***********************************************************************
2790 * NdrUserMarshalUnmarshall [RPCRT4.@]
2792 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2793 unsigned char **ppMemory,
2794 PFORMAT_STRING pFormat,
2795 unsigned char fMustAlloc)
2797 unsigned flags = pFormat[1];
2798 unsigned index = *(const WORD*)&pFormat[2];
2799 DWORD memsize = *(const WORD*)&pFormat[4];
2800 unsigned long uflag = UserMarshalFlags(pStubMsg);
2801 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2802 TRACE("index=%d\n", index);
2804 if (flags & USER_MARSHAL_POINTER)
2806 ALIGN_POINTER(pStubMsg->Buffer, 4);
2807 /* skip pointer prefix */
2808 pStubMsg->Buffer += 4;
2809 ALIGN_POINTER(pStubMsg->Buffer, 8);
2811 else
2812 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2814 if (fMustAlloc || !*ppMemory)
2815 *ppMemory = NdrAllocate(pStubMsg, memsize);
2817 pStubMsg->Buffer =
2818 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2819 &uflag, pStubMsg->Buffer, *ppMemory);
2821 return NULL;
2824 /***********************************************************************
2825 * NdrUserMarshalBufferSize [RPCRT4.@]
2827 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2828 unsigned char *pMemory,
2829 PFORMAT_STRING pFormat)
2831 unsigned flags = pFormat[1];
2832 unsigned index = *(const WORD*)&pFormat[2];
2833 DWORD bufsize = *(const WORD*)&pFormat[6];
2834 unsigned long uflag = UserMarshalFlags(pStubMsg);
2835 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2836 TRACE("index=%d\n", index);
2838 if (flags & USER_MARSHAL_POINTER)
2840 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2841 /* skip pointer prefix */
2842 pStubMsg->BufferLength += 4;
2843 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2845 else
2846 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2848 if (bufsize) {
2849 TRACE("size=%ld\n", bufsize);
2850 pStubMsg->BufferLength += bufsize;
2851 return;
2854 pStubMsg->BufferLength =
2855 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2856 &uflag, pStubMsg->BufferLength, pMemory);
2859 /***********************************************************************
2860 * NdrUserMarshalMemorySize [RPCRT4.@]
2862 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2863 PFORMAT_STRING pFormat)
2865 unsigned flags = pFormat[1];
2866 unsigned index = *(const WORD*)&pFormat[2];
2867 DWORD memsize = *(const WORD*)&pFormat[4];
2868 DWORD bufsize = *(const WORD*)&pFormat[6];
2870 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2871 TRACE("index=%d\n", index);
2873 pStubMsg->MemorySize += memsize;
2875 if (flags & USER_MARSHAL_POINTER)
2877 ALIGN_POINTER(pStubMsg->Buffer, 4);
2878 /* skip pointer prefix */
2879 pStubMsg->Buffer += 4;
2880 ALIGN_POINTER(pStubMsg->Buffer, 8);
2882 else
2883 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2885 pStubMsg->Buffer += bufsize;
2887 return pStubMsg->MemorySize;
2890 /***********************************************************************
2891 * NdrUserMarshalFree [RPCRT4.@]
2893 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2894 unsigned char *pMemory,
2895 PFORMAT_STRING pFormat)
2897 /* unsigned flags = pFormat[1]; */
2898 unsigned index = *(const WORD*)&pFormat[2];
2899 unsigned long uflag = UserMarshalFlags(pStubMsg);
2900 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2901 TRACE("index=%d\n", index);
2903 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2904 &uflag, pMemory);
2907 /***********************************************************************
2908 * NdrClearOutParameters [RPCRT4.@]
2910 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2911 PFORMAT_STRING pFormat,
2912 void *ArgAddr)
2914 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2917 /***********************************************************************
2918 * NdrConvert [RPCRT4.@]
2920 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2922 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2923 /* FIXME: since this stub doesn't do any converting, the proper behavior
2924 is to raise an exception */
2927 /***********************************************************************
2928 * NdrConvert2 [RPCRT4.@]
2930 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2932 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2933 pStubMsg, pFormat, NumberParams);
2934 /* FIXME: since this stub doesn't do any converting, the proper behavior
2935 is to raise an exception */
2938 typedef struct _NDR_CSTRUCT_FORMAT
2940 unsigned char type;
2941 unsigned char alignment;
2942 unsigned short memory_size;
2943 short offset_to_array_description;
2944 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2946 /***********************************************************************
2947 * NdrConformantStructMarshall [RPCRT4.@]
2949 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2950 unsigned char *pMemory,
2951 PFORMAT_STRING pFormat)
2953 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
2954 PFORMAT_STRING pCArrayFormat;
2955 ULONG esize, bufsize;
2957 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2959 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2960 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2962 ERR("invalid format type %x\n", pCStructFormat->type);
2963 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2964 return NULL;
2967 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
2968 pCStructFormat->offset_to_array_description;
2969 if (*pCArrayFormat != RPC_FC_CARRAY)
2971 ERR("invalid array format type %x\n", pCStructFormat->type);
2972 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2973 return NULL;
2975 esize = *(const WORD*)(pCArrayFormat+2);
2977 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2978 pCArrayFormat + 4, 0);
2980 WriteConformance(pStubMsg);
2982 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2984 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2986 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
2987 /* copy constant sized part of struct */
2988 pStubMsg->BufferMark = pStubMsg->Buffer;
2989 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
2990 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
2992 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2993 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2995 STD_OVERFLOW_CHECK(pStubMsg);
2997 return NULL;
3000 /***********************************************************************
3001 * NdrConformantStructUnmarshall [RPCRT4.@]
3003 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3004 unsigned char **ppMemory,
3005 PFORMAT_STRING pFormat,
3006 unsigned char fMustAlloc)
3008 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3009 PFORMAT_STRING pCArrayFormat;
3010 ULONG esize, bufsize;
3012 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3014 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3015 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3017 ERR("invalid format type %x\n", pCStructFormat->type);
3018 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3019 return NULL;
3021 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3022 pCStructFormat->offset_to_array_description;
3023 if (*pCArrayFormat != RPC_FC_CARRAY)
3025 ERR("invalid array format type %x\n", pCStructFormat->type);
3026 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3027 return NULL;
3029 esize = *(const WORD*)(pCArrayFormat+2);
3031 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3033 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3035 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3037 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3038 /* work out how much memory to allocate if we need to do so */
3039 if (!*ppMemory || fMustAlloc)
3041 SIZE_T size = pCStructFormat->memory_size + bufsize;
3042 *ppMemory = NdrAllocate(pStubMsg, size);
3045 /* now copy the data */
3046 pStubMsg->BufferMark = pStubMsg->Buffer;
3047 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
3048 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3050 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3051 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3053 return NULL;
3056 /***********************************************************************
3057 * NdrConformantStructBufferSize [RPCRT4.@]
3059 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3060 unsigned char *pMemory,
3061 PFORMAT_STRING pFormat)
3063 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3064 PFORMAT_STRING pCArrayFormat;
3065 ULONG esize;
3067 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3069 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3070 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3072 ERR("invalid format type %x\n", pCStructFormat->type);
3073 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3074 return;
3076 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3077 pCStructFormat->offset_to_array_description;
3078 if (*pCArrayFormat != RPC_FC_CARRAY)
3080 ERR("invalid array format type %x\n", pCStructFormat->type);
3081 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3082 return;
3084 esize = *(const WORD*)(pCArrayFormat+2);
3086 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3087 SizeConformance(pStubMsg);
3089 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3091 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3093 pStubMsg->BufferLength += pCStructFormat->memory_size +
3094 safe_multiply(pStubMsg->MaxCount, esize);
3096 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3097 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3100 /***********************************************************************
3101 * NdrConformantStructMemorySize [RPCRT4.@]
3103 unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3104 PFORMAT_STRING pFormat)
3106 FIXME("stub\n");
3107 return 0;
3110 /***********************************************************************
3111 * NdrConformantStructFree [RPCRT4.@]
3113 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3114 unsigned char *pMemory,
3115 PFORMAT_STRING pFormat)
3117 FIXME("stub\n");
3120 /***********************************************************************
3121 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3123 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3124 unsigned char *pMemory,
3125 PFORMAT_STRING pFormat)
3127 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3128 PFORMAT_STRING pCVArrayFormat;
3129 ULONG esize, bufsize;
3131 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3133 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3134 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3136 ERR("invalid format type %x\n", pCVStructFormat->type);
3137 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3138 return NULL;
3141 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3142 pCVStructFormat->offset_to_array_description;
3143 switch (*pCVArrayFormat)
3145 case RPC_FC_CVARRAY:
3146 esize = *(const WORD*)(pCVArrayFormat+2);
3148 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3149 pCVArrayFormat + 4, 0);
3150 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3151 pCVArrayFormat, 0);
3152 break;
3153 case RPC_FC_C_CSTRING:
3154 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3155 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3156 esize = sizeof(char);
3157 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3158 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3159 pCVArrayFormat + 2, 0);
3160 else
3161 pStubMsg->MaxCount = pStubMsg->ActualCount;
3162 break;
3163 case RPC_FC_C_WSTRING:
3164 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3165 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3166 esize = sizeof(WCHAR);
3167 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3168 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3169 pCVArrayFormat + 2, 0);
3170 else
3171 pStubMsg->MaxCount = pStubMsg->ActualCount;
3172 break;
3173 default:
3174 ERR("invalid array format type %x\n", *pCVArrayFormat);
3175 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3176 return NULL;
3179 WriteConformance(pStubMsg);
3181 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3183 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3185 /* write constant sized part */
3186 pStubMsg->BufferMark = pStubMsg->Buffer;
3187 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3188 pStubMsg->Buffer += pCVStructFormat->memory_size;
3190 WriteVariance(pStubMsg);
3192 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3194 /* write array part */
3195 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3196 pStubMsg->Buffer += bufsize;
3198 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3200 STD_OVERFLOW_CHECK(pStubMsg);
3202 return NULL;
3205 /***********************************************************************
3206 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3208 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3209 unsigned char **ppMemory,
3210 PFORMAT_STRING pFormat,
3211 unsigned char fMustAlloc)
3213 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3214 PFORMAT_STRING pCVArrayFormat;
3215 ULONG esize, bufsize;
3216 unsigned char cvarray_type;
3218 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3220 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3221 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3223 ERR("invalid format type %x\n", pCVStructFormat->type);
3224 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3225 return NULL;
3228 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3229 pCVStructFormat->offset_to_array_description;
3230 cvarray_type = *pCVArrayFormat;
3231 switch (cvarray_type)
3233 case RPC_FC_CVARRAY:
3234 esize = *(const WORD*)(pCVArrayFormat+2);
3235 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3236 break;
3237 case RPC_FC_C_CSTRING:
3238 esize = sizeof(char);
3239 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3240 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3241 else
3242 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3243 break;
3244 case RPC_FC_C_WSTRING:
3245 esize = sizeof(WCHAR);
3246 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3247 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3248 else
3249 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3250 break;
3251 default:
3252 ERR("invalid array format type %x\n", *pCVArrayFormat);
3253 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3254 return NULL;
3257 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3259 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3261 /* work out how much memory to allocate if we need to do so */
3262 if (!*ppMemory || fMustAlloc)
3264 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3265 *ppMemory = NdrAllocate(pStubMsg, size);
3268 /* copy the constant data */
3269 pStubMsg->BufferMark = pStubMsg->Buffer;
3270 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3271 pStubMsg->Buffer += pCVStructFormat->memory_size;
3273 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3275 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3277 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3278 (cvarray_type == RPC_FC_C_WSTRING))
3280 ULONG i;
3281 /* strings must always have null terminating bytes */
3282 if (bufsize < esize)
3284 ERR("invalid string length of %ld\n", pStubMsg->ActualCount);
3285 RpcRaiseException(RPC_S_INVALID_BOUND);
3286 return NULL;
3288 for (i = bufsize - esize; i < bufsize; i++)
3289 if (pStubMsg->Buffer[i] != 0)
3291 ERR("string not null-terminated at byte position %ld, data is 0x%x\n",
3292 i, pStubMsg->Buffer[i]);
3293 RpcRaiseException(RPC_S_INVALID_BOUND);
3294 return NULL;
3298 /* copy the array data */
3299 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3300 bufsize);
3301 pStubMsg->Buffer += bufsize;
3303 if (cvarray_type == RPC_FC_C_CSTRING)
3304 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3305 else if (cvarray_type == RPC_FC_C_WSTRING)
3306 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3308 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3310 return NULL;
3313 /***********************************************************************
3314 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3316 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3317 unsigned char *pMemory,
3318 PFORMAT_STRING pFormat)
3320 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3321 PFORMAT_STRING pCVArrayFormat;
3322 ULONG esize;
3324 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3326 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3327 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3329 ERR("invalid format type %x\n", pCVStructFormat->type);
3330 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3331 return;
3334 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3335 pCVStructFormat->offset_to_array_description;
3336 switch (*pCVArrayFormat)
3338 case RPC_FC_CVARRAY:
3339 esize = *(const WORD*)(pCVArrayFormat+2);
3341 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3342 pCVArrayFormat + 4, 0);
3343 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3344 pCVArrayFormat, 0);
3345 break;
3346 case RPC_FC_C_CSTRING:
3347 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3348 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3349 esize = sizeof(char);
3350 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3351 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3352 pCVArrayFormat + 2, 0);
3353 else
3354 pStubMsg->MaxCount = pStubMsg->ActualCount;
3355 break;
3356 case RPC_FC_C_WSTRING:
3357 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3358 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3359 esize = sizeof(WCHAR);
3360 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3361 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3362 pCVArrayFormat + 2, 0);
3363 else
3364 pStubMsg->MaxCount = pStubMsg->ActualCount;
3365 break;
3366 default:
3367 ERR("invalid array format type %x\n", *pCVArrayFormat);
3368 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3369 return;
3372 SizeConformance(pStubMsg);
3374 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3376 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3378 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3379 SizeVariance(pStubMsg);
3380 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3382 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3385 /***********************************************************************
3386 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3388 unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3389 PFORMAT_STRING pFormat)
3391 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3392 PFORMAT_STRING pCVArrayFormat;
3393 ULONG esize;
3394 unsigned char cvarray_type;
3396 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3398 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3399 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3401 ERR("invalid format type %x\n", pCVStructFormat->type);
3402 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3403 return 0;
3406 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3407 pCVStructFormat->offset_to_array_description;
3408 cvarray_type = *pCVArrayFormat;
3409 switch (cvarray_type)
3411 case RPC_FC_CVARRAY:
3412 esize = *(const WORD*)(pCVArrayFormat+2);
3413 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3414 break;
3415 case RPC_FC_C_CSTRING:
3416 esize = sizeof(char);
3417 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3418 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3419 else
3420 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3421 break;
3422 case RPC_FC_C_WSTRING:
3423 esize = sizeof(WCHAR);
3424 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3425 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3426 else
3427 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3428 break;
3429 default:
3430 ERR("invalid array format type %x\n", *pCVArrayFormat);
3431 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3432 return 0;
3435 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3437 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3439 pStubMsg->Buffer += pCVStructFormat->memory_size;
3440 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3441 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3443 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3445 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3447 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3450 /***********************************************************************
3451 * NdrConformantVaryingStructFree [RPCRT4.@]
3453 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3454 unsigned char *pMemory,
3455 PFORMAT_STRING pFormat)
3457 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
3458 PFORMAT_STRING pCVArrayFormat;
3459 ULONG esize;
3461 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3463 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3464 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3466 ERR("invalid format type %x\n", pCVStructFormat->type);
3467 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3468 return;
3471 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
3472 pCVStructFormat->offset_to_array_description;
3473 switch (*pCVArrayFormat)
3475 case RPC_FC_CVARRAY:
3476 esize = *(const WORD*)(pCVArrayFormat+2);
3478 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3479 pCVArrayFormat + 4, 0);
3480 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3481 pCVArrayFormat, 0);
3482 break;
3483 case RPC_FC_C_CSTRING:
3484 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3485 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3486 esize = sizeof(char);
3487 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3488 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3489 pCVArrayFormat + 2, 0);
3490 else
3491 pStubMsg->MaxCount = pStubMsg->ActualCount;
3492 break;
3493 case RPC_FC_C_WSTRING:
3494 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3495 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3496 esize = sizeof(WCHAR);
3497 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3498 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3499 pCVArrayFormat + 2, 0);
3500 else
3501 pStubMsg->MaxCount = pStubMsg->ActualCount;
3502 break;
3503 default:
3504 ERR("invalid array format type %x\n", *pCVArrayFormat);
3505 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3506 return;
3509 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3511 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3514 typedef struct
3516 unsigned char type;
3517 unsigned char alignment;
3518 unsigned short total_size;
3519 } NDR_SMFARRAY_FORMAT;
3521 typedef struct
3523 unsigned char type;
3524 unsigned char alignment;
3525 unsigned long total_size;
3526 } NDR_LGFARRAY_FORMAT;
3528 /***********************************************************************
3529 * NdrFixedArrayMarshall [RPCRT4.@]
3531 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3532 unsigned char *pMemory,
3533 PFORMAT_STRING pFormat)
3535 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3536 unsigned long total_size;
3538 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3540 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3541 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3543 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3544 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3545 return NULL;
3548 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3550 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3552 total_size = pSmFArrayFormat->total_size;
3553 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3555 else
3557 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3558 total_size = pLgFArrayFormat->total_size;
3559 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3562 memcpy(pStubMsg->Buffer, pMemory, total_size);
3563 pStubMsg->BufferMark = pStubMsg->Buffer;
3564 pStubMsg->Buffer += total_size;
3566 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3568 return NULL;
3571 /***********************************************************************
3572 * NdrFixedArrayUnmarshall [RPCRT4.@]
3574 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3575 unsigned char **ppMemory,
3576 PFORMAT_STRING pFormat,
3577 unsigned char fMustAlloc)
3579 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3580 unsigned long total_size;
3582 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3584 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3585 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3587 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3588 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3589 return NULL;
3592 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3594 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3596 total_size = pSmFArrayFormat->total_size;
3597 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3599 else
3601 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3602 total_size = pLgFArrayFormat->total_size;
3603 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3606 if (fMustAlloc || !*ppMemory)
3607 *ppMemory = NdrAllocate(pStubMsg, total_size);
3608 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3609 pStubMsg->BufferMark = pStubMsg->Buffer;
3610 pStubMsg->Buffer += total_size;
3612 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3614 return NULL;
3617 /***********************************************************************
3618 * NdrFixedArrayBufferSize [RPCRT4.@]
3620 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3621 unsigned char *pMemory,
3622 PFORMAT_STRING pFormat)
3624 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3625 unsigned long total_size;
3627 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3629 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3630 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3632 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3633 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3634 return;
3637 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3639 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3641 total_size = pSmFArrayFormat->total_size;
3642 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3644 else
3646 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3647 total_size = pLgFArrayFormat->total_size;
3648 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3650 pStubMsg->BufferLength += total_size;
3652 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3655 /***********************************************************************
3656 * NdrFixedArrayMemorySize [RPCRT4.@]
3658 unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3659 PFORMAT_STRING pFormat)
3661 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3662 unsigned long total_size;
3664 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3666 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3667 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3669 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3670 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3671 return 0;
3674 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3676 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3678 total_size = pSmFArrayFormat->total_size;
3679 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3681 else
3683 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3684 total_size = pLgFArrayFormat->total_size;
3685 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3687 pStubMsg->BufferMark = pStubMsg->Buffer;
3688 pStubMsg->Buffer += total_size;
3689 pStubMsg->MemorySize += total_size;
3691 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3693 return total_size;
3696 /***********************************************************************
3697 * NdrFixedArrayFree [RPCRT4.@]
3699 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3700 unsigned char *pMemory,
3701 PFORMAT_STRING pFormat)
3703 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3705 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3707 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3708 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3710 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3711 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3712 return;
3715 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3716 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
3717 else
3719 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3720 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
3723 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3726 /***********************************************************************
3727 * NdrVaryingArrayMarshall [RPCRT4.@]
3729 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3730 unsigned char *pMemory,
3731 PFORMAT_STRING pFormat)
3733 unsigned char alignment;
3734 DWORD elements, esize;
3735 ULONG bufsize;
3737 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3739 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3740 (pFormat[0] != RPC_FC_LGVARRAY))
3742 ERR("invalid format type %x\n", pFormat[0]);
3743 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3744 return NULL;
3747 alignment = pFormat[1] + 1;
3749 if (pFormat[0] == RPC_FC_SMVARRAY)
3751 pFormat += 2;
3752 pFormat += sizeof(WORD);
3753 elements = *(const WORD*)pFormat;
3754 pFormat += sizeof(WORD);
3756 else
3758 pFormat += 2;
3759 pFormat += sizeof(DWORD);
3760 elements = *(const DWORD*)pFormat;
3761 pFormat += sizeof(DWORD);
3764 esize = *(const WORD*)pFormat;
3765 pFormat += sizeof(WORD);
3767 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3768 if ((pStubMsg->ActualCount > elements) ||
3769 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3771 RpcRaiseException(RPC_S_INVALID_BOUND);
3772 return NULL;
3775 WriteVariance(pStubMsg);
3777 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3779 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3780 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
3781 pStubMsg->BufferMark = pStubMsg->Buffer;
3782 pStubMsg->Buffer += bufsize;
3784 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3786 STD_OVERFLOW_CHECK(pStubMsg);
3788 return NULL;
3791 /***********************************************************************
3792 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3794 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3795 unsigned char **ppMemory,
3796 PFORMAT_STRING pFormat,
3797 unsigned char fMustAlloc)
3799 unsigned char alignment;
3800 DWORD size, elements, esize;
3801 ULONG bufsize;
3803 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3805 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3806 (pFormat[0] != RPC_FC_LGVARRAY))
3808 ERR("invalid format type %x\n", pFormat[0]);
3809 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3810 return NULL;
3813 alignment = pFormat[1] + 1;
3815 if (pFormat[0] == RPC_FC_SMVARRAY)
3817 pFormat += 2;
3818 size = *(const WORD*)pFormat;
3819 pFormat += sizeof(WORD);
3820 elements = *(const WORD*)pFormat;
3821 pFormat += sizeof(WORD);
3823 else
3825 pFormat += 2;
3826 size = *(const DWORD*)pFormat;
3827 pFormat += sizeof(DWORD);
3828 elements = *(const DWORD*)pFormat;
3829 pFormat += sizeof(DWORD);
3832 esize = *(const WORD*)pFormat;
3833 pFormat += sizeof(WORD);
3835 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3837 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3839 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3841 if (!*ppMemory || fMustAlloc)
3842 *ppMemory = NdrAllocate(pStubMsg, size);
3843 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
3844 pStubMsg->Buffer += bufsize;
3846 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3848 return NULL;
3851 /***********************************************************************
3852 * NdrVaryingArrayBufferSize [RPCRT4.@]
3854 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3855 unsigned char *pMemory,
3856 PFORMAT_STRING pFormat)
3858 unsigned char alignment;
3859 DWORD elements, esize;
3861 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3863 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3864 (pFormat[0] != RPC_FC_LGVARRAY))
3866 ERR("invalid format type %x\n", pFormat[0]);
3867 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3868 return;
3871 alignment = pFormat[1] + 1;
3873 if (pFormat[0] == RPC_FC_SMVARRAY)
3875 pFormat += 2;
3876 pFormat += sizeof(WORD);
3877 elements = *(const WORD*)pFormat;
3878 pFormat += sizeof(WORD);
3880 else
3882 pFormat += 2;
3883 pFormat += sizeof(DWORD);
3884 elements = *(const DWORD*)pFormat;
3885 pFormat += sizeof(DWORD);
3888 esize = *(const WORD*)pFormat;
3889 pFormat += sizeof(WORD);
3891 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3892 if ((pStubMsg->ActualCount > elements) ||
3893 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3895 RpcRaiseException(RPC_S_INVALID_BOUND);
3896 return;
3899 SizeVariance(pStubMsg);
3901 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3903 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
3905 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3908 /***********************************************************************
3909 * NdrVaryingArrayMemorySize [RPCRT4.@]
3911 unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3912 PFORMAT_STRING pFormat)
3914 unsigned char alignment;
3915 DWORD size, elements, esize;
3917 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3919 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3920 (pFormat[0] != RPC_FC_LGVARRAY))
3922 ERR("invalid format type %x\n", pFormat[0]);
3923 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3924 return 0;
3927 alignment = pFormat[1] + 1;
3929 if (pFormat[0] == RPC_FC_SMVARRAY)
3931 pFormat += 2;
3932 size = *(const WORD*)pFormat;
3933 pFormat += sizeof(WORD);
3934 elements = *(const WORD*)pFormat;
3935 pFormat += sizeof(WORD);
3937 else
3939 pFormat += 2;
3940 size = *(const DWORD*)pFormat;
3941 pFormat += sizeof(DWORD);
3942 elements = *(const DWORD*)pFormat;
3943 pFormat += sizeof(DWORD);
3946 esize = *(const WORD*)pFormat;
3947 pFormat += sizeof(WORD);
3949 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3951 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3953 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
3954 pStubMsg->MemorySize += size;
3956 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3958 return pStubMsg->MemorySize;
3961 /***********************************************************************
3962 * NdrVaryingArrayFree [RPCRT4.@]
3964 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3965 unsigned char *pMemory,
3966 PFORMAT_STRING pFormat)
3968 unsigned char alignment;
3969 DWORD elements;
3971 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3973 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3974 (pFormat[0] != RPC_FC_LGVARRAY))
3976 ERR("invalid format type %x\n", pFormat[0]);
3977 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3978 return;
3981 alignment = pFormat[1] + 1;
3983 if (pFormat[0] == RPC_FC_SMVARRAY)
3985 pFormat += 2;
3986 pFormat += sizeof(WORD);
3987 elements = *(const WORD*)pFormat;
3988 pFormat += sizeof(WORD);
3990 else
3992 pFormat += 2;
3993 pFormat += sizeof(DWORD);
3994 elements = *(const DWORD*)pFormat;
3995 pFormat += sizeof(DWORD);
3998 pFormat += sizeof(WORD);
4000 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4001 if ((pStubMsg->ActualCount > elements) ||
4002 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4004 RpcRaiseException(RPC_S_INVALID_BOUND);
4005 return;
4008 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4011 /***********************************************************************
4012 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4014 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4015 unsigned char *pMemory,
4016 PFORMAT_STRING pFormat)
4018 FIXME("stub\n");
4019 return NULL;
4022 /***********************************************************************
4023 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4025 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4026 unsigned char **ppMemory,
4027 PFORMAT_STRING pFormat,
4028 unsigned char fMustAlloc)
4030 FIXME("stub\n");
4031 return NULL;
4034 /***********************************************************************
4035 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4037 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4038 unsigned char *pMemory,
4039 PFORMAT_STRING pFormat)
4041 FIXME("stub\n");
4044 /***********************************************************************
4045 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4047 unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4048 PFORMAT_STRING pFormat)
4050 FIXME("stub\n");
4051 return 0;
4054 /***********************************************************************
4055 * NdrEncapsulatedUnionFree [RPCRT4.@]
4057 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4058 unsigned char *pMemory,
4059 PFORMAT_STRING pFormat)
4061 FIXME("stub\n");
4064 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4065 unsigned long discriminant,
4066 PFORMAT_STRING pFormat)
4068 unsigned short num_arms, arm, type;
4070 num_arms = *(const SHORT*)pFormat & 0x0fff;
4071 pFormat += 2;
4072 for(arm = 0; arm < num_arms; arm++)
4074 if(discriminant == *(const ULONG*)pFormat)
4076 pFormat += 4;
4077 break;
4079 pFormat += 6;
4082 type = *(const unsigned short*)pFormat;
4083 TRACE("type %04x\n", type);
4084 if(arm == num_arms) /* default arm extras */
4086 if(type == 0xffff)
4088 ERR("no arm for 0x%lx and no default case\n", discriminant);
4089 RpcRaiseException(RPC_S_INVALID_TAG);
4090 return NULL;
4092 if(type == 0)
4094 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4095 return NULL;
4098 return pFormat;
4101 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
4102 ULONG value,
4103 PFORMAT_STRING pFormat)
4105 pFormat += *(const SHORT*)pFormat;
4106 pFormat += 2;
4108 return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
4111 /***********************************************************************
4112 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4114 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4115 unsigned char *pMemory,
4116 PFORMAT_STRING pFormat)
4118 unsigned short type;
4119 unsigned char switch_type;
4121 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4122 pFormat++;
4124 switch_type = *pFormat;
4125 pFormat++;
4127 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4128 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4129 /* Marshall discriminant */
4130 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4132 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4133 if(!pFormat)
4134 return NULL;
4136 type = *(const unsigned short*)pFormat;
4137 if((type & 0xff00) == 0x8000)
4139 unsigned char basetype = LOBYTE(type);
4140 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4142 else
4144 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4145 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4146 if (m)
4148 unsigned char *saved_buffer = NULL;
4149 switch(*desc)
4151 case RPC_FC_RP:
4152 case RPC_FC_UP:
4153 case RPC_FC_OP:
4154 case RPC_FC_FP:
4155 saved_buffer = pStubMsg->Buffer;
4156 pStubMsg->Buffer += 4; /* for pointer ID */
4157 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4158 break;
4159 default:
4160 m(pStubMsg, pMemory, desc);
4163 else FIXME("no marshaller for embedded type %02x\n", *desc);
4165 return NULL;
4168 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4169 PFORMAT_STRING *ppFormat)
4171 long discriminant = 0;
4173 switch(**ppFormat)
4175 case RPC_FC_BYTE:
4176 case RPC_FC_CHAR:
4177 case RPC_FC_SMALL:
4178 case RPC_FC_USMALL:
4179 discriminant = *(UCHAR *)pStubMsg->Buffer;
4180 pStubMsg->Buffer += sizeof(UCHAR);
4181 break;
4182 case RPC_FC_WCHAR:
4183 case RPC_FC_SHORT:
4184 case RPC_FC_USHORT:
4185 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4186 discriminant = *(USHORT *)pStubMsg->Buffer;
4187 pStubMsg->Buffer += sizeof(USHORT);
4188 break;
4189 case RPC_FC_LONG:
4190 case RPC_FC_ULONG:
4191 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4192 discriminant = *(ULONG *)pStubMsg->Buffer;
4193 pStubMsg->Buffer += sizeof(ULONG);
4194 break;
4195 default:
4196 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4198 (*ppFormat)++;
4200 if (pStubMsg->fHasNewCorrDesc)
4201 *ppFormat += 6;
4202 else
4203 *ppFormat += 4;
4204 return discriminant;
4207 /**********************************************************************
4208 * NdrNonEncapsulatedUnionUnmarshall[RPCRT4.@]
4210 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4211 unsigned char **ppMemory,
4212 PFORMAT_STRING pFormat,
4213 unsigned char fMustAlloc)
4215 long discriminant;
4216 unsigned short type, size;
4218 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4219 pFormat++;
4221 /* Unmarshall discriminant */
4222 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4223 TRACE("unmarshalled discriminant %lx\n", discriminant);
4225 pFormat += *(const SHORT*)pFormat;
4227 size = *(const unsigned short*)pFormat;
4228 pFormat += 2;
4230 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4231 if(!pFormat)
4232 return NULL;
4234 if(!*ppMemory || fMustAlloc)
4235 *ppMemory = NdrAllocate(pStubMsg, size);
4237 type = *(const unsigned short*)pFormat;
4238 if((type & 0xff00) == 0x8000)
4240 unsigned char basetype = LOBYTE(type);
4241 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4243 else
4245 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4246 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4247 if (m)
4249 unsigned char *saved_buffer = NULL;
4250 switch(*desc)
4252 case RPC_FC_RP:
4253 case RPC_FC_UP:
4254 case RPC_FC_OP:
4255 case RPC_FC_FP:
4256 ALIGN_POINTER(pStubMsg->Buffer, 4);
4257 saved_buffer = pStubMsg->Buffer;
4258 pStubMsg->Buffer += 4; /* for pointer ID */
4259 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
4260 break;
4261 default:
4262 m(pStubMsg, ppMemory, desc, fMustAlloc);
4265 else FIXME("no marshaller for embedded type %02x\n", *desc);
4267 return NULL;
4270 /***********************************************************************
4271 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4273 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4274 unsigned char *pMemory,
4275 PFORMAT_STRING pFormat)
4277 unsigned short type;
4278 unsigned char switch_type;
4280 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4281 pFormat++;
4283 switch_type = *pFormat;
4284 pFormat++;
4286 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4287 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4288 /* Add discriminant size */
4289 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4291 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4292 if(!pFormat)
4293 return;
4295 type = *(const unsigned short*)pFormat;
4296 if((type & 0xff00) == 0x8000)
4298 unsigned char basetype = LOBYTE(type);
4299 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4301 else
4303 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4304 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4305 if (m)
4307 switch(*desc)
4309 case RPC_FC_RP:
4310 case RPC_FC_UP:
4311 case RPC_FC_OP:
4312 case RPC_FC_FP:
4313 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4314 pStubMsg->BufferLength += 4; /* for pointer ID */
4315 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4316 break;
4317 default:
4318 m(pStubMsg, pMemory, desc);
4321 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4323 return;
4326 /***********************************************************************
4327 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4329 unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4330 PFORMAT_STRING pFormat)
4332 unsigned long discriminant;
4333 unsigned short type, size;
4335 pFormat++;
4336 /* Unmarshall discriminant */
4337 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4338 TRACE("unmarshalled discriminant 0x%lx\n", discriminant);
4340 pFormat += *(const SHORT*)pFormat;
4342 size = *(const unsigned short*)pFormat;
4343 pFormat += 2;
4345 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4346 if(!pFormat)
4347 return 0;
4349 pStubMsg->Memory += size;
4351 type = *(const unsigned short*)pFormat;
4352 if((type & 0xff00) == 0x8000)
4354 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4356 else
4358 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4359 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4360 unsigned char *saved_buffer;
4361 if (m)
4363 switch(*desc)
4365 case RPC_FC_RP:
4366 case RPC_FC_UP:
4367 case RPC_FC_OP:
4368 case RPC_FC_FP:
4369 ALIGN_POINTER(pStubMsg->Buffer, 4);
4370 saved_buffer = pStubMsg->Buffer;
4371 pStubMsg->Buffer += 4;
4372 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4373 pStubMsg->MemorySize += 4;
4374 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4375 break;
4376 default:
4377 return m(pStubMsg, desc);
4380 else FIXME("no marshaller for embedded type %02x\n", *desc);
4383 TRACE("size %d\n", size);
4384 return size;
4387 /***********************************************************************
4388 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4390 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4391 unsigned char *pMemory,
4392 PFORMAT_STRING pFormat)
4394 FIXME("stub\n");
4397 /***********************************************************************
4398 * NdrByteCountPointerMarshall [RPCRT4.@]
4400 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4401 unsigned char *pMemory,
4402 PFORMAT_STRING pFormat)
4404 FIXME("stub\n");
4405 return NULL;
4408 /***********************************************************************
4409 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4411 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4412 unsigned char **ppMemory,
4413 PFORMAT_STRING pFormat,
4414 unsigned char fMustAlloc)
4416 FIXME("stub\n");
4417 return NULL;
4420 /***********************************************************************
4421 * NdrByteCountPointerBufferSize [RPCRT4.@]
4423 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4424 unsigned char *pMemory,
4425 PFORMAT_STRING pFormat)
4427 FIXME("stub\n");
4430 /***********************************************************************
4431 * NdrByteCountPointerMemorySize [RPCRT4.@]
4433 unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4434 PFORMAT_STRING pFormat)
4436 FIXME("stub\n");
4437 return 0;
4440 /***********************************************************************
4441 * NdrByteCountPointerFree [RPCRT4.@]
4443 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4444 unsigned char *pMemory,
4445 PFORMAT_STRING pFormat)
4447 FIXME("stub\n");
4450 /***********************************************************************
4451 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4453 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4454 unsigned char *pMemory,
4455 PFORMAT_STRING pFormat)
4457 FIXME("stub\n");
4458 return NULL;
4461 /***********************************************************************
4462 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4464 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4465 unsigned char **ppMemory,
4466 PFORMAT_STRING pFormat,
4467 unsigned char fMustAlloc)
4469 FIXME("stub\n");
4470 return NULL;
4473 /***********************************************************************
4474 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4476 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4477 unsigned char *pMemory,
4478 PFORMAT_STRING pFormat)
4480 FIXME("stub\n");
4483 /***********************************************************************
4484 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4486 unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4487 PFORMAT_STRING pFormat)
4489 FIXME("stub\n");
4490 return 0;
4493 /***********************************************************************
4494 * NdrXmitOrRepAsFree [RPCRT4.@]
4496 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4497 unsigned char *pMemory,
4498 PFORMAT_STRING pFormat)
4500 FIXME("stub\n");
4503 /***********************************************************************
4504 * NdrBaseTypeMarshall [internal]
4506 static unsigned char *WINAPI NdrBaseTypeMarshall(
4507 PMIDL_STUB_MESSAGE pStubMsg,
4508 unsigned char *pMemory,
4509 PFORMAT_STRING pFormat)
4511 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4513 switch(*pFormat)
4515 case RPC_FC_BYTE:
4516 case RPC_FC_CHAR:
4517 case RPC_FC_SMALL:
4518 case RPC_FC_USMALL:
4519 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4520 pStubMsg->Buffer += sizeof(UCHAR);
4521 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4522 break;
4523 case RPC_FC_WCHAR:
4524 case RPC_FC_SHORT:
4525 case RPC_FC_USHORT:
4526 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4527 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4528 pStubMsg->Buffer += sizeof(USHORT);
4529 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4530 break;
4531 case RPC_FC_LONG:
4532 case RPC_FC_ULONG:
4533 case RPC_FC_ERROR_STATUS_T:
4534 case RPC_FC_ENUM32:
4535 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4536 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4537 pStubMsg->Buffer += sizeof(ULONG);
4538 TRACE("value: 0x%08lx\n", *(ULONG *)pMemory);
4539 break;
4540 case RPC_FC_FLOAT:
4541 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4542 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4543 pStubMsg->Buffer += sizeof(float);
4544 break;
4545 case RPC_FC_DOUBLE:
4546 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4547 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4548 pStubMsg->Buffer += sizeof(double);
4549 break;
4550 case RPC_FC_HYPER:
4551 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4552 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4553 pStubMsg->Buffer += sizeof(ULONGLONG);
4554 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4555 break;
4556 case RPC_FC_ENUM16:
4557 /* only 16-bits on the wire, so do a sanity check */
4558 if (*(UINT *)pMemory > USHRT_MAX)
4559 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4560 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4561 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4562 pStubMsg->Buffer += sizeof(USHORT);
4563 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4564 break;
4565 default:
4566 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4569 STD_OVERFLOW_CHECK(pStubMsg);
4571 /* FIXME: what is the correct return value? */
4572 return NULL;
4575 /***********************************************************************
4576 * NdrBaseTypeUnmarshall [internal]
4578 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4579 PMIDL_STUB_MESSAGE pStubMsg,
4580 unsigned char **ppMemory,
4581 PFORMAT_STRING pFormat,
4582 unsigned char fMustAlloc)
4584 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4586 #define BASE_TYPE_UNMARSHALL(type) \
4587 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4588 if (fMustAlloc || !*ppMemory) \
4589 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4590 TRACE("*ppMemory: %p\n", *ppMemory); \
4591 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4592 pStubMsg->Buffer += sizeof(type);
4594 switch(*pFormat)
4596 case RPC_FC_BYTE:
4597 case RPC_FC_CHAR:
4598 case RPC_FC_SMALL:
4599 case RPC_FC_USMALL:
4600 BASE_TYPE_UNMARSHALL(UCHAR);
4601 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4602 break;
4603 case RPC_FC_WCHAR:
4604 case RPC_FC_SHORT:
4605 case RPC_FC_USHORT:
4606 BASE_TYPE_UNMARSHALL(USHORT);
4607 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4608 break;
4609 case RPC_FC_LONG:
4610 case RPC_FC_ULONG:
4611 case RPC_FC_ERROR_STATUS_T:
4612 case RPC_FC_ENUM32:
4613 BASE_TYPE_UNMARSHALL(ULONG);
4614 TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory);
4615 break;
4616 case RPC_FC_FLOAT:
4617 BASE_TYPE_UNMARSHALL(float);
4618 TRACE("value: %f\n", **(float **)ppMemory);
4619 break;
4620 case RPC_FC_DOUBLE:
4621 BASE_TYPE_UNMARSHALL(double);
4622 TRACE("value: %f\n", **(double **)ppMemory);
4623 break;
4624 case RPC_FC_HYPER:
4625 BASE_TYPE_UNMARSHALL(ULONGLONG);
4626 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4627 break;
4628 case RPC_FC_ENUM16:
4629 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4630 if (fMustAlloc || !*ppMemory)
4631 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
4632 TRACE("*ppMemory: %p\n", *ppMemory);
4633 /* 16-bits on the wire, but int in memory */
4634 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4635 pStubMsg->Buffer += sizeof(USHORT);
4636 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4637 break;
4638 default:
4639 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4641 #undef BASE_TYPE_UNMARSHALL
4643 /* FIXME: what is the correct return value? */
4645 return NULL;
4648 /***********************************************************************
4649 * NdrBaseTypeBufferSize [internal]
4651 static void WINAPI NdrBaseTypeBufferSize(
4652 PMIDL_STUB_MESSAGE pStubMsg,
4653 unsigned char *pMemory,
4654 PFORMAT_STRING pFormat)
4656 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4658 switch(*pFormat)
4660 case RPC_FC_BYTE:
4661 case RPC_FC_CHAR:
4662 case RPC_FC_SMALL:
4663 case RPC_FC_USMALL:
4664 pStubMsg->BufferLength += sizeof(UCHAR);
4665 break;
4666 case RPC_FC_WCHAR:
4667 case RPC_FC_SHORT:
4668 case RPC_FC_USHORT:
4669 case RPC_FC_ENUM16:
4670 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4671 pStubMsg->BufferLength += sizeof(USHORT);
4672 break;
4673 case RPC_FC_LONG:
4674 case RPC_FC_ULONG:
4675 case RPC_FC_ENUM32:
4676 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4677 pStubMsg->BufferLength += sizeof(ULONG);
4678 break;
4679 case RPC_FC_FLOAT:
4680 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4681 pStubMsg->BufferLength += sizeof(float);
4682 break;
4683 case RPC_FC_DOUBLE:
4684 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4685 pStubMsg->BufferLength += sizeof(double);
4686 break;
4687 case RPC_FC_HYPER:
4688 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4689 pStubMsg->BufferLength += sizeof(ULONGLONG);
4690 break;
4691 case RPC_FC_ERROR_STATUS_T:
4692 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4693 pStubMsg->BufferLength += sizeof(error_status_t);
4694 break;
4695 default:
4696 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4700 /***********************************************************************
4701 * NdrBaseTypeMemorySize [internal]
4703 static unsigned long WINAPI NdrBaseTypeMemorySize(
4704 PMIDL_STUB_MESSAGE pStubMsg,
4705 PFORMAT_STRING pFormat)
4707 switch(*pFormat)
4709 case RPC_FC_BYTE:
4710 case RPC_FC_CHAR:
4711 case RPC_FC_SMALL:
4712 case RPC_FC_USMALL:
4713 pStubMsg->Buffer += sizeof(UCHAR);
4714 pStubMsg->MemorySize += sizeof(UCHAR);
4715 return sizeof(UCHAR);
4716 case RPC_FC_WCHAR:
4717 case RPC_FC_SHORT:
4718 case RPC_FC_USHORT:
4719 pStubMsg->Buffer += sizeof(USHORT);
4720 pStubMsg->MemorySize += sizeof(USHORT);
4721 return sizeof(USHORT);
4722 case RPC_FC_LONG:
4723 case RPC_FC_ULONG:
4724 pStubMsg->Buffer += sizeof(ULONG);
4725 pStubMsg->MemorySize += sizeof(ULONG);
4726 return sizeof(ULONG);
4727 case RPC_FC_FLOAT:
4728 pStubMsg->Buffer += sizeof(float);
4729 pStubMsg->MemorySize += sizeof(float);
4730 return sizeof(float);
4731 case RPC_FC_DOUBLE:
4732 pStubMsg->Buffer += sizeof(double);
4733 pStubMsg->MemorySize += sizeof(double);
4734 return sizeof(double);
4735 case RPC_FC_HYPER:
4736 pStubMsg->Buffer += sizeof(ULONGLONG);
4737 pStubMsg->MemorySize += sizeof(ULONGLONG);
4738 return sizeof(ULONGLONG);
4739 case RPC_FC_ERROR_STATUS_T:
4740 pStubMsg->Buffer += sizeof(error_status_t);
4741 pStubMsg->MemorySize += sizeof(error_status_t);
4742 return sizeof(error_status_t);
4743 case RPC_FC_ENUM16:
4744 case RPC_FC_ENUM32:
4745 pStubMsg->Buffer += sizeof(INT);
4746 pStubMsg->MemorySize += sizeof(INT);
4747 return sizeof(INT);
4748 default:
4749 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4750 return 0;
4754 /***********************************************************************
4755 * NdrBaseTypeFree [internal]
4757 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4758 unsigned char *pMemory,
4759 PFORMAT_STRING pFormat)
4761 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4763 /* nothing to do */
4766 /***********************************************************************
4767 * NdrClientContextMarshall
4769 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4770 NDR_CCONTEXT ContextHandle,
4771 int fCheck)
4773 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
4775 ALIGN_POINTER(pStubMsg->Buffer, 4);
4777 /* FIXME: what does fCheck do? */
4778 NDRCContextMarshall(ContextHandle,
4779 pStubMsg->Buffer);
4781 pStubMsg->Buffer += cbNDRContext;
4784 /***********************************************************************
4785 * NdrClientContextUnmarshall
4787 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4788 NDR_CCONTEXT * pContextHandle,
4789 RPC_BINDING_HANDLE BindHandle)
4791 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
4793 ALIGN_POINTER(pStubMsg->Buffer, 4);
4795 NDRCContextUnmarshall(pContextHandle,
4796 BindHandle,
4797 pStubMsg->Buffer,
4798 pStubMsg->RpcMsg->DataRepresentation);
4800 pStubMsg->Buffer += cbNDRContext;
4803 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4804 NDR_SCONTEXT ContextHandle,
4805 NDR_RUNDOWN RundownRoutine )
4807 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4810 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4812 FIXME("(%p): stub\n", pStubMsg);
4813 return NULL;
4816 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4817 unsigned char* pMemory,
4818 PFORMAT_STRING pFormat)
4820 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
4823 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
4824 PFORMAT_STRING pFormat)
4826 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4827 return NULL;
4830 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4831 NDR_SCONTEXT ContextHandle,
4832 NDR_RUNDOWN RundownRoutine,
4833 PFORMAT_STRING pFormat)
4835 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
4838 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4839 PFORMAT_STRING pFormat)
4841 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4842 return NULL;
4845 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
4847 typedef struct ndr_context_handle
4849 DWORD attributes;
4850 GUID uuid;
4851 } ndr_context_handle;
4853 struct context_handle_entry
4855 struct list entry;
4856 DWORD magic;
4857 RPC_BINDING_HANDLE handle;
4858 ndr_context_handle wire_data;
4861 static struct list context_handle_list = LIST_INIT(context_handle_list);
4863 static CRITICAL_SECTION ndr_context_cs;
4864 static CRITICAL_SECTION_DEBUG ndr_context_debug =
4866 0, 0, &ndr_context_cs,
4867 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
4868 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
4870 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
4872 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
4874 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
4876 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
4877 return NULL;
4878 return che;
4881 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
4883 struct context_handle_entry *che;
4884 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
4885 if (IsEqualGUID(&che->wire_data.uuid, uuid))
4886 return che;
4887 return NULL;
4890 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
4892 struct context_handle_entry *che;
4893 RPC_BINDING_HANDLE handle = NULL;
4895 TRACE("%p\n", CContext);
4897 EnterCriticalSection(&ndr_context_cs);
4898 che = get_context_entry(CContext);
4899 if (che)
4900 handle = che->handle;
4901 LeaveCriticalSection(&ndr_context_cs);
4903 if (!handle)
4904 RpcRaiseException(ERROR_INVALID_HANDLE);
4905 return handle;
4908 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
4910 struct context_handle_entry *che;
4912 TRACE("%p %p\n", CContext, pBuff);
4914 if (CContext)
4916 EnterCriticalSection(&ndr_context_cs);
4917 che = get_context_entry(CContext);
4918 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
4919 LeaveCriticalSection(&ndr_context_cs);
4921 else
4923 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
4924 wire_data->attributes = 0;
4925 wire_data->uuid = GUID_NULL;
4929 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
4930 RPC_BINDING_HANDLE hBinding,
4931 ndr_context_handle *chi)
4933 struct context_handle_entry *che = NULL;
4935 /* a null UUID means we should free the context handle */
4936 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
4938 if (*CContext)
4940 che = get_context_entry(*CContext);
4941 if (!che)
4942 return ERROR_INVALID_HANDLE;
4943 list_remove(&che->entry);
4944 RpcBindingFree(&che->handle);
4945 HeapFree(GetProcessHeap(), 0, che);
4946 che = NULL;
4949 /* if there's no existing entry matching the GUID, allocate one */
4950 else if (!(che = context_entry_from_guid(&chi->uuid)))
4952 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
4953 if (!che)
4954 return ERROR_NOT_ENOUGH_MEMORY;
4955 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
4956 RpcBindingCopy(hBinding, &che->handle);
4957 list_add_tail(&context_handle_list, &che->entry);
4958 memcpy(&che->wire_data, chi, sizeof *chi);
4961 *CContext = che;
4963 return ERROR_SUCCESS;
4966 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
4967 RPC_BINDING_HANDLE hBinding,
4968 void *pBuff,
4969 unsigned long DataRepresentation)
4971 UINT r;
4973 TRACE("*%p=(%p) %p %p %08lx\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 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
4984 void *pBuff,
4985 NDR_RUNDOWN userRunDownIn)
4987 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
4990 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
4991 NDR_SCONTEXT CContext,
4992 void *pBuff,
4993 NDR_RUNDOWN userRunDownIn)
4995 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
4998 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
4999 NDR_SCONTEXT CContext,
5000 void *pBuff,
5001 NDR_RUNDOWN userRunDownIn,
5002 void *CtxGuard,
5003 unsigned long Flags)
5005 FIXME("(%p %p %p %p %p %lu): stub\n",
5006 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5009 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5010 unsigned long DataRepresentation)
5012 FIXME("(%p %08lx): stub\n", pBuff, DataRepresentation);
5013 return NULL;
5016 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5017 void *pBuff,
5018 unsigned long DataRepresentation)
5020 FIXME("(%p %p %08lx): stub\n", hBinding, pBuff, DataRepresentation);
5021 return NULL;
5024 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5025 void *pBuff,
5026 unsigned long DataRepresentation,
5027 void *CtxGuard,
5028 unsigned long Flags)
5030 FIXME("(%p %p %08lx %p %lu): stub\n",
5031 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
5032 return NULL;