rpcrt4: Support small fixed arrays in EmbeddedComplexSize.
[wine/testsucceed.git] / dlls / rpcrt4 / ndr_marshall.c
blob179d93319c5f4781a4c08ce1043e412aad0eb541
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 = *(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 = *(LPWORD)(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 return *(const WORD*)&pFormat[2];
1656 case RPC_FC_USER_MARSHAL:
1657 return *(const WORD*)&pFormat[4];
1658 case RPC_FC_NON_ENCAPSULATED_UNION:
1659 pFormat += 2;
1660 if (pStubMsg->fHasNewCorrDesc)
1661 pFormat += 6;
1662 else
1663 pFormat += 4;
1665 pFormat += *(const SHORT*)pFormat;
1666 return *(const SHORT*)pFormat;
1667 case RPC_FC_IP:
1668 return sizeof(void *);
1669 default:
1670 FIXME("unhandled embedded type %02x\n", *pFormat);
1672 return 0;
1676 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1677 PFORMAT_STRING pFormat)
1679 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1681 if (!m)
1683 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1684 return 0;
1687 return m(pStubMsg, pFormat);
1691 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1692 unsigned char *pMemory,
1693 PFORMAT_STRING pFormat,
1694 PFORMAT_STRING pPointer)
1696 PFORMAT_STRING desc;
1697 NDR_MARSHALL m;
1698 unsigned long size;
1700 while (*pFormat != RPC_FC_END) {
1701 switch (*pFormat) {
1702 case RPC_FC_BYTE:
1703 case RPC_FC_CHAR:
1704 case RPC_FC_SMALL:
1705 case RPC_FC_USMALL:
1706 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
1707 memcpy(pStubMsg->Buffer, pMemory, 1);
1708 pStubMsg->Buffer += 1;
1709 pMemory += 1;
1710 break;
1711 case RPC_FC_WCHAR:
1712 case RPC_FC_SHORT:
1713 case RPC_FC_USHORT:
1714 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1715 memcpy(pStubMsg->Buffer, pMemory, 2);
1716 pStubMsg->Buffer += 2;
1717 pMemory += 2;
1718 break;
1719 case RPC_FC_LONG:
1720 case RPC_FC_ULONG:
1721 case RPC_FC_ENUM32:
1722 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1723 memcpy(pStubMsg->Buffer, pMemory, 4);
1724 pStubMsg->Buffer += 4;
1725 pMemory += 4;
1726 break;
1727 case RPC_FC_HYPER:
1728 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1729 memcpy(pStubMsg->Buffer, pMemory, 8);
1730 pStubMsg->Buffer += 8;
1731 pMemory += 8;
1732 break;
1733 case RPC_FC_POINTER:
1734 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1735 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1736 pPointer += 4;
1737 pMemory += 4;
1738 break;
1739 case RPC_FC_ALIGNM4:
1740 ALIGN_POINTER(pMemory, 4);
1741 break;
1742 case RPC_FC_ALIGNM8:
1743 ALIGN_POINTER(pMemory, 8);
1744 break;
1745 case RPC_FC_STRUCTPAD1:
1746 case RPC_FC_STRUCTPAD2:
1747 case RPC_FC_STRUCTPAD3:
1748 case RPC_FC_STRUCTPAD4:
1749 case RPC_FC_STRUCTPAD5:
1750 case RPC_FC_STRUCTPAD6:
1751 case RPC_FC_STRUCTPAD7:
1752 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1753 break;
1754 case RPC_FC_EMBEDDED_COMPLEX:
1755 pMemory += pFormat[1];
1756 pFormat += 2;
1757 desc = pFormat + *(const SHORT*)pFormat;
1758 size = EmbeddedComplexSize(pStubMsg, desc);
1759 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1760 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1761 if (m) m(pStubMsg, pMemory, desc);
1762 else FIXME("no marshaller for embedded type %02x\n", *desc);
1763 pMemory += size;
1764 pFormat += 2;
1765 continue;
1766 case RPC_FC_PAD:
1767 break;
1768 default:
1769 FIXME("unhandled format 0x%02x\n", *pFormat);
1771 pFormat++;
1774 return pMemory;
1777 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1778 unsigned char *pMemory,
1779 PFORMAT_STRING pFormat,
1780 PFORMAT_STRING pPointer)
1782 PFORMAT_STRING desc;
1783 NDR_UNMARSHALL m;
1784 unsigned long size;
1786 while (*pFormat != RPC_FC_END) {
1787 switch (*pFormat) {
1788 case RPC_FC_BYTE:
1789 case RPC_FC_CHAR:
1790 case RPC_FC_SMALL:
1791 case RPC_FC_USMALL:
1792 memcpy(pMemory, pStubMsg->Buffer, 1);
1793 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
1794 pStubMsg->Buffer += 1;
1795 pMemory += 1;
1796 break;
1797 case RPC_FC_WCHAR:
1798 case RPC_FC_SHORT:
1799 case RPC_FC_USHORT:
1800 memcpy(pMemory, pStubMsg->Buffer, 2);
1801 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1802 pStubMsg->Buffer += 2;
1803 pMemory += 2;
1804 break;
1805 case RPC_FC_LONG:
1806 case RPC_FC_ULONG:
1807 case RPC_FC_ENUM32:
1808 memcpy(pMemory, pStubMsg->Buffer, 4);
1809 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1810 pStubMsg->Buffer += 4;
1811 pMemory += 4;
1812 break;
1813 case RPC_FC_HYPER:
1814 memcpy(pMemory, pStubMsg->Buffer, 8);
1815 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
1816 pStubMsg->Buffer += 8;
1817 pMemory += 8;
1818 break;
1819 case RPC_FC_POINTER:
1820 TRACE("pointer => %p\n", pMemory);
1821 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1822 pPointer += 4;
1823 pMemory += 4;
1824 break;
1825 case RPC_FC_ALIGNM4:
1826 ALIGN_POINTER(pMemory, 4);
1827 break;
1828 case RPC_FC_ALIGNM8:
1829 ALIGN_POINTER(pMemory, 8);
1830 break;
1831 case RPC_FC_STRUCTPAD1:
1832 case RPC_FC_STRUCTPAD2:
1833 case RPC_FC_STRUCTPAD3:
1834 case RPC_FC_STRUCTPAD4:
1835 case RPC_FC_STRUCTPAD5:
1836 case RPC_FC_STRUCTPAD6:
1837 case RPC_FC_STRUCTPAD7:
1838 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1839 break;
1840 case RPC_FC_EMBEDDED_COMPLEX:
1841 pMemory += pFormat[1];
1842 pFormat += 2;
1843 desc = pFormat + *(const SHORT*)pFormat;
1844 size = EmbeddedComplexSize(pStubMsg, desc);
1845 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1846 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1847 memset(pMemory, 0, size); /* just in case */
1848 if (m) m(pStubMsg, &pMemory, desc, FALSE);
1849 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1850 pMemory += size;
1851 pFormat += 2;
1852 continue;
1853 case RPC_FC_PAD:
1854 break;
1855 default:
1856 FIXME("unhandled format %d\n", *pFormat);
1858 pFormat++;
1861 return pMemory;
1864 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1865 unsigned char *pMemory,
1866 PFORMAT_STRING pFormat,
1867 PFORMAT_STRING pPointer)
1869 PFORMAT_STRING desc;
1870 NDR_BUFFERSIZE m;
1871 unsigned long size;
1873 while (*pFormat != RPC_FC_END) {
1874 switch (*pFormat) {
1875 case RPC_FC_BYTE:
1876 case RPC_FC_CHAR:
1877 case RPC_FC_SMALL:
1878 case RPC_FC_USMALL:
1879 pStubMsg->BufferLength += 1;
1880 pMemory += 1;
1881 break;
1882 case RPC_FC_WCHAR:
1883 case RPC_FC_SHORT:
1884 case RPC_FC_USHORT:
1885 pStubMsg->BufferLength += 2;
1886 pMemory += 2;
1887 break;
1888 case RPC_FC_LONG:
1889 case RPC_FC_ULONG:
1890 case RPC_FC_ENUM32:
1891 pStubMsg->BufferLength += 4;
1892 pMemory += 4;
1893 break;
1894 case RPC_FC_HYPER:
1895 pStubMsg->BufferLength += 8;
1896 pMemory += 8;
1897 break;
1898 case RPC_FC_POINTER:
1899 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1900 pPointer += 4;
1901 pMemory += 4;
1902 break;
1903 case RPC_FC_ALIGNM4:
1904 ALIGN_POINTER(pMemory, 4);
1905 break;
1906 case RPC_FC_ALIGNM8:
1907 ALIGN_POINTER(pMemory, 8);
1908 break;
1909 case RPC_FC_STRUCTPAD1:
1910 case RPC_FC_STRUCTPAD2:
1911 case RPC_FC_STRUCTPAD3:
1912 case RPC_FC_STRUCTPAD4:
1913 case RPC_FC_STRUCTPAD5:
1914 case RPC_FC_STRUCTPAD6:
1915 case RPC_FC_STRUCTPAD7:
1916 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1917 break;
1918 case RPC_FC_EMBEDDED_COMPLEX:
1919 pMemory += pFormat[1];
1920 pFormat += 2;
1921 desc = pFormat + *(const SHORT*)pFormat;
1922 size = EmbeddedComplexSize(pStubMsg, desc);
1923 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1924 if (m) m(pStubMsg, pMemory, desc);
1925 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1926 pMemory += size;
1927 pFormat += 2;
1928 continue;
1929 case RPC_FC_PAD:
1930 break;
1931 default:
1932 FIXME("unhandled format 0x%02x\n", *pFormat);
1934 pFormat++;
1937 return pMemory;
1940 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1941 unsigned char *pMemory,
1942 PFORMAT_STRING pFormat,
1943 PFORMAT_STRING pPointer)
1945 PFORMAT_STRING desc;
1946 NDR_FREE m;
1947 unsigned long size;
1949 while (*pFormat != RPC_FC_END) {
1950 switch (*pFormat) {
1951 case RPC_FC_BYTE:
1952 case RPC_FC_CHAR:
1953 case RPC_FC_SMALL:
1954 case RPC_FC_USMALL:
1955 pMemory += 1;
1956 break;
1957 case RPC_FC_WCHAR:
1958 case RPC_FC_SHORT:
1959 case RPC_FC_USHORT:
1960 pMemory += 2;
1961 break;
1962 case RPC_FC_LONG:
1963 case RPC_FC_ULONG:
1964 case RPC_FC_ENUM32:
1965 pMemory += 4;
1966 break;
1967 case RPC_FC_HYPER:
1968 pMemory += 8;
1969 break;
1970 case RPC_FC_POINTER:
1971 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1972 pPointer += 4;
1973 pMemory += 4;
1974 break;
1975 case RPC_FC_ALIGNM4:
1976 ALIGN_POINTER(pMemory, 4);
1977 break;
1978 case RPC_FC_ALIGNM8:
1979 ALIGN_POINTER(pMemory, 8);
1980 break;
1981 case RPC_FC_STRUCTPAD1:
1982 case RPC_FC_STRUCTPAD2:
1983 case RPC_FC_STRUCTPAD3:
1984 case RPC_FC_STRUCTPAD4:
1985 case RPC_FC_STRUCTPAD5:
1986 case RPC_FC_STRUCTPAD6:
1987 case RPC_FC_STRUCTPAD7:
1988 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
1989 break;
1990 case RPC_FC_EMBEDDED_COMPLEX:
1991 pMemory += pFormat[1];
1992 pFormat += 2;
1993 desc = pFormat + *(const SHORT*)pFormat;
1994 size = EmbeddedComplexSize(pStubMsg, desc);
1995 m = NdrFreer[*desc & NDR_TABLE_MASK];
1996 if (m) m(pStubMsg, pMemory, desc);
1997 else FIXME("no freer for embedded type %02x\n", *desc);
1998 pMemory += size;
1999 pFormat += 2;
2000 continue;
2001 case RPC_FC_PAD:
2002 break;
2003 default:
2004 FIXME("unhandled format 0x%02x\n", *pFormat);
2006 pFormat++;
2009 return pMemory;
2012 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2013 PFORMAT_STRING pFormat)
2015 PFORMAT_STRING desc;
2016 unsigned long size = 0;
2018 while (*pFormat != RPC_FC_END) {
2019 switch (*pFormat) {
2020 case RPC_FC_BYTE:
2021 case RPC_FC_CHAR:
2022 case RPC_FC_SMALL:
2023 case RPC_FC_USMALL:
2024 size += 1;
2025 pStubMsg->Buffer += 1;
2026 break;
2027 case RPC_FC_WCHAR:
2028 case RPC_FC_SHORT:
2029 case RPC_FC_USHORT:
2030 size += 2;
2031 pStubMsg->Buffer += 2;
2032 break;
2033 case RPC_FC_LONG:
2034 case RPC_FC_ULONG:
2035 case RPC_FC_ENUM32:
2036 size += 4;
2037 pStubMsg->Buffer += 4;
2038 break;
2039 case RPC_FC_HYPER:
2040 size += 8;
2041 pStubMsg->Buffer += 8;
2042 break;
2043 case RPC_FC_POINTER:
2044 size += 4;
2045 pStubMsg->Buffer += 4;
2046 break;
2047 case RPC_FC_ALIGNM4:
2048 ALIGN_LENGTH(size, 4);
2049 ALIGN_POINTER(pStubMsg->Buffer, 4);
2050 break;
2051 case RPC_FC_ALIGNM8:
2052 ALIGN_LENGTH(size, 8);
2053 ALIGN_POINTER(pStubMsg->Buffer, 8);
2054 break;
2055 case RPC_FC_STRUCTPAD1:
2056 case RPC_FC_STRUCTPAD2:
2057 case RPC_FC_STRUCTPAD3:
2058 case RPC_FC_STRUCTPAD4:
2059 case RPC_FC_STRUCTPAD5:
2060 case RPC_FC_STRUCTPAD6:
2061 case RPC_FC_STRUCTPAD7:
2062 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2063 break;
2064 case RPC_FC_EMBEDDED_COMPLEX:
2065 size += pFormat[1];
2066 pFormat += 2;
2067 desc = pFormat + *(const SHORT*)pFormat;
2068 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2069 pFormat += 2;
2070 continue;
2071 case RPC_FC_PAD:
2072 break;
2073 default:
2074 FIXME("unhandled format 0x%02x\n", *pFormat);
2076 pFormat++;
2079 return size;
2082 /***********************************************************************
2083 * NdrComplexStructMarshall [RPCRT4.@]
2085 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2086 unsigned char *pMemory,
2087 PFORMAT_STRING pFormat)
2089 PFORMAT_STRING conf_array = NULL;
2090 PFORMAT_STRING pointer_desc = NULL;
2091 unsigned char *OldMemory = pStubMsg->Memory;
2093 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2095 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2097 pFormat += 4;
2098 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2099 pFormat += 2;
2100 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2101 pFormat += 2;
2103 pStubMsg->Memory = pMemory;
2105 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2107 if (conf_array)
2108 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2110 pStubMsg->Memory = OldMemory;
2112 STD_OVERFLOW_CHECK(pStubMsg);
2114 return NULL;
2117 /***********************************************************************
2118 * NdrComplexStructUnmarshall [RPCRT4.@]
2120 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2121 unsigned char **ppMemory,
2122 PFORMAT_STRING pFormat,
2123 unsigned char fMustAlloc)
2125 unsigned size = *(const WORD*)(pFormat+2);
2126 PFORMAT_STRING conf_array = NULL;
2127 PFORMAT_STRING pointer_desc = NULL;
2128 unsigned char *pMemory;
2130 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2132 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2134 if (fMustAlloc || !*ppMemory)
2136 *ppMemory = NdrAllocate(pStubMsg, size);
2137 memset(*ppMemory, 0, size);
2140 pFormat += 4;
2141 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2142 pFormat += 2;
2143 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2144 pFormat += 2;
2146 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2148 if (conf_array)
2149 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2151 return NULL;
2154 /***********************************************************************
2155 * NdrComplexStructBufferSize [RPCRT4.@]
2157 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2158 unsigned char *pMemory,
2159 PFORMAT_STRING pFormat)
2161 PFORMAT_STRING conf_array = NULL;
2162 PFORMAT_STRING pointer_desc = NULL;
2163 unsigned char *OldMemory = pStubMsg->Memory;
2165 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2167 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2169 pFormat += 4;
2170 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2171 pFormat += 2;
2172 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2173 pFormat += 2;
2175 pStubMsg->Memory = pMemory;
2177 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2179 if (conf_array)
2180 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2182 pStubMsg->Memory = OldMemory;
2185 /***********************************************************************
2186 * NdrComplexStructMemorySize [RPCRT4.@]
2188 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2189 PFORMAT_STRING pFormat)
2191 unsigned size = *(const WORD*)(pFormat+2);
2192 PFORMAT_STRING conf_array = NULL;
2193 PFORMAT_STRING pointer_desc = NULL;
2195 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2197 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2199 pFormat += 4;
2200 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2201 pFormat += 2;
2202 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2203 pFormat += 2;
2205 ComplexStructMemorySize(pStubMsg, pFormat);
2207 if (conf_array)
2208 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2210 return size;
2213 /***********************************************************************
2214 * NdrComplexStructFree [RPCRT4.@]
2216 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2217 unsigned char *pMemory,
2218 PFORMAT_STRING pFormat)
2220 PFORMAT_STRING conf_array = NULL;
2221 PFORMAT_STRING pointer_desc = NULL;
2222 unsigned char *OldMemory = pStubMsg->Memory;
2224 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2226 pFormat += 4;
2227 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2228 pFormat += 2;
2229 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2230 pFormat += 2;
2232 pStubMsg->Memory = pMemory;
2234 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2236 if (conf_array)
2237 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2239 pStubMsg->Memory = OldMemory;
2242 /***********************************************************************
2243 * NdrConformantArrayMarshall [RPCRT4.@]
2245 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2246 unsigned char *pMemory,
2247 PFORMAT_STRING pFormat)
2249 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2250 unsigned char alignment = pFormat[1] + 1;
2252 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2253 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2255 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2257 WriteConformance(pStubMsg);
2259 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2261 size = safe_multiply(esize, pStubMsg->MaxCount);
2262 memcpy(pStubMsg->Buffer, pMemory, size);
2263 pStubMsg->BufferMark = pStubMsg->Buffer;
2264 pStubMsg->Buffer += size;
2266 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2268 STD_OVERFLOW_CHECK(pStubMsg);
2270 return NULL;
2273 /***********************************************************************
2274 * NdrConformantArrayUnmarshall [RPCRT4.@]
2276 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2277 unsigned char **ppMemory,
2278 PFORMAT_STRING pFormat,
2279 unsigned char fMustAlloc)
2281 DWORD size, esize = *(const WORD*)(pFormat+2);
2282 unsigned char alignment = pFormat[1] + 1;
2284 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2285 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2287 pFormat = ReadConformance(pStubMsg, pFormat+4);
2289 size = safe_multiply(esize, pStubMsg->MaxCount);
2291 if (fMustAlloc || !*ppMemory)
2292 *ppMemory = NdrAllocate(pStubMsg, size);
2294 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2296 memcpy(*ppMemory, pStubMsg->Buffer, size);
2298 pStubMsg->BufferMark = pStubMsg->Buffer;
2299 pStubMsg->Buffer += size;
2301 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2303 return NULL;
2306 /***********************************************************************
2307 * NdrConformantArrayBufferSize [RPCRT4.@]
2309 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2310 unsigned char *pMemory,
2311 PFORMAT_STRING pFormat)
2313 DWORD size, esize = *(const WORD*)(pFormat+2);
2314 unsigned char alignment = pFormat[1] + 1;
2316 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2317 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2319 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2321 SizeConformance(pStubMsg);
2323 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2325 size = safe_multiply(esize, pStubMsg->MaxCount);
2326 /* conformance value plus array */
2327 pStubMsg->BufferLength += size;
2329 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2332 /***********************************************************************
2333 * NdrConformantArrayMemorySize [RPCRT4.@]
2335 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2336 PFORMAT_STRING pFormat)
2338 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2339 unsigned char alignment = pFormat[1] + 1;
2341 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2342 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2344 pFormat = ReadConformance(pStubMsg, pFormat+4);
2345 size = safe_multiply(esize, pStubMsg->MaxCount);
2346 pStubMsg->MemorySize += size;
2348 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2349 pStubMsg->BufferMark = pStubMsg->Buffer;
2350 pStubMsg->Buffer += size;
2352 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2354 return pStubMsg->MemorySize;
2357 /***********************************************************************
2358 * NdrConformantArrayFree [RPCRT4.@]
2360 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2361 unsigned char *pMemory,
2362 PFORMAT_STRING pFormat)
2364 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2365 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2367 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2371 /***********************************************************************
2372 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2374 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2375 unsigned char* pMemory,
2376 PFORMAT_STRING pFormat )
2378 ULONG bufsize;
2379 unsigned char alignment = pFormat[1] + 1;
2380 DWORD esize = *(const WORD*)(pFormat+2);
2382 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2384 if (pFormat[0] != RPC_FC_CVARRAY)
2386 ERR("invalid format type %x\n", pFormat[0]);
2387 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2388 return NULL;
2391 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2392 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2394 WriteConformance(pStubMsg);
2395 WriteVariance(pStubMsg);
2397 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2399 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2401 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
2402 pStubMsg->BufferMark = pStubMsg->Buffer;
2403 pStubMsg->Buffer += bufsize;
2405 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2407 STD_OVERFLOW_CHECK(pStubMsg);
2409 return NULL;
2413 /***********************************************************************
2414 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2416 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2417 unsigned char** ppMemory,
2418 PFORMAT_STRING pFormat,
2419 unsigned char fMustAlloc )
2421 ULONG bufsize, memsize;
2422 unsigned char alignment = pFormat[1] + 1;
2423 DWORD esize = *(const WORD*)(pFormat+2);
2425 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2427 if (pFormat[0] != RPC_FC_CVARRAY)
2429 ERR("invalid format type %x\n", pFormat[0]);
2430 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2431 return NULL;
2434 pFormat = ReadConformance(pStubMsg, pFormat+4);
2435 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2437 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2439 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2440 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2442 if (!*ppMemory || fMustAlloc)
2443 *ppMemory = NdrAllocate(pStubMsg, memsize);
2444 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
2445 pStubMsg->Buffer += bufsize;
2447 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2449 return NULL;
2453 /***********************************************************************
2454 * NdrConformantVaryingArrayFree [RPCRT4.@]
2456 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2457 unsigned char* pMemory,
2458 PFORMAT_STRING pFormat )
2460 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2462 if (pFormat[0] != RPC_FC_CVARRAY)
2464 ERR("invalid format type %x\n", pFormat[0]);
2465 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2466 return;
2469 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2470 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2472 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2476 /***********************************************************************
2477 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2479 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2480 unsigned char* pMemory, PFORMAT_STRING pFormat )
2482 unsigned char alignment = pFormat[1] + 1;
2483 DWORD esize = *(const WORD*)(pFormat+2);
2485 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2487 if (pFormat[0] != RPC_FC_CVARRAY)
2489 ERR("invalid format type %x\n", pFormat[0]);
2490 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2491 return;
2494 /* compute size */
2495 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2496 /* compute length */
2497 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2499 SizeConformance(pStubMsg);
2500 SizeVariance(pStubMsg);
2502 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2504 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
2506 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2510 /***********************************************************************
2511 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2513 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2514 PFORMAT_STRING pFormat )
2516 FIXME( "stub\n" );
2517 return 0;
2521 /***********************************************************************
2522 * NdrComplexArrayMarshall [RPCRT4.@]
2524 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2525 unsigned char *pMemory,
2526 PFORMAT_STRING pFormat)
2528 ULONG i, count, def;
2529 BOOL variance_present;
2530 unsigned char alignment;
2532 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2534 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2536 ERR("invalid format type %x\n", pFormat[0]);
2537 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2538 return NULL;
2541 alignment = pFormat[1] + 1;
2543 def = *(const WORD*)&pFormat[2];
2544 pFormat += 4;
2546 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2547 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2549 variance_present = IsConformanceOrVariancePresent(pFormat);
2550 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2551 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2553 WriteConformance(pStubMsg);
2554 if (variance_present)
2555 WriteVariance(pStubMsg);
2557 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2559 count = pStubMsg->ActualCount;
2560 for (i = 0; i < count; i++)
2561 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2563 STD_OVERFLOW_CHECK(pStubMsg);
2565 return NULL;
2568 /***********************************************************************
2569 * NdrComplexArrayUnmarshall [RPCRT4.@]
2571 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2572 unsigned char **ppMemory,
2573 PFORMAT_STRING pFormat,
2574 unsigned char fMustAlloc)
2576 ULONG i, count, esize, memsize;
2577 unsigned char alignment;
2578 unsigned char *pMemory;
2579 unsigned char *Buffer;
2581 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2583 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2585 ERR("invalid format type %x\n", pFormat[0]);
2586 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2587 return NULL;
2590 alignment = pFormat[1] + 1;
2592 pFormat += 4;
2594 pFormat = ReadConformance(pStubMsg, pFormat);
2595 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2597 Buffer = pStubMsg->Buffer;
2598 pStubMsg->MemorySize = 0;
2599 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2600 pStubMsg->Buffer = Buffer;
2602 /* do multiply here instead of inside if block to verify MaxCount */
2603 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2604 if (fMustAlloc || !*ppMemory)
2606 *ppMemory = NdrAllocate(pStubMsg, memsize);
2607 memset(*ppMemory, 0, memsize);
2610 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2612 pMemory = *ppMemory;
2613 count = pStubMsg->ActualCount;
2614 for (i = 0; i < count; i++)
2615 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2617 return NULL;
2620 /***********************************************************************
2621 * NdrComplexArrayBufferSize [RPCRT4.@]
2623 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2624 unsigned char *pMemory,
2625 PFORMAT_STRING pFormat)
2627 ULONG i, count, def;
2628 unsigned char alignment;
2629 BOOL variance_present;
2631 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2633 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2635 ERR("invalid format type %x\n", pFormat[0]);
2636 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2637 return;
2640 alignment = pFormat[1] + 1;
2642 def = *(const WORD*)&pFormat[2];
2643 pFormat += 4;
2645 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2646 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2647 SizeConformance(pStubMsg);
2649 variance_present = IsConformanceOrVariancePresent(pFormat);
2650 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2651 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2653 if (variance_present)
2654 SizeVariance(pStubMsg);
2656 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2658 count = pStubMsg->ActualCount;
2659 for (i = 0; i < count; i++)
2660 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2663 /***********************************************************************
2664 * NdrComplexArrayMemorySize [RPCRT4.@]
2666 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2667 PFORMAT_STRING pFormat)
2669 ULONG i, count, esize;
2670 unsigned char alignment;
2671 unsigned char *Buffer;
2672 unsigned long SavedMemorySize;
2673 unsigned long MemorySize;
2675 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2677 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2679 ERR("invalid format type %x\n", pFormat[0]);
2680 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2681 return 0;
2684 alignment = pFormat[1] + 1;
2686 pFormat += 4;
2688 pFormat = ReadConformance(pStubMsg, pFormat);
2689 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2691 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2693 SavedMemorySize = pStubMsg->MemorySize;
2695 Buffer = pStubMsg->Buffer;
2696 pStubMsg->MemorySize = 0;
2697 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2698 pStubMsg->Buffer = Buffer;
2700 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
2702 count = pStubMsg->ActualCount;
2703 for (i = 0; i < count; i++)
2704 ComplexStructMemorySize(pStubMsg, pFormat);
2706 pStubMsg->MemorySize = SavedMemorySize;
2708 pStubMsg->MemorySize += MemorySize;
2709 return MemorySize;
2712 /***********************************************************************
2713 * NdrComplexArrayFree [RPCRT4.@]
2715 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2716 unsigned char *pMemory,
2717 PFORMAT_STRING pFormat)
2719 ULONG i, count, def;
2721 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2723 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2725 ERR("invalid format type %x\n", pFormat[0]);
2726 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2727 return;
2730 def = *(const WORD*)&pFormat[2];
2731 pFormat += 4;
2733 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2734 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2736 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2737 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2739 count = pStubMsg->ActualCount;
2740 for (i = 0; i < count; i++)
2741 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2744 static unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2746 return MAKELONG(pStubMsg->dwDestContext,
2747 pStubMsg->RpcMsg->DataRepresentation);
2750 #define USER_MARSHAL_PTR_PREFIX \
2751 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2752 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2754 /***********************************************************************
2755 * NdrUserMarshalMarshall [RPCRT4.@]
2757 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2758 unsigned char *pMemory,
2759 PFORMAT_STRING pFormat)
2761 unsigned flags = pFormat[1];
2762 unsigned index = *(const WORD*)&pFormat[2];
2763 unsigned long uflag = UserMarshalFlags(pStubMsg);
2764 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2765 TRACE("index=%d\n", index);
2767 if (flags & USER_MARSHAL_POINTER)
2769 ALIGN_POINTER(pStubMsg->Buffer, 4);
2770 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2771 pStubMsg->Buffer += 4;
2772 ALIGN_POINTER(pStubMsg->Buffer, 8);
2774 else
2775 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2777 pStubMsg->Buffer =
2778 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2779 &uflag, pStubMsg->Buffer, pMemory);
2781 STD_OVERFLOW_CHECK(pStubMsg);
2783 return NULL;
2786 /***********************************************************************
2787 * NdrUserMarshalUnmarshall [RPCRT4.@]
2789 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2790 unsigned char **ppMemory,
2791 PFORMAT_STRING pFormat,
2792 unsigned char fMustAlloc)
2794 unsigned flags = pFormat[1];
2795 unsigned index = *(const WORD*)&pFormat[2];
2796 DWORD memsize = *(const WORD*)&pFormat[4];
2797 unsigned long uflag = UserMarshalFlags(pStubMsg);
2798 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2799 TRACE("index=%d\n", index);
2801 if (flags & USER_MARSHAL_POINTER)
2803 ALIGN_POINTER(pStubMsg->Buffer, 4);
2804 /* skip pointer prefix */
2805 pStubMsg->Buffer += 4;
2806 ALIGN_POINTER(pStubMsg->Buffer, 8);
2808 else
2809 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2811 if (fMustAlloc || !*ppMemory)
2812 *ppMemory = NdrAllocate(pStubMsg, memsize);
2814 pStubMsg->Buffer =
2815 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2816 &uflag, pStubMsg->Buffer, *ppMemory);
2818 return NULL;
2821 /***********************************************************************
2822 * NdrUserMarshalBufferSize [RPCRT4.@]
2824 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2825 unsigned char *pMemory,
2826 PFORMAT_STRING pFormat)
2828 unsigned flags = pFormat[1];
2829 unsigned index = *(const WORD*)&pFormat[2];
2830 DWORD bufsize = *(const WORD*)&pFormat[6];
2831 unsigned long uflag = UserMarshalFlags(pStubMsg);
2832 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2833 TRACE("index=%d\n", index);
2835 if (flags & USER_MARSHAL_POINTER)
2837 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2838 /* skip pointer prefix */
2839 pStubMsg->BufferLength += 4;
2840 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2842 else
2843 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2845 if (bufsize) {
2846 TRACE("size=%ld\n", bufsize);
2847 pStubMsg->BufferLength += bufsize;
2848 return;
2851 pStubMsg->BufferLength =
2852 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2853 &uflag, pStubMsg->BufferLength, pMemory);
2856 /***********************************************************************
2857 * NdrUserMarshalMemorySize [RPCRT4.@]
2859 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2860 PFORMAT_STRING pFormat)
2862 unsigned flags = pFormat[1];
2863 unsigned index = *(const WORD*)&pFormat[2];
2864 DWORD memsize = *(const WORD*)&pFormat[4];
2865 DWORD bufsize = *(const WORD*)&pFormat[6];
2867 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2868 TRACE("index=%d\n", index);
2870 pStubMsg->MemorySize += memsize;
2872 if (flags & USER_MARSHAL_POINTER)
2874 ALIGN_POINTER(pStubMsg->Buffer, 4);
2875 /* skip pointer prefix */
2876 pStubMsg->Buffer += 4;
2877 ALIGN_POINTER(pStubMsg->Buffer, 8);
2879 else
2880 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2882 pStubMsg->Buffer += bufsize;
2884 return pStubMsg->MemorySize;
2887 /***********************************************************************
2888 * NdrUserMarshalFree [RPCRT4.@]
2890 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2891 unsigned char *pMemory,
2892 PFORMAT_STRING pFormat)
2894 /* unsigned flags = pFormat[1]; */
2895 unsigned index = *(const WORD*)&pFormat[2];
2896 unsigned long uflag = UserMarshalFlags(pStubMsg);
2897 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2898 TRACE("index=%d\n", index);
2900 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2901 &uflag, pMemory);
2904 /***********************************************************************
2905 * NdrClearOutParameters [RPCRT4.@]
2907 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2908 PFORMAT_STRING pFormat,
2909 void *ArgAddr)
2911 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2914 /***********************************************************************
2915 * NdrConvert [RPCRT4.@]
2917 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2919 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2920 /* FIXME: since this stub doesn't do any converting, the proper behavior
2921 is to raise an exception */
2924 /***********************************************************************
2925 * NdrConvert2 [RPCRT4.@]
2927 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2929 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2930 pStubMsg, pFormat, NumberParams);
2931 /* FIXME: since this stub doesn't do any converting, the proper behavior
2932 is to raise an exception */
2935 typedef struct _NDR_CSTRUCT_FORMAT
2937 unsigned char type;
2938 unsigned char alignment;
2939 unsigned short memory_size;
2940 short offset_to_array_description;
2941 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2943 /***********************************************************************
2944 * NdrConformantStructMarshall [RPCRT4.@]
2946 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2947 unsigned char *pMemory,
2948 PFORMAT_STRING pFormat)
2950 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2951 PFORMAT_STRING pCArrayFormat;
2952 ULONG esize, bufsize;
2954 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2956 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2957 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2959 ERR("invalid format type %x\n", pCStructFormat->type);
2960 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2961 return NULL;
2964 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2965 pCStructFormat->offset_to_array_description;
2966 if (*pCArrayFormat != RPC_FC_CARRAY)
2968 ERR("invalid array format type %x\n", pCStructFormat->type);
2969 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2970 return NULL;
2972 esize = *(const WORD*)(pCArrayFormat+2);
2974 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2975 pCArrayFormat + 4, 0);
2977 WriteConformance(pStubMsg);
2979 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2981 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2983 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
2984 /* copy constant sized part of struct */
2985 pStubMsg->BufferMark = pStubMsg->Buffer;
2986 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize);
2987 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
2989 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2990 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2992 STD_OVERFLOW_CHECK(pStubMsg);
2994 return NULL;
2997 /***********************************************************************
2998 * NdrConformantStructUnmarshall [RPCRT4.@]
3000 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3001 unsigned char **ppMemory,
3002 PFORMAT_STRING pFormat,
3003 unsigned char fMustAlloc)
3005 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
3006 PFORMAT_STRING pCArrayFormat;
3007 ULONG esize, bufsize;
3009 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3011 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3012 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3014 ERR("invalid format type %x\n", pCStructFormat->type);
3015 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3016 return NULL;
3018 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
3019 pCStructFormat->offset_to_array_description;
3020 if (*pCArrayFormat != RPC_FC_CARRAY)
3022 ERR("invalid array format type %x\n", pCStructFormat->type);
3023 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3024 return NULL;
3026 esize = *(const WORD*)(pCArrayFormat+2);
3028 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3030 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3032 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3034 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3035 /* work out how much memory to allocate if we need to do so */
3036 if (!*ppMemory || fMustAlloc)
3038 SIZE_T size = pCStructFormat->memory_size + bufsize;
3039 *ppMemory = NdrAllocate(pStubMsg, size);
3042 /* now copy the data */
3043 pStubMsg->BufferMark = pStubMsg->Buffer;
3044 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
3045 pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
3047 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3048 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3050 return NULL;
3053 /***********************************************************************
3054 * NdrConformantStructBufferSize [RPCRT4.@]
3056 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3057 unsigned char *pMemory,
3058 PFORMAT_STRING pFormat)
3060 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
3061 PFORMAT_STRING pCArrayFormat;
3062 ULONG esize;
3064 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3066 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3067 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3069 ERR("invalid format type %x\n", pCStructFormat->type);
3070 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3071 return;
3073 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
3074 pCStructFormat->offset_to_array_description;
3075 if (*pCArrayFormat != RPC_FC_CARRAY)
3077 ERR("invalid array format type %x\n", pCStructFormat->type);
3078 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3079 return;
3081 esize = *(const WORD*)(pCArrayFormat+2);
3083 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
3084 SizeConformance(pStubMsg);
3086 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
3088 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3090 pStubMsg->BufferLength += pCStructFormat->memory_size +
3091 safe_multiply(pStubMsg->MaxCount, esize);
3093 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3094 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3097 /***********************************************************************
3098 * NdrConformantStructMemorySize [RPCRT4.@]
3100 unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3101 PFORMAT_STRING pFormat)
3103 FIXME("stub\n");
3104 return 0;
3107 /***********************************************************************
3108 * NdrConformantStructFree [RPCRT4.@]
3110 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3111 unsigned char *pMemory,
3112 PFORMAT_STRING pFormat)
3114 FIXME("stub\n");
3117 /***********************************************************************
3118 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3120 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3121 unsigned char *pMemory,
3122 PFORMAT_STRING pFormat)
3124 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3125 PFORMAT_STRING pCVArrayFormat;
3126 ULONG esize, bufsize;
3128 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3130 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3131 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3133 ERR("invalid format type %x\n", pCVStructFormat->type);
3134 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3135 return NULL;
3138 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3139 pCVStructFormat->offset_to_array_description;
3140 switch (*pCVArrayFormat)
3142 case RPC_FC_CVARRAY:
3143 esize = *(const WORD*)(pCVArrayFormat+2);
3145 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3146 pCVArrayFormat + 4, 0);
3147 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3148 pCVArrayFormat, 0);
3149 break;
3150 case RPC_FC_C_CSTRING:
3151 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3152 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3153 esize = sizeof(char);
3154 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3155 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3156 pCVArrayFormat + 2, 0);
3157 else
3158 pStubMsg->MaxCount = pStubMsg->ActualCount;
3159 break;
3160 case RPC_FC_C_WSTRING:
3161 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3162 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3163 esize = sizeof(WCHAR);
3164 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3165 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3166 pCVArrayFormat + 2, 0);
3167 else
3168 pStubMsg->MaxCount = pStubMsg->ActualCount;
3169 break;
3170 default:
3171 ERR("invalid array format type %x\n", *pCVArrayFormat);
3172 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3173 return NULL;
3176 WriteConformance(pStubMsg);
3178 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3180 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3182 /* write constant sized part */
3183 pStubMsg->BufferMark = pStubMsg->Buffer;
3184 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3185 pStubMsg->Buffer += pCVStructFormat->memory_size;
3187 WriteVariance(pStubMsg);
3189 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3191 /* write array part */
3192 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize);
3193 pStubMsg->Buffer += bufsize;
3195 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3197 STD_OVERFLOW_CHECK(pStubMsg);
3199 return NULL;
3202 /***********************************************************************
3203 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3205 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3206 unsigned char **ppMemory,
3207 PFORMAT_STRING pFormat,
3208 unsigned char fMustAlloc)
3210 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3211 PFORMAT_STRING pCVArrayFormat;
3212 ULONG esize, bufsize;
3213 unsigned char cvarray_type;
3215 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3217 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3218 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3220 ERR("invalid format type %x\n", pCVStructFormat->type);
3221 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3222 return NULL;
3225 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3226 pCVStructFormat->offset_to_array_description;
3227 cvarray_type = *pCVArrayFormat;
3228 switch (cvarray_type)
3230 case RPC_FC_CVARRAY:
3231 esize = *(const WORD*)(pCVArrayFormat+2);
3232 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3233 break;
3234 case RPC_FC_C_CSTRING:
3235 esize = sizeof(char);
3236 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3237 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3238 else
3239 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3240 break;
3241 case RPC_FC_C_WSTRING:
3242 esize = sizeof(WCHAR);
3243 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3244 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3245 else
3246 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3247 break;
3248 default:
3249 ERR("invalid array format type %x\n", *pCVArrayFormat);
3250 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3251 return NULL;
3254 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3256 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3258 /* work out how much memory to allocate if we need to do so */
3259 if (!*ppMemory || fMustAlloc)
3261 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3262 *ppMemory = NdrAllocate(pStubMsg, size);
3265 /* copy the constant data */
3266 pStubMsg->BufferMark = pStubMsg->Buffer;
3267 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3268 pStubMsg->Buffer += pCVStructFormat->memory_size;
3270 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3272 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3274 if ((cvarray_type == RPC_FC_C_CSTRING) ||
3275 (cvarray_type == RPC_FC_C_WSTRING))
3277 ULONG i;
3278 /* strings must always have null terminating bytes */
3279 if (bufsize < esize)
3281 ERR("invalid string length of %ld\n", pStubMsg->ActualCount);
3282 RpcRaiseException(RPC_S_INVALID_BOUND);
3283 return NULL;
3285 for (i = bufsize - esize; i < bufsize; i++)
3286 if (pStubMsg->Buffer[i] != 0)
3288 ERR("string not null-terminated at byte position %ld, data is 0x%x\n",
3289 i, pStubMsg->Buffer[i]);
3290 RpcRaiseException(RPC_S_INVALID_BOUND);
3291 return NULL;
3295 /* copy the array data */
3296 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3297 bufsize);
3298 pStubMsg->Buffer += bufsize;
3300 if (cvarray_type == RPC_FC_C_CSTRING)
3301 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3302 else if (cvarray_type == RPC_FC_C_WSTRING)
3303 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3305 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3307 return NULL;
3310 /***********************************************************************
3311 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3313 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3314 unsigned char *pMemory,
3315 PFORMAT_STRING pFormat)
3317 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3318 PFORMAT_STRING pCVArrayFormat;
3319 ULONG esize;
3321 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3323 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3324 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3326 ERR("invalid format type %x\n", pCVStructFormat->type);
3327 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3328 return;
3331 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3332 pCVStructFormat->offset_to_array_description;
3333 switch (*pCVArrayFormat)
3335 case RPC_FC_CVARRAY:
3336 esize = *(const WORD*)(pCVArrayFormat+2);
3338 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3339 pCVArrayFormat + 4, 0);
3340 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3341 pCVArrayFormat, 0);
3342 break;
3343 case RPC_FC_C_CSTRING:
3344 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3345 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3346 esize = sizeof(char);
3347 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3348 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3349 pCVArrayFormat + 2, 0);
3350 else
3351 pStubMsg->MaxCount = pStubMsg->ActualCount;
3352 break;
3353 case RPC_FC_C_WSTRING:
3354 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3355 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3356 esize = sizeof(WCHAR);
3357 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3358 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3359 pCVArrayFormat + 2, 0);
3360 else
3361 pStubMsg->MaxCount = pStubMsg->ActualCount;
3362 break;
3363 default:
3364 ERR("invalid array format type %x\n", *pCVArrayFormat);
3365 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3366 return;
3369 SizeConformance(pStubMsg);
3371 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3373 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3375 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3376 SizeVariance(pStubMsg);
3377 pStubMsg->BufferLength += safe_multiply(pStubMsg->MaxCount, esize);
3379 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3382 /***********************************************************************
3383 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3385 unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3386 PFORMAT_STRING pFormat)
3388 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3389 PFORMAT_STRING pCVArrayFormat;
3390 ULONG esize;
3391 unsigned char cvarray_type;
3393 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3395 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3396 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3398 ERR("invalid format type %x\n", pCVStructFormat->type);
3399 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3400 return 0;
3403 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3404 pCVStructFormat->offset_to_array_description;
3405 cvarray_type = *pCVArrayFormat;
3406 switch (cvarray_type)
3408 case RPC_FC_CVARRAY:
3409 esize = *(const WORD*)(pCVArrayFormat+2);
3410 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3411 break;
3412 case RPC_FC_C_CSTRING:
3413 esize = sizeof(char);
3414 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3415 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3416 else
3417 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3418 break;
3419 case RPC_FC_C_WSTRING:
3420 esize = sizeof(WCHAR);
3421 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3422 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3423 else
3424 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3425 break;
3426 default:
3427 ERR("invalid array format type %x\n", *pCVArrayFormat);
3428 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3429 return 0;
3432 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3434 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3436 pStubMsg->Buffer += pCVStructFormat->memory_size;
3437 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
3438 pStubMsg->Buffer += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->ActualCount);
3440 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
3442 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3444 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3447 /***********************************************************************
3448 * NdrConformantVaryingStructFree [RPCRT4.@]
3450 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3451 unsigned char *pMemory,
3452 PFORMAT_STRING pFormat)
3454 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3455 PFORMAT_STRING pCVArrayFormat;
3456 ULONG esize;
3458 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3460 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3461 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3463 ERR("invalid format type %x\n", pCVStructFormat->type);
3464 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3465 return;
3468 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3469 pCVStructFormat->offset_to_array_description;
3470 switch (*pCVArrayFormat)
3472 case RPC_FC_CVARRAY:
3473 esize = *(const WORD*)(pCVArrayFormat+2);
3475 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3476 pCVArrayFormat + 4, 0);
3477 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3478 pCVArrayFormat, 0);
3479 break;
3480 case RPC_FC_C_CSTRING:
3481 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3482 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3483 esize = sizeof(char);
3484 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3485 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3486 pCVArrayFormat + 2, 0);
3487 else
3488 pStubMsg->MaxCount = pStubMsg->ActualCount;
3489 break;
3490 case RPC_FC_C_WSTRING:
3491 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3492 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3493 esize = sizeof(WCHAR);
3494 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3495 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3496 pCVArrayFormat + 2, 0);
3497 else
3498 pStubMsg->MaxCount = pStubMsg->ActualCount;
3499 break;
3500 default:
3501 ERR("invalid array format type %x\n", *pCVArrayFormat);
3502 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3503 return;
3506 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3508 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3511 typedef struct
3513 unsigned char type;
3514 unsigned char alignment;
3515 unsigned short total_size;
3516 } NDR_SMFARRAY_FORMAT;
3518 typedef struct
3520 unsigned char type;
3521 unsigned char alignment;
3522 unsigned long total_size;
3523 } NDR_LGFARRAY_FORMAT;
3525 /***********************************************************************
3526 * NdrFixedArrayMarshall [RPCRT4.@]
3528 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3529 unsigned char *pMemory,
3530 PFORMAT_STRING pFormat)
3532 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3533 unsigned long total_size;
3535 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3537 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3538 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3540 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3541 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3542 return NULL;
3545 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3547 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3549 total_size = pSmFArrayFormat->total_size;
3550 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3552 else
3554 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3555 total_size = pLgFArrayFormat->total_size;
3556 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3558 memcpy(pStubMsg->Buffer, pMemory, total_size);
3559 pStubMsg->Buffer += total_size;
3561 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3563 return NULL;
3566 /***********************************************************************
3567 * NdrFixedArrayUnmarshall [RPCRT4.@]
3569 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3570 unsigned char **ppMemory,
3571 PFORMAT_STRING pFormat,
3572 unsigned char fMustAlloc)
3574 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3575 unsigned long total_size;
3577 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3579 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3580 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3582 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3583 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3584 return NULL;
3587 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3589 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3591 total_size = pSmFArrayFormat->total_size;
3592 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3594 else
3596 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3597 total_size = pLgFArrayFormat->total_size;
3598 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3601 if (fMustAlloc || !*ppMemory)
3602 *ppMemory = NdrAllocate(pStubMsg, total_size);
3603 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3604 pStubMsg->Buffer += total_size;
3606 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3608 return NULL;
3611 /***********************************************************************
3612 * NdrFixedArrayBufferSize [RPCRT4.@]
3614 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3615 unsigned char *pMemory,
3616 PFORMAT_STRING pFormat)
3618 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3619 unsigned long total_size;
3621 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3623 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3624 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3626 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3627 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3628 return;
3631 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3633 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3635 total_size = pSmFArrayFormat->total_size;
3636 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3638 else
3640 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3641 total_size = pLgFArrayFormat->total_size;
3642 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3644 pStubMsg->BufferLength += total_size;
3646 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3649 /***********************************************************************
3650 * NdrFixedArrayMemorySize [RPCRT4.@]
3652 unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3653 PFORMAT_STRING pFormat)
3655 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3656 unsigned long total_size;
3658 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3660 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3661 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3663 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3664 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3665 return 0;
3668 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3670 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3672 total_size = pSmFArrayFormat->total_size;
3673 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3675 else
3677 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3678 total_size = pLgFArrayFormat->total_size;
3679 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3681 pStubMsg->Buffer += total_size;
3682 pStubMsg->MemorySize += total_size;
3684 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3686 return total_size;
3689 /***********************************************************************
3690 * NdrFixedArrayFree [RPCRT4.@]
3692 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3693 unsigned char *pMemory,
3694 PFORMAT_STRING pFormat)
3696 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3698 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3700 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3701 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3703 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3704 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3705 return;
3708 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3709 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3710 else
3712 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3713 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3716 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3719 /***********************************************************************
3720 * NdrVaryingArrayMarshall [RPCRT4.@]
3722 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3723 unsigned char *pMemory,
3724 PFORMAT_STRING pFormat)
3726 unsigned char alignment;
3727 DWORD elements, esize;
3728 ULONG bufsize;
3730 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3732 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3733 (pFormat[0] != RPC_FC_LGVARRAY))
3735 ERR("invalid format type %x\n", pFormat[0]);
3736 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3737 return NULL;
3740 alignment = pFormat[1] + 1;
3742 if (pFormat[0] == RPC_FC_SMVARRAY)
3744 pFormat += 2;
3745 pFormat += sizeof(WORD);
3746 elements = *(const WORD*)pFormat;
3747 pFormat += sizeof(WORD);
3749 else
3751 pFormat += 2;
3752 pFormat += sizeof(DWORD);
3753 elements = *(const DWORD*)pFormat;
3754 pFormat += sizeof(DWORD);
3757 esize = *(const WORD*)pFormat;
3758 pFormat += sizeof(WORD);
3760 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3761 if ((pStubMsg->ActualCount > elements) ||
3762 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3764 RpcRaiseException(RPC_S_INVALID_BOUND);
3765 return NULL;
3768 WriteVariance(pStubMsg);
3770 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3772 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3773 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
3774 pStubMsg->BufferMark = pStubMsg->Buffer;
3775 pStubMsg->Buffer += bufsize;
3777 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3779 STD_OVERFLOW_CHECK(pStubMsg);
3781 return NULL;
3784 /***********************************************************************
3785 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3787 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3788 unsigned char **ppMemory,
3789 PFORMAT_STRING pFormat,
3790 unsigned char fMustAlloc)
3792 unsigned char alignment;
3793 DWORD size, elements, esize;
3794 ULONG bufsize;
3796 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3798 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3799 (pFormat[0] != RPC_FC_LGVARRAY))
3801 ERR("invalid format type %x\n", pFormat[0]);
3802 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3803 return NULL;
3806 alignment = pFormat[1] + 1;
3808 if (pFormat[0] == RPC_FC_SMVARRAY)
3810 pFormat += 2;
3811 size = *(const WORD*)pFormat;
3812 pFormat += sizeof(WORD);
3813 elements = *(const WORD*)pFormat;
3814 pFormat += sizeof(WORD);
3816 else
3818 pFormat += 2;
3819 size = *(const DWORD*)pFormat;
3820 pFormat += sizeof(DWORD);
3821 elements = *(const DWORD*)pFormat;
3822 pFormat += sizeof(DWORD);
3825 esize = *(const WORD*)pFormat;
3826 pFormat += sizeof(WORD);
3828 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3830 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3832 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3834 if (!*ppMemory || fMustAlloc)
3835 *ppMemory = NdrAllocate(pStubMsg, size);
3836 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
3837 pStubMsg->Buffer += bufsize;
3839 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3841 return NULL;
3844 /***********************************************************************
3845 * NdrVaryingArrayBufferSize [RPCRT4.@]
3847 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3848 unsigned char *pMemory,
3849 PFORMAT_STRING pFormat)
3851 unsigned char alignment;
3852 DWORD elements, esize;
3854 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3856 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3857 (pFormat[0] != RPC_FC_LGVARRAY))
3859 ERR("invalid format type %x\n", pFormat[0]);
3860 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3861 return;
3864 alignment = pFormat[1] + 1;
3866 if (pFormat[0] == RPC_FC_SMVARRAY)
3868 pFormat += 2;
3869 pFormat += sizeof(WORD);
3870 elements = *(const WORD*)pFormat;
3871 pFormat += sizeof(WORD);
3873 else
3875 pFormat += 2;
3876 pFormat += sizeof(DWORD);
3877 elements = *(const DWORD*)pFormat;
3878 pFormat += sizeof(DWORD);
3881 esize = *(const WORD*)pFormat;
3882 pFormat += sizeof(WORD);
3884 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3885 if ((pStubMsg->ActualCount > elements) ||
3886 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3888 RpcRaiseException(RPC_S_INVALID_BOUND);
3889 return;
3892 SizeVariance(pStubMsg);
3894 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3896 pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);
3898 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3901 /***********************************************************************
3902 * NdrVaryingArrayMemorySize [RPCRT4.@]
3904 unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3905 PFORMAT_STRING pFormat)
3907 unsigned char alignment;
3908 DWORD size, elements, esize;
3910 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3912 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3913 (pFormat[0] != RPC_FC_LGVARRAY))
3915 ERR("invalid format type %x\n", pFormat[0]);
3916 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3917 return 0;
3920 alignment = pFormat[1] + 1;
3922 if (pFormat[0] == RPC_FC_SMVARRAY)
3924 pFormat += 2;
3925 size = *(const WORD*)pFormat;
3926 pFormat += sizeof(WORD);
3927 elements = *(const WORD*)pFormat;
3928 pFormat += sizeof(WORD);
3930 else
3932 pFormat += 2;
3933 size = *(const DWORD*)pFormat;
3934 pFormat += sizeof(DWORD);
3935 elements = *(const DWORD*)pFormat;
3936 pFormat += sizeof(DWORD);
3939 esize = *(const WORD*)pFormat;
3940 pFormat += sizeof(WORD);
3942 pFormat = ReadVariance(pStubMsg, pFormat, elements);
3944 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3946 pStubMsg->Buffer += safe_multiply(esize, pStubMsg->ActualCount);
3947 pStubMsg->MemorySize += size;
3949 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3951 return pStubMsg->MemorySize;
3954 /***********************************************************************
3955 * NdrVaryingArrayFree [RPCRT4.@]
3957 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3958 unsigned char *pMemory,
3959 PFORMAT_STRING pFormat)
3961 unsigned char alignment;
3962 DWORD elements;
3964 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3966 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
3967 (pFormat[0] != RPC_FC_LGVARRAY))
3969 ERR("invalid format type %x\n", pFormat[0]);
3970 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3971 return;
3974 alignment = pFormat[1] + 1;
3976 if (pFormat[0] == RPC_FC_SMVARRAY)
3978 pFormat += 2;
3979 pFormat += sizeof(WORD);
3980 elements = *(const WORD*)pFormat;
3981 pFormat += sizeof(WORD);
3983 else
3985 pFormat += 2;
3986 pFormat += sizeof(DWORD);
3987 elements = *(const DWORD*)pFormat;
3988 pFormat += sizeof(DWORD);
3991 pFormat += sizeof(WORD);
3993 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3994 if ((pStubMsg->ActualCount > elements) ||
3995 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
3997 RpcRaiseException(RPC_S_INVALID_BOUND);
3998 return;
4001 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4004 /***********************************************************************
4005 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4007 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4008 unsigned char *pMemory,
4009 PFORMAT_STRING pFormat)
4011 FIXME("stub\n");
4012 return NULL;
4015 /***********************************************************************
4016 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4018 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4019 unsigned char **ppMemory,
4020 PFORMAT_STRING pFormat,
4021 unsigned char fMustAlloc)
4023 FIXME("stub\n");
4024 return NULL;
4027 /***********************************************************************
4028 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4030 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4031 unsigned char *pMemory,
4032 PFORMAT_STRING pFormat)
4034 FIXME("stub\n");
4037 /***********************************************************************
4038 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4040 unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4041 PFORMAT_STRING pFormat)
4043 FIXME("stub\n");
4044 return 0;
4047 /***********************************************************************
4048 * NdrEncapsulatedUnionFree [RPCRT4.@]
4050 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4051 unsigned char *pMemory,
4052 PFORMAT_STRING pFormat)
4054 FIXME("stub\n");
4057 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4058 unsigned long discriminant,
4059 PFORMAT_STRING pFormat)
4061 unsigned short num_arms, arm, type;
4063 num_arms = *(const SHORT*)pFormat & 0x0fff;
4064 pFormat += 2;
4065 for(arm = 0; arm < num_arms; arm++)
4067 if(discriminant == *(const ULONG*)pFormat)
4069 pFormat += 4;
4070 break;
4072 pFormat += 6;
4075 type = *(const unsigned short*)pFormat;
4076 TRACE("type %04x\n", type);
4077 if(arm == num_arms) /* default arm extras */
4079 if(type == 0xffff)
4081 ERR("no arm for 0x%lx and no default case\n", discriminant);
4082 RpcRaiseException(RPC_S_INVALID_TAG);
4083 return NULL;
4085 if(type == 0)
4087 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
4088 return NULL;
4091 return pFormat;
4094 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
4095 ULONG value,
4096 PFORMAT_STRING pFormat)
4098 pFormat += *(const SHORT*)pFormat;
4099 pFormat += 2;
4101 return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
4104 /***********************************************************************
4105 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4107 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4108 unsigned char *pMemory,
4109 PFORMAT_STRING pFormat)
4111 unsigned short type;
4112 unsigned char switch_type;
4114 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4115 pFormat++;
4117 switch_type = *pFormat;
4118 pFormat++;
4120 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4121 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4122 /* Marshall discriminant */
4123 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4125 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4126 if(!pFormat)
4127 return NULL;
4129 type = *(const unsigned short*)pFormat;
4130 if((type & 0xff00) == 0x8000)
4132 unsigned char basetype = LOBYTE(type);
4133 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
4135 else
4137 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4138 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
4139 if (m)
4141 unsigned char *saved_buffer = NULL;
4142 switch(*desc)
4144 case RPC_FC_RP:
4145 case RPC_FC_UP:
4146 case RPC_FC_OP:
4147 case RPC_FC_FP:
4148 saved_buffer = pStubMsg->Buffer;
4149 pStubMsg->Buffer += 4; /* for pointer ID */
4150 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
4151 break;
4152 default:
4153 m(pStubMsg, pMemory, desc);
4156 else FIXME("no marshaller for embedded type %02x\n", *desc);
4158 return NULL;
4161 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
4162 PFORMAT_STRING *ppFormat)
4164 long discriminant = 0;
4166 switch(**ppFormat)
4168 case RPC_FC_BYTE:
4169 case RPC_FC_CHAR:
4170 case RPC_FC_SMALL:
4171 case RPC_FC_USMALL:
4172 discriminant = *(UCHAR *)pStubMsg->Buffer;
4173 pStubMsg->Buffer += sizeof(UCHAR);
4174 break;
4175 case RPC_FC_WCHAR:
4176 case RPC_FC_SHORT:
4177 case RPC_FC_USHORT:
4178 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4179 discriminant = *(USHORT *)pStubMsg->Buffer;
4180 pStubMsg->Buffer += sizeof(USHORT);
4181 break;
4182 case RPC_FC_LONG:
4183 case RPC_FC_ULONG:
4184 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4185 discriminant = *(ULONG *)pStubMsg->Buffer;
4186 pStubMsg->Buffer += sizeof(ULONG);
4187 break;
4188 default:
4189 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
4191 (*ppFormat)++;
4193 if (pStubMsg->fHasNewCorrDesc)
4194 *ppFormat += 6;
4195 else
4196 *ppFormat += 4;
4197 return discriminant;
4200 /**********************************************************************
4201 * NdrNonEncapsulatedUnionUnmarshall[RPCRT4.@]
4203 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4204 unsigned char **ppMemory,
4205 PFORMAT_STRING pFormat,
4206 unsigned char fMustAlloc)
4208 long discriminant;
4209 unsigned short type, size;
4211 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4212 pFormat++;
4214 /* Unmarshall discriminant */
4215 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4216 TRACE("unmarshalled discriminant %lx\n", discriminant);
4218 pFormat += *(const SHORT*)pFormat;
4220 size = *(const unsigned short*)pFormat;
4221 pFormat += 2;
4223 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4224 if(!pFormat)
4225 return NULL;
4227 if(!*ppMemory || fMustAlloc)
4228 *ppMemory = NdrAllocate(pStubMsg, size);
4230 type = *(const unsigned short*)pFormat;
4231 if((type & 0xff00) == 0x8000)
4233 unsigned char basetype = LOBYTE(type);
4234 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
4236 else
4238 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4239 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
4240 if (m)
4242 unsigned char *saved_buffer = NULL;
4243 switch(*desc)
4245 case RPC_FC_RP:
4246 case RPC_FC_UP:
4247 case RPC_FC_OP:
4248 case RPC_FC_FP:
4249 ALIGN_POINTER(pStubMsg->Buffer, 4);
4250 saved_buffer = pStubMsg->Buffer;
4251 pStubMsg->Buffer += 4; /* for pointer ID */
4252 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
4253 break;
4254 default:
4255 m(pStubMsg, ppMemory, desc, fMustAlloc);
4258 else FIXME("no marshaller for embedded type %02x\n", *desc);
4260 return NULL;
4263 /***********************************************************************
4264 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4266 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4267 unsigned char *pMemory,
4268 PFORMAT_STRING pFormat)
4270 unsigned short type;
4271 unsigned char switch_type;
4273 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4274 pFormat++;
4276 switch_type = *pFormat;
4277 pFormat++;
4279 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
4280 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
4281 /* Add discriminant size */
4282 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
4284 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
4285 if(!pFormat)
4286 return;
4288 type = *(const unsigned short*)pFormat;
4289 if((type & 0xff00) == 0x8000)
4291 unsigned char basetype = LOBYTE(type);
4292 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
4294 else
4296 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4297 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
4298 if (m)
4300 switch(*desc)
4302 case RPC_FC_RP:
4303 case RPC_FC_UP:
4304 case RPC_FC_OP:
4305 case RPC_FC_FP:
4306 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4307 pStubMsg->BufferLength += 4; /* for pointer ID */
4308 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
4309 break;
4310 default:
4311 m(pStubMsg, pMemory, desc);
4314 else FIXME("no buffersizer for embedded type %02x\n", *desc);
4316 return;
4319 /***********************************************************************
4320 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4322 unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4323 PFORMAT_STRING pFormat)
4325 unsigned long discriminant;
4326 unsigned short type, size;
4328 pFormat++;
4329 /* Unmarshall discriminant */
4330 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
4331 TRACE("unmarshalled discriminant 0x%lx\n", discriminant);
4333 pFormat += *(const SHORT*)pFormat;
4335 size = *(const unsigned short*)pFormat;
4336 pFormat += 2;
4338 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
4339 if(!pFormat)
4340 return 0;
4342 pStubMsg->Memory += size;
4344 type = *(const unsigned short*)pFormat;
4345 if((type & 0xff00) == 0x8000)
4347 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
4349 else
4351 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
4352 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
4353 unsigned char *saved_buffer;
4354 if (m)
4356 switch(*desc)
4358 case RPC_FC_RP:
4359 case RPC_FC_UP:
4360 case RPC_FC_OP:
4361 case RPC_FC_FP:
4362 ALIGN_POINTER(pStubMsg->Buffer, 4);
4363 saved_buffer = pStubMsg->Buffer;
4364 pStubMsg->Buffer += 4;
4365 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
4366 pStubMsg->MemorySize += 4;
4367 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
4368 break;
4369 default:
4370 return m(pStubMsg, desc);
4373 else FIXME("no marshaller for embedded type %02x\n", *desc);
4376 TRACE("size %d\n", size);
4377 return size;
4380 /***********************************************************************
4381 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4383 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
4384 unsigned char *pMemory,
4385 PFORMAT_STRING pFormat)
4387 FIXME("stub\n");
4390 /***********************************************************************
4391 * NdrByteCountPointerMarshall [RPCRT4.@]
4393 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4394 unsigned char *pMemory,
4395 PFORMAT_STRING pFormat)
4397 FIXME("stub\n");
4398 return NULL;
4401 /***********************************************************************
4402 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4404 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4405 unsigned char **ppMemory,
4406 PFORMAT_STRING pFormat,
4407 unsigned char fMustAlloc)
4409 FIXME("stub\n");
4410 return NULL;
4413 /***********************************************************************
4414 * NdrByteCountPointerBufferSize [RPCRT4.@]
4416 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4417 unsigned char *pMemory,
4418 PFORMAT_STRING pFormat)
4420 FIXME("stub\n");
4423 /***********************************************************************
4424 * NdrByteCountPointerMemorySize [RPCRT4.@]
4426 unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4427 PFORMAT_STRING pFormat)
4429 FIXME("stub\n");
4430 return 0;
4433 /***********************************************************************
4434 * NdrByteCountPointerFree [RPCRT4.@]
4436 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4437 unsigned char *pMemory,
4438 PFORMAT_STRING pFormat)
4440 FIXME("stub\n");
4443 /***********************************************************************
4444 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4446 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4447 unsigned char *pMemory,
4448 PFORMAT_STRING pFormat)
4450 FIXME("stub\n");
4451 return NULL;
4454 /***********************************************************************
4455 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4457 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4458 unsigned char **ppMemory,
4459 PFORMAT_STRING pFormat,
4460 unsigned char fMustAlloc)
4462 FIXME("stub\n");
4463 return NULL;
4466 /***********************************************************************
4467 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4469 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4470 unsigned char *pMemory,
4471 PFORMAT_STRING pFormat)
4473 FIXME("stub\n");
4476 /***********************************************************************
4477 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4479 unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4480 PFORMAT_STRING pFormat)
4482 FIXME("stub\n");
4483 return 0;
4486 /***********************************************************************
4487 * NdrXmitOrRepAsFree [RPCRT4.@]
4489 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4490 unsigned char *pMemory,
4491 PFORMAT_STRING pFormat)
4493 FIXME("stub\n");
4496 /***********************************************************************
4497 * NdrBaseTypeMarshall [internal]
4499 static unsigned char *WINAPI NdrBaseTypeMarshall(
4500 PMIDL_STUB_MESSAGE pStubMsg,
4501 unsigned char *pMemory,
4502 PFORMAT_STRING pFormat)
4504 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4506 switch(*pFormat)
4508 case RPC_FC_BYTE:
4509 case RPC_FC_CHAR:
4510 case RPC_FC_SMALL:
4511 case RPC_FC_USMALL:
4512 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4513 pStubMsg->Buffer += sizeof(UCHAR);
4514 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4515 break;
4516 case RPC_FC_WCHAR:
4517 case RPC_FC_SHORT:
4518 case RPC_FC_USHORT:
4519 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4520 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4521 pStubMsg->Buffer += sizeof(USHORT);
4522 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4523 break;
4524 case RPC_FC_LONG:
4525 case RPC_FC_ULONG:
4526 case RPC_FC_ERROR_STATUS_T:
4527 case RPC_FC_ENUM32:
4528 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4529 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4530 pStubMsg->Buffer += sizeof(ULONG);
4531 TRACE("value: 0x%08lx\n", *(ULONG *)pMemory);
4532 break;
4533 case RPC_FC_FLOAT:
4534 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4535 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4536 pStubMsg->Buffer += sizeof(float);
4537 break;
4538 case RPC_FC_DOUBLE:
4539 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4540 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4541 pStubMsg->Buffer += sizeof(double);
4542 break;
4543 case RPC_FC_HYPER:
4544 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4545 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4546 pStubMsg->Buffer += sizeof(ULONGLONG);
4547 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4548 break;
4549 case RPC_FC_ENUM16:
4550 /* only 16-bits on the wire, so do a sanity check */
4551 if (*(UINT *)pMemory > USHRT_MAX)
4552 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4553 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4554 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4555 pStubMsg->Buffer += sizeof(USHORT);
4556 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4557 break;
4558 default:
4559 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4562 STD_OVERFLOW_CHECK(pStubMsg);
4564 /* FIXME: what is the correct return value? */
4565 return NULL;
4568 /***********************************************************************
4569 * NdrBaseTypeUnmarshall [internal]
4571 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4572 PMIDL_STUB_MESSAGE pStubMsg,
4573 unsigned char **ppMemory,
4574 PFORMAT_STRING pFormat,
4575 unsigned char fMustAlloc)
4577 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4579 #define BASE_TYPE_UNMARSHALL(type) \
4580 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4581 if (fMustAlloc || !*ppMemory) \
4582 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4583 TRACE("*ppMemory: %p\n", *ppMemory); \
4584 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4585 pStubMsg->Buffer += sizeof(type);
4587 switch(*pFormat)
4589 case RPC_FC_BYTE:
4590 case RPC_FC_CHAR:
4591 case RPC_FC_SMALL:
4592 case RPC_FC_USMALL:
4593 BASE_TYPE_UNMARSHALL(UCHAR);
4594 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4595 break;
4596 case RPC_FC_WCHAR:
4597 case RPC_FC_SHORT:
4598 case RPC_FC_USHORT:
4599 BASE_TYPE_UNMARSHALL(USHORT);
4600 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4601 break;
4602 case RPC_FC_LONG:
4603 case RPC_FC_ULONG:
4604 case RPC_FC_ERROR_STATUS_T:
4605 case RPC_FC_ENUM32:
4606 BASE_TYPE_UNMARSHALL(ULONG);
4607 TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory);
4608 break;
4609 case RPC_FC_FLOAT:
4610 BASE_TYPE_UNMARSHALL(float);
4611 TRACE("value: %f\n", **(float **)ppMemory);
4612 break;
4613 case RPC_FC_DOUBLE:
4614 BASE_TYPE_UNMARSHALL(double);
4615 TRACE("value: %f\n", **(double **)ppMemory);
4616 break;
4617 case RPC_FC_HYPER:
4618 BASE_TYPE_UNMARSHALL(ULONGLONG);
4619 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4620 break;
4621 case RPC_FC_ENUM16:
4622 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4623 if (fMustAlloc || !*ppMemory)
4624 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
4625 TRACE("*ppMemory: %p\n", *ppMemory);
4626 /* 16-bits on the wire, but int in memory */
4627 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4628 pStubMsg->Buffer += sizeof(USHORT);
4629 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4630 break;
4631 default:
4632 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4634 #undef BASE_TYPE_UNMARSHALL
4636 /* FIXME: what is the correct return value? */
4638 return NULL;
4641 /***********************************************************************
4642 * NdrBaseTypeBufferSize [internal]
4644 static void WINAPI NdrBaseTypeBufferSize(
4645 PMIDL_STUB_MESSAGE pStubMsg,
4646 unsigned char *pMemory,
4647 PFORMAT_STRING pFormat)
4649 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4651 switch(*pFormat)
4653 case RPC_FC_BYTE:
4654 case RPC_FC_CHAR:
4655 case RPC_FC_SMALL:
4656 case RPC_FC_USMALL:
4657 pStubMsg->BufferLength += sizeof(UCHAR);
4658 break;
4659 case RPC_FC_WCHAR:
4660 case RPC_FC_SHORT:
4661 case RPC_FC_USHORT:
4662 case RPC_FC_ENUM16:
4663 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4664 pStubMsg->BufferLength += sizeof(USHORT);
4665 break;
4666 case RPC_FC_LONG:
4667 case RPC_FC_ULONG:
4668 case RPC_FC_ENUM32:
4669 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4670 pStubMsg->BufferLength += sizeof(ULONG);
4671 break;
4672 case RPC_FC_FLOAT:
4673 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4674 pStubMsg->BufferLength += sizeof(float);
4675 break;
4676 case RPC_FC_DOUBLE:
4677 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4678 pStubMsg->BufferLength += sizeof(double);
4679 break;
4680 case RPC_FC_HYPER:
4681 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4682 pStubMsg->BufferLength += sizeof(ULONGLONG);
4683 break;
4684 case RPC_FC_ERROR_STATUS_T:
4685 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4686 pStubMsg->BufferLength += sizeof(error_status_t);
4687 break;
4688 default:
4689 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4693 /***********************************************************************
4694 * NdrBaseTypeMemorySize [internal]
4696 static unsigned long WINAPI NdrBaseTypeMemorySize(
4697 PMIDL_STUB_MESSAGE pStubMsg,
4698 PFORMAT_STRING pFormat)
4700 switch(*pFormat)
4702 case RPC_FC_BYTE:
4703 case RPC_FC_CHAR:
4704 case RPC_FC_SMALL:
4705 case RPC_FC_USMALL:
4706 pStubMsg->Buffer += sizeof(UCHAR);
4707 pStubMsg->MemorySize += sizeof(UCHAR);
4708 return sizeof(UCHAR);
4709 case RPC_FC_WCHAR:
4710 case RPC_FC_SHORT:
4711 case RPC_FC_USHORT:
4712 pStubMsg->Buffer += sizeof(USHORT);
4713 pStubMsg->MemorySize += sizeof(USHORT);
4714 return sizeof(USHORT);
4715 case RPC_FC_LONG:
4716 case RPC_FC_ULONG:
4717 pStubMsg->Buffer += sizeof(ULONG);
4718 pStubMsg->MemorySize += sizeof(ULONG);
4719 return sizeof(ULONG);
4720 case RPC_FC_FLOAT:
4721 pStubMsg->Buffer += sizeof(float);
4722 pStubMsg->MemorySize += sizeof(float);
4723 return sizeof(float);
4724 case RPC_FC_DOUBLE:
4725 pStubMsg->Buffer += sizeof(double);
4726 pStubMsg->MemorySize += sizeof(double);
4727 return sizeof(double);
4728 case RPC_FC_HYPER:
4729 pStubMsg->Buffer += sizeof(ULONGLONG);
4730 pStubMsg->MemorySize += sizeof(ULONGLONG);
4731 return sizeof(ULONGLONG);
4732 case RPC_FC_ERROR_STATUS_T:
4733 pStubMsg->Buffer += sizeof(error_status_t);
4734 pStubMsg->MemorySize += sizeof(error_status_t);
4735 return sizeof(error_status_t);
4736 case RPC_FC_ENUM16:
4737 case RPC_FC_ENUM32:
4738 pStubMsg->Buffer += sizeof(INT);
4739 pStubMsg->MemorySize += sizeof(INT);
4740 return sizeof(INT);
4741 default:
4742 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4743 return 0;
4747 /***********************************************************************
4748 * NdrBaseTypeFree [internal]
4750 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4751 unsigned char *pMemory,
4752 PFORMAT_STRING pFormat)
4754 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4756 /* nothing to do */
4759 /***********************************************************************
4760 * NdrClientContextMarshall
4762 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4763 NDR_CCONTEXT ContextHandle,
4764 int fCheck)
4766 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
4768 ALIGN_POINTER(pStubMsg->Buffer, 4);
4770 /* FIXME: what does fCheck do? */
4771 NDRCContextMarshall(ContextHandle,
4772 pStubMsg->Buffer);
4774 pStubMsg->Buffer += cbNDRContext;
4777 /***********************************************************************
4778 * NdrClientContextUnmarshall
4780 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4781 NDR_CCONTEXT * pContextHandle,
4782 RPC_BINDING_HANDLE BindHandle)
4784 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
4786 ALIGN_POINTER(pStubMsg->Buffer, 4);
4788 NDRCContextUnmarshall(pContextHandle,
4789 BindHandle,
4790 pStubMsg->Buffer,
4791 pStubMsg->RpcMsg->DataRepresentation);
4793 pStubMsg->Buffer += cbNDRContext;
4796 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4797 NDR_SCONTEXT ContextHandle,
4798 NDR_RUNDOWN RundownRoutine )
4800 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4803 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4805 FIXME("(%p): stub\n", pStubMsg);
4806 return NULL;
4809 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4810 unsigned char* pMemory,
4811 PFORMAT_STRING pFormat)
4813 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
4816 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
4817 PFORMAT_STRING pFormat)
4819 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4820 return NULL;
4823 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4824 NDR_SCONTEXT ContextHandle,
4825 NDR_RUNDOWN RundownRoutine,
4826 PFORMAT_STRING pFormat)
4828 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
4831 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4832 PFORMAT_STRING pFormat)
4834 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4835 return NULL;
4838 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
4840 typedef struct ndr_context_handle
4842 DWORD attributes;
4843 GUID uuid;
4844 } ndr_context_handle;
4846 struct context_handle_entry
4848 struct list entry;
4849 DWORD magic;
4850 RPC_BINDING_HANDLE handle;
4851 ndr_context_handle wire_data;
4854 static struct list context_handle_list = LIST_INIT(context_handle_list);
4856 static CRITICAL_SECTION ndr_context_cs;
4857 static CRITICAL_SECTION_DEBUG ndr_context_debug =
4859 0, 0, &ndr_context_cs,
4860 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
4861 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
4863 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
4865 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
4867 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
4869 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
4870 return NULL;
4871 return che;
4874 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
4876 struct context_handle_entry *che;
4877 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
4878 if (IsEqualGUID(&che->wire_data.uuid, uuid))
4879 return che;
4880 return NULL;
4883 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
4885 struct context_handle_entry *che;
4886 RPC_BINDING_HANDLE handle = NULL;
4888 TRACE("%p\n", CContext);
4890 EnterCriticalSection(&ndr_context_cs);
4891 che = get_context_entry(CContext);
4892 if (che)
4893 handle = che->handle;
4894 LeaveCriticalSection(&ndr_context_cs);
4896 if (!handle)
4897 RpcRaiseException(ERROR_INVALID_HANDLE);
4898 return handle;
4901 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
4903 struct context_handle_entry *che;
4905 TRACE("%p %p\n", CContext, pBuff);
4907 if (CContext)
4909 EnterCriticalSection(&ndr_context_cs);
4910 che = get_context_entry(CContext);
4911 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
4912 LeaveCriticalSection(&ndr_context_cs);
4914 else
4916 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
4917 wire_data->attributes = 0;
4918 wire_data->uuid = GUID_NULL;
4922 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
4923 RPC_BINDING_HANDLE hBinding,
4924 ndr_context_handle *chi)
4926 struct context_handle_entry *che = NULL;
4928 /* a null UUID means we should free the context handle */
4929 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
4931 if (*CContext)
4933 che = get_context_entry(*CContext);
4934 if (!che)
4935 return ERROR_INVALID_HANDLE;
4936 list_remove(&che->entry);
4937 RpcBindingFree(&che->handle);
4938 HeapFree(GetProcessHeap(), 0, che);
4939 che = NULL;
4942 /* if there's no existing entry matching the GUID, allocate one */
4943 else if (!(che = context_entry_from_guid(&chi->uuid)))
4945 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
4946 if (!che)
4947 return ERROR_NOT_ENOUGH_MEMORY;
4948 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
4949 RpcBindingCopy(hBinding, &che->handle);
4950 list_add_tail(&context_handle_list, &che->entry);
4951 memcpy(&che->wire_data, chi, sizeof *chi);
4954 *CContext = che;
4956 return ERROR_SUCCESS;
4959 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
4960 RPC_BINDING_HANDLE hBinding,
4961 void *pBuff,
4962 unsigned long DataRepresentation)
4964 UINT r;
4966 TRACE("*%p=(%p) %p %p %08lx\n",
4967 CContext, *CContext, hBinding, pBuff, DataRepresentation);
4969 EnterCriticalSection(&ndr_context_cs);
4970 r = ndr_update_context_handle(CContext, hBinding, pBuff);
4971 LeaveCriticalSection(&ndr_context_cs);
4972 if (r)
4973 RpcRaiseException(r);
4976 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
4977 void *pBuff,
4978 NDR_RUNDOWN userRunDownIn)
4980 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
4983 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
4984 NDR_SCONTEXT CContext,
4985 void *pBuff,
4986 NDR_RUNDOWN userRunDownIn)
4988 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
4991 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
4992 NDR_SCONTEXT CContext,
4993 void *pBuff,
4994 NDR_RUNDOWN userRunDownIn,
4995 void *CtxGuard,
4996 unsigned long Flags)
4998 FIXME("(%p %p %p %p %p %lu): stub\n",
4999 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
5002 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
5003 unsigned long DataRepresentation)
5005 FIXME("(%p %08lx): stub\n", pBuff, DataRepresentation);
5006 return NULL;
5009 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
5010 void *pBuff,
5011 unsigned long DataRepresentation)
5013 FIXME("(%p %p %08lx): stub\n", hBinding, pBuff, DataRepresentation);
5014 return NULL;
5017 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
5018 void *pBuff,
5019 unsigned long DataRepresentation,
5020 void *CtxGuard,
5021 unsigned long Flags)
5023 FIXME("(%p %p %08lx %p %lu): stub\n",
5024 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
5025 return NULL;