rpcrt4: Freeing a NULL context handle is allowed.
[wine.git] / dlls / rpcrt4 / ndr_marshall.c
blob03f5c6c0b0353d7dfbbe704febba75ee7efe8629
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 * - Varying arrays
25 * - Encapsulated unions
26 * - Byte count pointers
27 * - transmit_as/represent as
28 * - Multi-dimensional arrays
29 * - Conversion functions (NdrConvert)
30 * - Checks for integer overflow when calculating array sizes
31 * - Checks for out-of-memory conditions
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <assert.h>
38 #include <limits.h>
40 #include "windef.h"
41 #include "winbase.h"
42 #include "winerror.h"
43 #include "winreg.h"
45 #include "ndr_misc.h"
46 #include "rpcndr.h"
48 #include "wine/unicode.h"
49 #include "wine/rpcfc.h"
51 #include "wine/debug.h"
52 #include "wine/list.h"
54 WINE_DEFAULT_DEBUG_CHANNEL(ole);
56 #if defined(__i386__)
57 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
58 (*((UINT32 *)(pchar)) = (uint32))
60 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
61 (*((UINT32 *)(pchar)))
62 #else
63 /* these would work for i386 too, but less efficient */
64 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
65 (*(pchar) = LOBYTE(LOWORD(uint32)), \
66 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
67 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
68 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
69 (uint32)) /* allow as r-value */
71 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
72 (MAKELONG( \
73 MAKEWORD(*(pchar), *((pchar)+1)), \
74 MAKEWORD(*((pchar)+2), *((pchar)+3))))
75 #endif
77 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
78 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
79 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
80 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
81 *(pchar) = HIBYTE(HIWORD(uint32)), \
82 (uint32)) /* allow as r-value */
84 #define BIG_ENDIAN_UINT32_READ(pchar) \
85 (MAKELONG( \
86 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
87 MAKEWORD(*((pchar)+1), *(pchar))))
89 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
90 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
91 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
92 # define NDR_LOCAL_UINT32_READ(pchar) \
93 BIG_ENDIAN_UINT32_READ(pchar)
94 #else
95 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
96 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
97 # define NDR_LOCAL_UINT32_READ(pchar) \
98 LITTLE_ENDIAN_UINT32_READ(pchar)
99 #endif
101 /* _Align must be the desired alignment,
102 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
103 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
104 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
105 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
106 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
108 #define STD_OVERFLOW_CHECK(_Msg) do { \
109 TRACE("buffer=%d/%ld\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
110 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
111 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
112 } while (0)
114 #define NDR_TABLE_SIZE 128
115 #define NDR_TABLE_MASK 127
117 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
119 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
121 static unsigned long WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
123 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
125 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
126 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
127 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
128 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
129 /* 0x10 */
130 NdrBaseTypeMarshall,
131 /* 0x11 */
132 NdrPointerMarshall, NdrPointerMarshall,
133 NdrPointerMarshall, NdrPointerMarshall,
134 /* 0x15 */
135 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
136 NdrConformantStructMarshall, NdrConformantStructMarshall,
137 NdrConformantVaryingStructMarshall,
138 NdrComplexStructMarshall,
139 /* 0x1b */
140 NdrConformantArrayMarshall,
141 NdrConformantVaryingArrayMarshall,
142 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
143 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
144 NdrComplexArrayMarshall,
145 /* 0x22 */
146 NdrConformantStringMarshall, 0, 0,
147 NdrConformantStringMarshall,
148 NdrNonConformantStringMarshall, 0, 0, 0,
149 /* 0x2a */
150 NdrEncapsulatedUnionMarshall,
151 NdrNonEncapsulatedUnionMarshall,
152 NdrByteCountPointerMarshall,
153 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
154 /* 0x2f */
155 NdrInterfacePointerMarshall,
156 /* 0xb0 */
157 0, 0, 0, 0,
158 NdrUserMarshalMarshall
160 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
162 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
163 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
164 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
165 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
166 /* 0x10 */
167 NdrBaseTypeUnmarshall,
168 /* 0x11 */
169 NdrPointerUnmarshall, NdrPointerUnmarshall,
170 NdrPointerUnmarshall, NdrPointerUnmarshall,
171 /* 0x15 */
172 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
173 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
174 NdrConformantVaryingStructUnmarshall,
175 NdrComplexStructUnmarshall,
176 /* 0x1b */
177 NdrConformantArrayUnmarshall,
178 NdrConformantVaryingArrayUnmarshall,
179 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
180 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
181 NdrComplexArrayUnmarshall,
182 /* 0x22 */
183 NdrConformantStringUnmarshall, 0, 0,
184 NdrConformantStringUnmarshall,
185 NdrNonConformantStringUnmarshall, 0, 0, 0,
186 /* 0x2a */
187 NdrEncapsulatedUnionUnmarshall,
188 NdrNonEncapsulatedUnionUnmarshall,
189 NdrByteCountPointerUnmarshall,
190 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
191 /* 0x2f */
192 NdrInterfacePointerUnmarshall,
193 /* 0xb0 */
194 0, 0, 0, 0,
195 NdrUserMarshalUnmarshall
197 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
199 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
200 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
201 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
202 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
203 /* 0x10 */
204 NdrBaseTypeBufferSize,
205 /* 0x11 */
206 NdrPointerBufferSize, NdrPointerBufferSize,
207 NdrPointerBufferSize, NdrPointerBufferSize,
208 /* 0x15 */
209 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
210 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
211 NdrConformantVaryingStructBufferSize,
212 NdrComplexStructBufferSize,
213 /* 0x1b */
214 NdrConformantArrayBufferSize,
215 NdrConformantVaryingArrayBufferSize,
216 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
217 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
218 NdrComplexArrayBufferSize,
219 /* 0x22 */
220 NdrConformantStringBufferSize, 0, 0,
221 NdrConformantStringBufferSize,
222 NdrNonConformantStringBufferSize, 0, 0, 0,
223 /* 0x2a */
224 NdrEncapsulatedUnionBufferSize,
225 NdrNonEncapsulatedUnionBufferSize,
226 NdrByteCountPointerBufferSize,
227 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
228 /* 0x2f */
229 NdrInterfacePointerBufferSize,
230 /* 0xb0 */
231 0, 0, 0, 0,
232 NdrUserMarshalBufferSize
234 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
236 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
237 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
238 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
239 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
240 /* 0x10 */
241 NdrBaseTypeMemorySize,
242 /* 0x11 */
243 NdrPointerMemorySize, NdrPointerMemorySize,
244 NdrPointerMemorySize, NdrPointerMemorySize,
245 /* 0x15 */
246 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
247 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
248 NdrConformantVaryingStructMemorySize,
249 NdrComplexStructMemorySize,
250 /* 0x1b */
251 NdrConformantArrayMemorySize,
252 NdrConformantVaryingArrayMemorySize,
253 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
254 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
255 NdrComplexArrayMemorySize,
256 /* 0x22 */
257 NdrConformantStringMemorySize, 0, 0,
258 NdrConformantStringMemorySize,
259 NdrNonConformantStringMemorySize, 0, 0, 0,
260 /* 0x2a */
261 NdrEncapsulatedUnionMemorySize,
262 NdrNonEncapsulatedUnionMemorySize,
263 NdrByteCountPointerMemorySize,
264 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
265 /* 0x2f */
266 NdrInterfacePointerMemorySize,
267 /* 0xb0 */
268 0, 0, 0, 0,
269 NdrUserMarshalMemorySize
271 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
273 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
274 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
275 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
276 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
277 /* 0x10 */
278 NdrBaseTypeFree,
279 /* 0x11 */
280 NdrPointerFree, NdrPointerFree,
281 NdrPointerFree, NdrPointerFree,
282 /* 0x15 */
283 NdrSimpleStructFree, NdrSimpleStructFree,
284 NdrConformantStructFree, NdrConformantStructFree,
285 NdrConformantVaryingStructFree,
286 NdrComplexStructFree,
287 /* 0x1b */
288 NdrConformantArrayFree,
289 NdrConformantVaryingArrayFree,
290 NdrFixedArrayFree, NdrFixedArrayFree,
291 NdrVaryingArrayFree, NdrVaryingArrayFree,
292 NdrComplexArrayFree,
293 /* 0x22 */
294 0, 0, 0,
295 0, 0, 0, 0, 0,
296 /* 0x2a */
297 NdrEncapsulatedUnionFree,
298 NdrNonEncapsulatedUnionFree,
300 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
301 /* 0x2f */
302 NdrInterfacePointerFree,
303 /* 0xb0 */
304 0, 0, 0, 0,
305 NdrUserMarshalFree
308 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
310 /* hmm, this is probably supposed to do more? */
311 return pStubMsg->pfnAllocate(len);
314 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
316 pStubMsg->pfnFree(Pointer);
319 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
321 return (*(const ULONG *)pFormat != -1);
324 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
326 ALIGN_POINTER(pStubMsg->Buffer, 4);
327 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
328 pStubMsg->Buffer += 4;
329 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
330 if (pStubMsg->fHasNewCorrDesc)
331 return pFormat+6;
332 else
333 return pFormat+4;
336 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
338 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
340 pStubMsg->Offset = 0;
341 pStubMsg->ActualCount = pStubMsg->MaxCount;
342 goto done;
345 ALIGN_POINTER(pStubMsg->Buffer, 4);
346 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
347 pStubMsg->Buffer += 4;
348 TRACE("offset is %ld\n", pStubMsg->Offset);
349 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
350 pStubMsg->Buffer += 4;
351 TRACE("variance is %ld\n", pStubMsg->ActualCount);
353 done:
354 if (pStubMsg->fHasNewCorrDesc)
355 return pFormat+6;
356 else
357 return pFormat+4;
360 /* writes the conformance value to the buffer */
361 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
363 ALIGN_POINTER(pStubMsg->Buffer, 4);
364 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
365 pStubMsg->Buffer += 4;
368 /* writes the variance values to the buffer */
369 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
371 ALIGN_POINTER(pStubMsg->Buffer, 4);
372 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
373 pStubMsg->Buffer += 4;
374 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
375 pStubMsg->Buffer += 4;
378 /* requests buffer space for the conformance value */
379 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
381 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
382 pStubMsg->BufferLength += 4;
385 /* requests buffer space for the variance values */
386 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
388 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
389 pStubMsg->BufferLength += 8;
392 PFORMAT_STRING ComputeConformanceOrVariance(
393 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
394 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount)
396 BYTE dtype = pFormat[0] & 0xf;
397 short ofs = *(short *)&pFormat[2];
398 LPVOID ptr = NULL;
399 DWORD data = 0;
401 if (!IsConformanceOrVariancePresent(pFormat)) {
402 /* null descriptor */
403 *pCount = def;
404 goto finish_conf;
407 switch (pFormat[0] & 0xf0) {
408 case RPC_FC_NORMAL_CONFORMANCE:
409 TRACE("normal conformance, ofs=%d\n", ofs);
410 ptr = pMemory;
411 break;
412 case RPC_FC_POINTER_CONFORMANCE:
413 TRACE("pointer conformance, ofs=%d\n", ofs);
414 ptr = pStubMsg->Memory;
415 break;
416 case RPC_FC_TOP_LEVEL_CONFORMANCE:
417 TRACE("toplevel conformance, ofs=%d\n", ofs);
418 if (pStubMsg->StackTop) {
419 ptr = pStubMsg->StackTop;
421 else {
422 /* -Os mode, *pCount is already set */
423 goto finish_conf;
425 break;
426 case RPC_FC_CONSTANT_CONFORMANCE:
427 data = ofs | ((DWORD)pFormat[1] << 16);
428 TRACE("constant conformance, val=%ld\n", data);
429 *pCount = data;
430 goto finish_conf;
431 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
432 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
433 if (pStubMsg->StackTop) {
434 ptr = pStubMsg->StackTop;
436 else {
437 /* ? */
438 goto done_conf_grab;
440 break;
441 default:
442 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
445 switch (pFormat[1]) {
446 case RPC_FC_DEREFERENCE:
447 ptr = *(LPVOID*)((char *)ptr + ofs);
448 break;
449 case RPC_FC_CALLBACK:
451 unsigned char *old_stack_top = pStubMsg->StackTop;
452 pStubMsg->StackTop = ptr;
454 /* ofs is index into StubDesc->apfnExprEval */
455 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
456 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
458 pStubMsg->StackTop = old_stack_top;
459 goto finish_conf;
461 default:
462 ptr = (char *)ptr + ofs;
463 break;
466 switch (dtype) {
467 case RPC_FC_LONG:
468 case RPC_FC_ULONG:
469 data = *(DWORD*)ptr;
470 break;
471 case RPC_FC_SHORT:
472 data = *(SHORT*)ptr;
473 break;
474 case RPC_FC_USHORT:
475 data = *(USHORT*)ptr;
476 break;
477 case RPC_FC_CHAR:
478 case RPC_FC_SMALL:
479 data = *(CHAR*)ptr;
480 break;
481 case RPC_FC_BYTE:
482 case RPC_FC_USMALL:
483 data = *(UCHAR*)ptr;
484 break;
485 default:
486 FIXME("unknown conformance data type %x\n", dtype);
487 goto done_conf_grab;
489 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
491 done_conf_grab:
492 switch (pFormat[1]) {
493 case RPC_FC_DEREFERENCE: /* already handled */
494 case 0: /* no op */
495 *pCount = data;
496 break;
497 case RPC_FC_ADD_1:
498 *pCount = data + 1;
499 break;
500 case RPC_FC_SUB_1:
501 *pCount = data - 1;
502 break;
503 case RPC_FC_MULT_2:
504 *pCount = data * 2;
505 break;
506 case RPC_FC_DIV_2:
507 *pCount = data / 2;
508 break;
509 default:
510 FIXME("unknown conformance op %d\n", pFormat[1]);
511 goto finish_conf;
514 finish_conf:
515 TRACE("resulting conformance is %ld\n", *pCount);
516 if (pStubMsg->fHasNewCorrDesc)
517 return pFormat+6;
518 else
519 return pFormat+4;
524 * NdrConformantString:
526 * What MS calls a ConformantString is, in DCE terminology,
527 * a Varying-Conformant String.
529 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
530 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
531 * into unmarshalled string)
532 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
533 * [
534 * data: CHARTYPE[maxlen]
535 * ]
536 * ], where CHARTYPE is the appropriate character type (specified externally)
540 /***********************************************************************
541 * NdrConformantStringMarshall [RPCRT4.@]
543 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
544 unsigned char *pszMessage, PFORMAT_STRING pFormat)
546 unsigned long esize;
548 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
550 if (*pFormat == RPC_FC_C_CSTRING) {
551 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
552 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
553 esize = 1;
555 else if (*pFormat == RPC_FC_C_WSTRING) {
556 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
557 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
558 esize = 2;
560 else {
561 ERR("Unhandled string type: %#x\n", *pFormat);
562 /* FIXME: raise an exception. */
563 return NULL;
566 if (pFormat[1] == RPC_FC_STRING_SIZED)
567 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
568 else
569 pStubMsg->MaxCount = pStubMsg->ActualCount;
570 pStubMsg->Offset = 0;
571 WriteConformance(pStubMsg);
572 WriteVariance(pStubMsg);
574 memcpy(pStubMsg->Buffer, pszMessage, pStubMsg->ActualCount*esize); /* the string itself */
575 pStubMsg->Buffer += pStubMsg->ActualCount*esize;
577 STD_OVERFLOW_CHECK(pStubMsg);
579 /* success */
580 return NULL; /* is this always right? */
583 /***********************************************************************
584 * NdrConformantStringBufferSize [RPCRT4.@]
586 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
587 unsigned char* pMemory, PFORMAT_STRING pFormat)
589 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
591 SizeConformance(pStubMsg);
592 SizeVariance(pStubMsg);
594 if (*pFormat == RPC_FC_C_CSTRING) {
595 /* we need + 1 octet for '\0' */
596 TRACE("string=%s\n", debugstr_a((char*)pMemory));
597 pStubMsg->BufferLength += strlen((char*)pMemory) + 1;
599 else if (*pFormat == RPC_FC_C_WSTRING) {
600 /* we need + 2 octets for L'\0' */
601 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
602 pStubMsg->BufferLength += strlenW((LPWSTR)pMemory)*2 + 2;
604 else {
605 ERR("Unhandled string type: %#x\n", *pFormat);
606 /* FIXME: raise an exception */
610 /************************************************************************
611 * NdrConformantStringMemorySize [RPCRT4.@]
613 unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
614 PFORMAT_STRING pFormat )
616 unsigned long rslt = 0;
618 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
620 assert(pStubMsg && pFormat);
622 if (*pFormat == RPC_FC_C_CSTRING) {
623 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
625 else if (*pFormat == RPC_FC_C_WSTRING) {
626 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
628 else {
629 ERR("Unhandled string type: %#x\n", *pFormat);
630 /* FIXME: raise an exception */
633 if (pFormat[1] != RPC_FC_PAD) {
634 FIXME("sized string format=%d\n", pFormat[1]);
637 TRACE(" --> %lu\n", rslt);
638 return rslt;
641 /************************************************************************
642 * NdrConformantStringUnmarshall [RPCRT4.@]
644 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
645 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
647 unsigned long len, esize;
649 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
650 pStubMsg, *ppMemory, pFormat, fMustAlloc);
652 assert(pFormat && ppMemory && pStubMsg);
654 ReadConformance(pStubMsg, NULL);
655 ReadVariance(pStubMsg, NULL);
657 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
658 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
659 else {
660 ERR("Unhandled string type: %#x\n", *pFormat);
661 /* FIXME: raise an exception */
662 esize = 0;
665 len = pStubMsg->ActualCount;
667 if (fMustAlloc || !*ppMemory)
668 *ppMemory = NdrAllocate(pStubMsg, len*esize);
670 memcpy(*ppMemory, pStubMsg->Buffer, len*esize);
672 pStubMsg->Buffer += len*esize;
674 if (*pFormat == RPC_FC_C_CSTRING) {
675 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
677 else if (*pFormat == RPC_FC_C_WSTRING) {
678 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
681 return NULL; /* FIXME: is this always right? */
684 /***********************************************************************
685 * NdrNonConformantStringMarshall [RPCRT4.@]
687 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
688 unsigned char *pMemory,
689 PFORMAT_STRING pFormat)
691 FIXME("stub\n");
692 return NULL;
695 /***********************************************************************
696 * NdrNonConformantStringUnmarshall [RPCRT4.@]
698 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
699 unsigned char **ppMemory,
700 PFORMAT_STRING pFormat,
701 unsigned char fMustAlloc)
703 FIXME("stub\n");
704 return NULL;
707 /***********************************************************************
708 * NdrNonConformantStringBufferSize [RPCRT4.@]
710 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
711 unsigned char *pMemory,
712 PFORMAT_STRING pFormat)
714 FIXME("stub\n");
717 /***********************************************************************
718 * NdrNonConformantStringMemorySize [RPCRT4.@]
720 unsigned long WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
721 PFORMAT_STRING pFormat)
723 FIXME("stub\n");
724 return 0;
727 static inline void dump_pointer_attr(unsigned char attr)
729 if (attr & RPC_FC_P_ALLOCALLNODES)
730 TRACE(" RPC_FC_P_ALLOCALLNODES");
731 if (attr & RPC_FC_P_DONTFREE)
732 TRACE(" RPC_FC_P_DONTFREE");
733 if (attr & RPC_FC_P_ONSTACK)
734 TRACE(" RPC_FC_P_ONSTACK");
735 if (attr & RPC_FC_P_SIMPLEPOINTER)
736 TRACE(" RPC_FC_P_SIMPLEPOINTER");
737 if (attr & RPC_FC_P_DEREF)
738 TRACE(" RPC_FC_P_DEREF");
739 TRACE("\n");
742 /***********************************************************************
743 * PointerMarshall
745 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
746 unsigned char *Buffer,
747 unsigned char *Pointer,
748 PFORMAT_STRING pFormat)
750 unsigned type = pFormat[0], attr = pFormat[1];
751 PFORMAT_STRING desc;
752 NDR_MARSHALL m;
753 unsigned long pointer_id;
754 int pointer_needs_marshaling;
756 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
757 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
758 pFormat += 2;
759 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
760 else desc = pFormat + *(const SHORT*)pFormat;
762 switch (type) {
763 case RPC_FC_RP: /* ref pointer (always non-null) */
764 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
765 if (!Pointer)
766 RpcRaiseException(RPC_X_NULL_REF_POINTER);
767 #endif
768 pointer_needs_marshaling = 1;
769 break;
770 case RPC_FC_UP: /* unique pointer */
771 case RPC_FC_OP: /* object pointer - same as unique here */
772 if (Pointer)
773 pointer_needs_marshaling = 1;
774 else
775 pointer_needs_marshaling = 0;
776 pointer_id = (unsigned long)Pointer;
777 TRACE("writing 0x%08lx to buffer\n", pointer_id);
778 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
779 break;
780 case RPC_FC_FP:
781 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
782 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
783 TRACE("writing 0x%08lx to buffer\n", pointer_id);
784 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
785 break;
786 default:
787 FIXME("unhandled ptr type=%02x\n", type);
788 RpcRaiseException(RPC_X_BAD_STUB_DATA);
789 return;
792 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
794 if (pointer_needs_marshaling) {
795 if (attr & RPC_FC_P_DEREF) {
796 Pointer = *(unsigned char**)Pointer;
797 TRACE("deref => %p\n", Pointer);
799 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
800 if (m) m(pStubMsg, Pointer, desc);
801 else FIXME("no marshaller for data type=%02x\n", *desc);
804 STD_OVERFLOW_CHECK(pStubMsg);
807 /***********************************************************************
808 * PointerUnmarshall
810 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
811 unsigned char *Buffer,
812 unsigned char **pPointer,
813 PFORMAT_STRING pFormat,
814 unsigned char fMustAlloc)
816 unsigned type = pFormat[0], attr = pFormat[1];
817 PFORMAT_STRING desc;
818 NDR_UNMARSHALL m;
819 DWORD pointer_id = 0;
820 int pointer_needs_unmarshaling;
822 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
823 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
824 pFormat += 2;
825 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
826 else desc = pFormat + *(const SHORT*)pFormat;
828 switch (type) {
829 case RPC_FC_RP: /* ref pointer (always non-null) */
830 pointer_needs_unmarshaling = 1;
831 break;
832 case RPC_FC_UP: /* unique pointer */
833 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
834 TRACE("pointer_id is 0x%08lx\n", pointer_id);
835 if (pointer_id)
836 pointer_needs_unmarshaling = 1;
837 else {
838 *pPointer = NULL;
839 pointer_needs_unmarshaling = 0;
841 break;
842 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
843 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
844 TRACE("pointer_id is 0x%08lx\n", pointer_id);
845 if (!fMustAlloc && *pPointer)
846 FIXME("free object pointer %p\n", *pPointer);
847 if (pointer_id)
848 pointer_needs_unmarshaling = 1;
849 else
850 pointer_needs_unmarshaling = 0;
851 break;
852 case RPC_FC_FP:
853 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
854 TRACE("pointer_id is 0x%08lx\n", pointer_id);
855 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
856 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
857 break;
858 default:
859 FIXME("unhandled ptr type=%02x\n", type);
860 RpcRaiseException(RPC_X_BAD_STUB_DATA);
861 return;
864 if (pointer_needs_unmarshaling) {
865 if (attr & RPC_FC_P_DEREF) {
866 if (!*pPointer || fMustAlloc)
867 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
868 pPointer = *(unsigned char***)pPointer;
869 TRACE("deref => %p\n", pPointer);
871 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
872 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
873 else FIXME("no unmarshaller for data type=%02x\n", *desc);
875 if (type == RPC_FC_FP)
876 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
877 *pPointer);
880 TRACE("pointer=%p\n", *pPointer);
883 /***********************************************************************
884 * PointerBufferSize
886 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
887 unsigned char *Pointer,
888 PFORMAT_STRING pFormat)
890 unsigned type = pFormat[0], attr = pFormat[1];
891 PFORMAT_STRING desc;
892 NDR_BUFFERSIZE m;
893 int pointer_needs_sizing;
894 unsigned long pointer_id;
896 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
897 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
898 pFormat += 2;
899 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
900 else desc = pFormat + *(const SHORT*)pFormat;
902 switch (type) {
903 case RPC_FC_RP: /* ref pointer (always non-null) */
904 break;
905 case RPC_FC_OP:
906 case RPC_FC_UP:
907 /* NULL pointer has no further representation */
908 if (!Pointer)
909 return;
910 break;
911 case RPC_FC_FP:
912 pointer_needs_sizing = !NdrFullPointerQueryPointer(
913 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
914 if (!pointer_needs_sizing)
915 return;
916 break;
917 default:
918 FIXME("unhandled ptr type=%02x\n", type);
919 RpcRaiseException(RPC_X_BAD_STUB_DATA);
920 return;
923 if (attr & RPC_FC_P_DEREF) {
924 Pointer = *(unsigned char**)Pointer;
925 TRACE("deref => %p\n", Pointer);
928 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
929 if (m) m(pStubMsg, Pointer, desc);
930 else FIXME("no buffersizer for data type=%02x\n", *desc);
933 /***********************************************************************
934 * PointerMemorySize [RPCRT4.@]
936 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
937 unsigned char *Buffer,
938 PFORMAT_STRING pFormat)
940 unsigned type = pFormat[0], attr = pFormat[1];
941 PFORMAT_STRING desc;
942 NDR_MEMORYSIZE m;
944 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
945 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
946 pFormat += 2;
947 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
948 else desc = pFormat + *(const SHORT*)pFormat;
950 switch (type) {
951 case RPC_FC_RP: /* ref pointer (always non-null) */
952 break;
953 default:
954 FIXME("unhandled ptr type=%02x\n", type);
955 RpcRaiseException(RPC_X_BAD_STUB_DATA);
958 if (attr & RPC_FC_P_DEREF) {
959 TRACE("deref\n");
962 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
963 if (m) m(pStubMsg, desc);
964 else FIXME("no memorysizer for data type=%02x\n", *desc);
966 return 0;
969 /***********************************************************************
970 * PointerFree [RPCRT4.@]
972 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
973 unsigned char *Pointer,
974 PFORMAT_STRING pFormat)
976 unsigned type = pFormat[0], attr = pFormat[1];
977 PFORMAT_STRING desc;
978 NDR_FREE m;
980 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
981 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
982 if (attr & RPC_FC_P_DONTFREE) return;
983 pFormat += 2;
984 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
985 else desc = pFormat + *(const SHORT*)pFormat;
987 if (!Pointer) return;
989 if (type == RPC_FC_FP) {
990 int pointer_needs_freeing = NdrFullPointerFree(
991 pStubMsg->FullPtrXlatTables, Pointer);
992 if (!pointer_needs_freeing)
993 return;
996 if (attr & RPC_FC_P_DEREF) {
997 Pointer = *(unsigned char**)Pointer;
998 TRACE("deref => %p\n", Pointer);
1001 m = NdrFreer[*desc & NDR_TABLE_MASK];
1002 if (m) m(pStubMsg, Pointer, desc);
1004 /* hmm... is this sensible?
1005 * perhaps we should check if the memory comes from NdrAllocate,
1006 * and deallocate only if so - checking if the pointer is between
1007 * BufferStart and BufferEnd is probably no good since the buffer
1008 * may be reallocated when the server wants to marshal the reply */
1009 switch (*desc) {
1010 case RPC_FC_BOGUS_STRUCT:
1011 case RPC_FC_BOGUS_ARRAY:
1012 case RPC_FC_USER_MARSHAL:
1013 case RPC_FC_CARRAY:
1014 case RPC_FC_CVARRAY:
1015 break;
1016 default:
1017 FIXME("unhandled data type=%02x\n", *desc);
1018 break;
1019 case RPC_FC_C_CSTRING:
1020 case RPC_FC_C_WSTRING:
1021 if (pStubMsg->ReuseBuffer) goto notfree;
1022 break;
1023 case RPC_FC_IP:
1024 goto notfree;
1027 if (attr & RPC_FC_P_ONSTACK) {
1028 TRACE("not freeing stack ptr %p\n", Pointer);
1029 return;
1031 TRACE("freeing %p\n", Pointer);
1032 NdrFree(pStubMsg, Pointer);
1033 return;
1034 notfree:
1035 TRACE("not freeing %p\n", Pointer);
1038 /***********************************************************************
1039 * EmbeddedPointerMarshall
1041 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1042 unsigned char *pMemory,
1043 PFORMAT_STRING pFormat)
1045 unsigned char *Mark = pStubMsg->BufferMark;
1046 unsigned long Offset = pStubMsg->Offset;
1047 unsigned ofs, rep, count, stride, xofs;
1048 unsigned i;
1050 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1052 if (*pFormat != RPC_FC_PP) return NULL;
1053 pFormat += 2;
1055 while (pFormat[0] != RPC_FC_END) {
1056 switch (pFormat[0]) {
1057 default:
1058 FIXME("unknown repeat type %d\n", pFormat[0]);
1059 case RPC_FC_NO_REPEAT:
1060 rep = 1;
1061 stride = 0;
1062 ofs = 0;
1063 count = 1;
1064 xofs = 0;
1065 pFormat += 2;
1066 break;
1067 case RPC_FC_FIXED_REPEAT:
1068 rep = *(const WORD*)&pFormat[2];
1069 stride = *(const WORD*)&pFormat[4];
1070 ofs = *(const WORD*)&pFormat[6];
1071 count = *(const WORD*)&pFormat[8];
1072 xofs = 0;
1073 pFormat += 10;
1074 break;
1075 case RPC_FC_VARIABLE_REPEAT:
1076 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1077 stride = *(const WORD*)&pFormat[2];
1078 ofs = *(const WORD*)&pFormat[4];
1079 count = *(const WORD*)&pFormat[6];
1080 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1081 pFormat += 8;
1082 break;
1084 for (i = 0; i < rep; i++) {
1085 PFORMAT_STRING info = pFormat;
1086 unsigned char *membase = pMemory + (i * stride);
1087 unsigned char *bufbase = Mark + (i * stride);
1088 unsigned u;
1089 /* ofs doesn't seem to matter in this context */
1090 for (u=0; u<count; u++,info+=8) {
1091 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1092 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1093 unsigned char *saved_memory = pStubMsg->Memory;
1095 pStubMsg->Memory = pMemory;
1096 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1097 pStubMsg->Memory = saved_memory;
1100 pFormat += 8 * count;
1103 STD_OVERFLOW_CHECK(pStubMsg);
1105 return NULL;
1108 /***********************************************************************
1109 * EmbeddedPointerUnmarshall
1111 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1112 unsigned char **ppMemory,
1113 PFORMAT_STRING pFormat,
1114 unsigned char fMustAlloc)
1116 unsigned char *Mark = pStubMsg->BufferMark;
1117 unsigned long Offset = pStubMsg->Offset;
1118 unsigned ofs, rep, count, stride, xofs;
1119 unsigned i;
1121 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1123 if (*pFormat != RPC_FC_PP) return NULL;
1124 pFormat += 2;
1126 while (pFormat[0] != RPC_FC_END) {
1127 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1128 switch (pFormat[0]) {
1129 default:
1130 FIXME("unknown repeat type %d\n", pFormat[0]);
1131 case RPC_FC_NO_REPEAT:
1132 rep = 1;
1133 stride = 0;
1134 ofs = 0;
1135 count = 1;
1136 xofs = 0;
1137 pFormat += 2;
1138 break;
1139 case RPC_FC_FIXED_REPEAT:
1140 rep = *(const WORD*)&pFormat[2];
1141 stride = *(const WORD*)&pFormat[4];
1142 ofs = *(const WORD*)&pFormat[6];
1143 count = *(const WORD*)&pFormat[8];
1144 xofs = 0;
1145 pFormat += 10;
1146 break;
1147 case RPC_FC_VARIABLE_REPEAT:
1148 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1149 stride = *(const WORD*)&pFormat[2];
1150 ofs = *(const WORD*)&pFormat[4];
1151 count = *(const WORD*)&pFormat[6];
1152 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1153 pFormat += 8;
1154 break;
1156 /* ofs doesn't seem to matter in this context */
1157 for (i = 0; i < rep; i++) {
1158 PFORMAT_STRING info = pFormat;
1159 unsigned char *membase = *ppMemory + (i * stride);
1160 unsigned char *bufbase = Mark + (i * stride);
1161 unsigned u;
1162 for (u=0; u<count; u++,info+=8) {
1163 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1164 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1165 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1168 pFormat += 8 * count;
1171 return NULL;
1174 /***********************************************************************
1175 * EmbeddedPointerBufferSize
1177 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1178 unsigned char *pMemory,
1179 PFORMAT_STRING pFormat)
1181 unsigned long Offset = pStubMsg->Offset;
1182 unsigned ofs, rep, count, stride, xofs;
1183 unsigned i;
1185 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1187 if (pStubMsg->IgnoreEmbeddedPointers) return;
1189 if (*pFormat != RPC_FC_PP) return;
1190 pFormat += 2;
1192 while (pFormat[0] != RPC_FC_END) {
1193 switch (pFormat[0]) {
1194 default:
1195 FIXME("unknown repeat type %d\n", pFormat[0]);
1196 case RPC_FC_NO_REPEAT:
1197 rep = 1;
1198 stride = 0;
1199 ofs = 0;
1200 count = 1;
1201 xofs = 0;
1202 pFormat += 2;
1203 break;
1204 case RPC_FC_FIXED_REPEAT:
1205 rep = *(const WORD*)&pFormat[2];
1206 stride = *(const WORD*)&pFormat[4];
1207 ofs = *(const WORD*)&pFormat[6];
1208 count = *(const WORD*)&pFormat[8];
1209 xofs = 0;
1210 pFormat += 10;
1211 break;
1212 case RPC_FC_VARIABLE_REPEAT:
1213 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1214 stride = *(const WORD*)&pFormat[2];
1215 ofs = *(const WORD*)&pFormat[4];
1216 count = *(const WORD*)&pFormat[6];
1217 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1218 pFormat += 8;
1219 break;
1221 /* ofs doesn't seem to matter in this context */
1222 for (i = 0; i < rep; i++) {
1223 PFORMAT_STRING info = pFormat;
1224 unsigned char *membase = pMemory + (i * stride);
1225 unsigned u;
1226 for (u=0; u<count; u++,info+=8) {
1227 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1228 unsigned char *saved_memory = pStubMsg->Memory;
1230 pStubMsg->Memory = pMemory;
1231 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1232 pStubMsg->Memory = saved_memory;
1235 pFormat += 8 * count;
1239 /***********************************************************************
1240 * EmbeddedPointerMemorySize
1242 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1243 PFORMAT_STRING pFormat)
1245 unsigned long Offset = pStubMsg->Offset;
1246 unsigned char *Mark = pStubMsg->BufferMark;
1247 unsigned ofs, rep, count, stride, xofs;
1248 unsigned i;
1250 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1252 if (*pFormat != RPC_FC_PP) return 0;
1253 pFormat += 2;
1255 while (pFormat[0] != RPC_FC_END) {
1256 switch (pFormat[0]) {
1257 default:
1258 FIXME("unknown repeat type %d\n", pFormat[0]);
1259 case RPC_FC_NO_REPEAT:
1260 rep = 1;
1261 stride = 0;
1262 ofs = 0;
1263 count = 1;
1264 xofs = 0;
1265 pFormat += 2;
1266 break;
1267 case RPC_FC_FIXED_REPEAT:
1268 rep = *(const WORD*)&pFormat[2];
1269 stride = *(const WORD*)&pFormat[4];
1270 ofs = *(const WORD*)&pFormat[6];
1271 count = *(const WORD*)&pFormat[8];
1272 xofs = 0;
1273 pFormat += 10;
1274 break;
1275 case RPC_FC_VARIABLE_REPEAT:
1276 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1277 stride = *(const WORD*)&pFormat[2];
1278 ofs = *(const WORD*)&pFormat[4];
1279 count = *(const WORD*)&pFormat[6];
1280 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1281 pFormat += 8;
1282 break;
1284 /* ofs doesn't seem to matter in this context */
1285 for (i = 0; i < rep; i++) {
1286 PFORMAT_STRING info = pFormat;
1287 unsigned char *bufbase = Mark + (i * stride);
1288 unsigned u;
1289 for (u=0; u<count; u++,info+=8) {
1290 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1291 PointerMemorySize(pStubMsg, bufptr, info+4);
1294 pFormat += 8 * count;
1297 return 0;
1300 /***********************************************************************
1301 * EmbeddedPointerFree
1303 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1304 unsigned char *pMemory,
1305 PFORMAT_STRING pFormat)
1307 unsigned long Offset = pStubMsg->Offset;
1308 unsigned ofs, rep, count, stride, xofs;
1309 unsigned i;
1311 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1312 if (*pFormat != RPC_FC_PP) return;
1313 pFormat += 2;
1315 while (pFormat[0] != RPC_FC_END) {
1316 switch (pFormat[0]) {
1317 default:
1318 FIXME("unknown repeat type %d\n", pFormat[0]);
1319 case RPC_FC_NO_REPEAT:
1320 rep = 1;
1321 stride = 0;
1322 ofs = 0;
1323 count = 1;
1324 xofs = 0;
1325 pFormat += 2;
1326 break;
1327 case RPC_FC_FIXED_REPEAT:
1328 rep = *(const WORD*)&pFormat[2];
1329 stride = *(const WORD*)&pFormat[4];
1330 ofs = *(const WORD*)&pFormat[6];
1331 count = *(const WORD*)&pFormat[8];
1332 xofs = 0;
1333 pFormat += 10;
1334 break;
1335 case RPC_FC_VARIABLE_REPEAT:
1336 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1337 stride = *(const WORD*)&pFormat[2];
1338 ofs = *(const WORD*)&pFormat[4];
1339 count = *(const WORD*)&pFormat[6];
1340 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1341 pFormat += 8;
1342 break;
1344 /* ofs doesn't seem to matter in this context */
1345 for (i = 0; i < rep; i++) {
1346 PFORMAT_STRING info = pFormat;
1347 unsigned char *membase = pMemory + (i * stride);
1348 unsigned u;
1349 for (u=0; u<count; u++,info+=8) {
1350 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1351 unsigned char *saved_memory = pStubMsg->Memory;
1353 pStubMsg->Memory = pMemory;
1354 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1355 pStubMsg->Memory = saved_memory;
1358 pFormat += 8 * count;
1362 /***********************************************************************
1363 * NdrPointerMarshall [RPCRT4.@]
1365 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1366 unsigned char *pMemory,
1367 PFORMAT_STRING pFormat)
1369 unsigned char *Buffer;
1371 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1373 /* incremement the buffer here instead of in PointerMarshall,
1374 * as that is used by embedded pointers which already handle the incrementing
1375 * the buffer, and shouldn't write any additional pointer data to the wire */
1376 if (*pFormat != RPC_FC_RP)
1378 ALIGN_POINTER(pStubMsg->Buffer, 4);
1379 Buffer = pStubMsg->Buffer;
1380 pStubMsg->Buffer += 4;
1382 else
1383 Buffer = pStubMsg->Buffer;
1385 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1387 STD_OVERFLOW_CHECK(pStubMsg);
1389 return NULL;
1392 /***********************************************************************
1393 * NdrPointerUnmarshall [RPCRT4.@]
1395 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1396 unsigned char **ppMemory,
1397 PFORMAT_STRING pFormat,
1398 unsigned char fMustAlloc)
1400 unsigned char *Buffer;
1402 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1404 /* incremement the buffer here instead of in PointerUnmarshall,
1405 * as that is used by embedded pointers which already handle the incrementing
1406 * the buffer, and shouldn't read any additional pointer data from the
1407 * buffer */
1408 if (*pFormat != RPC_FC_RP)
1410 ALIGN_POINTER(pStubMsg->Buffer, 4);
1411 Buffer = pStubMsg->Buffer;
1412 pStubMsg->Buffer += 4;
1414 else
1415 Buffer = pStubMsg->Buffer;
1417 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1419 return NULL;
1422 /***********************************************************************
1423 * NdrPointerBufferSize [RPCRT4.@]
1425 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1426 unsigned char *pMemory,
1427 PFORMAT_STRING pFormat)
1429 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1431 /* incremement the buffer length here instead of in PointerBufferSize,
1432 * as that is used by embedded pointers which already handle the buffer
1433 * length, and shouldn't write anything more to the wire */
1434 if (*pFormat != RPC_FC_RP)
1436 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1437 pStubMsg->BufferLength += 4;
1440 PointerBufferSize(pStubMsg, pMemory, pFormat);
1443 /***********************************************************************
1444 * NdrPointerMemorySize [RPCRT4.@]
1446 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1447 PFORMAT_STRING pFormat)
1449 /* unsigned size = *(LPWORD)(pFormat+2); */
1450 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1451 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1452 return 0;
1455 /***********************************************************************
1456 * NdrPointerFree [RPCRT4.@]
1458 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1459 unsigned char *pMemory,
1460 PFORMAT_STRING pFormat)
1462 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1463 PointerFree(pStubMsg, pMemory, pFormat);
1466 /***********************************************************************
1467 * NdrSimpleTypeMarshall [RPCRT4.@]
1469 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1470 unsigned char FormatChar )
1472 FIXME("stub\n");
1475 /***********************************************************************
1476 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1478 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1479 unsigned char FormatChar )
1481 FIXME("stub\n");
1484 /***********************************************************************
1485 * NdrSimpleStructMarshall [RPCRT4.@]
1487 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1488 unsigned char *pMemory,
1489 PFORMAT_STRING pFormat)
1491 unsigned size = *(const WORD*)(pFormat+2);
1492 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1494 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1496 memcpy(pStubMsg->Buffer, pMemory, size);
1497 pStubMsg->BufferMark = pStubMsg->Buffer;
1498 pStubMsg->Buffer += size;
1500 if (pFormat[0] != RPC_FC_STRUCT)
1501 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1503 STD_OVERFLOW_CHECK(pStubMsg);
1505 return NULL;
1508 /***********************************************************************
1509 * NdrSimpleStructUnmarshall [RPCRT4.@]
1511 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1512 unsigned char **ppMemory,
1513 PFORMAT_STRING pFormat,
1514 unsigned char fMustAlloc)
1516 unsigned size = *(const WORD*)(pFormat+2);
1517 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1519 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1521 if (fMustAlloc) {
1522 *ppMemory = NdrAllocate(pStubMsg, size);
1523 memcpy(*ppMemory, pStubMsg->Buffer, size);
1524 } else {
1525 if (!pStubMsg->IsClient && !*ppMemory)
1526 /* for servers, we just point straight into the RPC buffer */
1527 *ppMemory = pStubMsg->Buffer;
1528 else
1529 /* for clients, memory should be provided by caller */
1530 memcpy(*ppMemory, pStubMsg->Buffer, size);
1533 pStubMsg->BufferMark = pStubMsg->Buffer;
1534 pStubMsg->Buffer += size;
1536 if (pFormat[0] != RPC_FC_STRUCT)
1537 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1539 return NULL;
1542 /***********************************************************************
1543 * NdrSimpleStructBufferSize [RPCRT4.@]
1545 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1546 unsigned char *pMemory,
1547 PFORMAT_STRING pFormat)
1549 unsigned size = *(const WORD*)(pFormat+2);
1550 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1552 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1554 pStubMsg->BufferLength += size;
1555 if (pFormat[0] != RPC_FC_STRUCT)
1556 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1559 /***********************************************************************
1560 * NdrSimpleStructMemorySize [RPCRT4.@]
1562 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1563 PFORMAT_STRING pFormat)
1565 unsigned short size = *(LPWORD)(pFormat+2);
1567 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1569 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1570 pStubMsg->MemorySize += size;
1571 pStubMsg->Buffer += size;
1573 if (pFormat[0] != RPC_FC_STRUCT)
1574 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1575 return size;
1578 /***********************************************************************
1579 * NdrSimpleStructFree [RPCRT4.@]
1581 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1582 unsigned char *pMemory,
1583 PFORMAT_STRING pFormat)
1585 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1586 if (pFormat[0] != RPC_FC_STRUCT)
1587 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1591 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1592 PFORMAT_STRING pFormat)
1594 switch (*pFormat) {
1595 case RPC_FC_STRUCT:
1596 case RPC_FC_PSTRUCT:
1597 case RPC_FC_CSTRUCT:
1598 case RPC_FC_BOGUS_STRUCT:
1599 return *(const WORD*)&pFormat[2];
1600 case RPC_FC_USER_MARSHAL:
1601 return *(const WORD*)&pFormat[4];
1602 case RPC_FC_NON_ENCAPSULATED_UNION:
1603 pFormat += 2;
1604 if (pStubMsg->fHasNewCorrDesc)
1605 pFormat += 6;
1606 else
1607 pFormat += 4;
1609 pFormat += *(const SHORT*)pFormat;
1610 return *(const SHORT*)pFormat;
1611 case RPC_FC_IP:
1612 return sizeof(void *);
1613 default:
1614 FIXME("unhandled embedded type %02x\n", *pFormat);
1616 return 0;
1620 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1621 PFORMAT_STRING pFormat)
1623 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1625 if (!m)
1627 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1628 return 0;
1631 return m(pStubMsg, pFormat);
1635 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1636 unsigned char *pMemory,
1637 PFORMAT_STRING pFormat,
1638 PFORMAT_STRING pPointer)
1640 PFORMAT_STRING desc;
1641 NDR_MARSHALL m;
1642 unsigned long size;
1644 while (*pFormat != RPC_FC_END) {
1645 switch (*pFormat) {
1646 case RPC_FC_SHORT:
1647 case RPC_FC_USHORT:
1648 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1649 memcpy(pStubMsg->Buffer, pMemory, 2);
1650 pStubMsg->Buffer += 2;
1651 pMemory += 2;
1652 break;
1653 case RPC_FC_LONG:
1654 case RPC_FC_ULONG:
1655 case RPC_FC_ENUM32:
1656 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1657 memcpy(pStubMsg->Buffer, pMemory, 4);
1658 pStubMsg->Buffer += 4;
1659 pMemory += 4;
1660 break;
1661 case RPC_FC_POINTER:
1662 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1663 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1664 pPointer += 4;
1665 pMemory += 4;
1666 break;
1667 case RPC_FC_ALIGNM4:
1668 ALIGN_POINTER(pMemory, 4);
1669 break;
1670 case RPC_FC_ALIGNM8:
1671 ALIGN_POINTER(pMemory, 8);
1672 break;
1673 case RPC_FC_STRUCTPAD2:
1674 pMemory += 2;
1675 break;
1676 case RPC_FC_EMBEDDED_COMPLEX:
1677 pMemory += pFormat[1];
1678 pFormat += 2;
1679 desc = pFormat + *(const SHORT*)pFormat;
1680 size = EmbeddedComplexSize(pStubMsg, desc);
1681 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1682 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1683 if (m) m(pStubMsg, pMemory, desc);
1684 else FIXME("no marshaller for embedded type %02x\n", *desc);
1685 pMemory += size;
1686 pFormat += 2;
1687 continue;
1688 case RPC_FC_PAD:
1689 break;
1690 default:
1691 FIXME("unhandled format %02x\n", *pFormat);
1693 pFormat++;
1696 return pMemory;
1699 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1700 unsigned char *pMemory,
1701 PFORMAT_STRING pFormat,
1702 PFORMAT_STRING pPointer)
1704 PFORMAT_STRING desc;
1705 NDR_UNMARSHALL m;
1706 unsigned long size;
1708 while (*pFormat != RPC_FC_END) {
1709 switch (*pFormat) {
1710 case RPC_FC_SHORT:
1711 case RPC_FC_USHORT:
1712 memcpy(pMemory, pStubMsg->Buffer, 2);
1713 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1714 pStubMsg->Buffer += 2;
1715 pMemory += 2;
1716 break;
1717 case RPC_FC_LONG:
1718 case RPC_FC_ULONG:
1719 case RPC_FC_ENUM32:
1720 memcpy(pMemory, pStubMsg->Buffer, 4);
1721 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1722 pStubMsg->Buffer += 4;
1723 pMemory += 4;
1724 break;
1725 case RPC_FC_POINTER:
1726 TRACE("pointer => %p\n", pMemory);
1727 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1728 pPointer += 4;
1729 pMemory += 4;
1730 break;
1731 case RPC_FC_ALIGNM4:
1732 ALIGN_POINTER(pMemory, 4);
1733 break;
1734 case RPC_FC_ALIGNM8:
1735 ALIGN_POINTER(pMemory, 8);
1736 break;
1737 case RPC_FC_STRUCTPAD2:
1738 pMemory += 2;
1739 break;
1740 case RPC_FC_EMBEDDED_COMPLEX:
1741 pMemory += pFormat[1];
1742 pFormat += 2;
1743 desc = pFormat + *(const SHORT*)pFormat;
1744 size = EmbeddedComplexSize(pStubMsg, desc);
1745 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1746 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1747 memset(pMemory, 0, size); /* just in case */
1748 if (m) m(pStubMsg, &pMemory, desc, FALSE);
1749 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1750 pMemory += size;
1751 pFormat += 2;
1752 continue;
1753 case RPC_FC_PAD:
1754 break;
1755 default:
1756 FIXME("unhandled format %d\n", *pFormat);
1758 pFormat++;
1761 return pMemory;
1764 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1765 unsigned char *pMemory,
1766 PFORMAT_STRING pFormat,
1767 PFORMAT_STRING pPointer)
1769 PFORMAT_STRING desc;
1770 NDR_BUFFERSIZE m;
1771 unsigned long size;
1773 while (*pFormat != RPC_FC_END) {
1774 switch (*pFormat) {
1775 case RPC_FC_SHORT:
1776 case RPC_FC_USHORT:
1777 pStubMsg->BufferLength += 2;
1778 pMemory += 2;
1779 break;
1780 case RPC_FC_LONG:
1781 case RPC_FC_ULONG:
1782 case RPC_FC_ENUM32:
1783 pStubMsg->BufferLength += 4;
1784 pMemory += 4;
1785 break;
1786 case RPC_FC_POINTER:
1787 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1788 pPointer += 4;
1789 pMemory += 4;
1790 break;
1791 case RPC_FC_ALIGNM4:
1792 ALIGN_POINTER(pMemory, 4);
1793 break;
1794 case RPC_FC_ALIGNM8:
1795 ALIGN_POINTER(pMemory, 8);
1796 break;
1797 case RPC_FC_STRUCTPAD2:
1798 pMemory += 2;
1799 break;
1800 case RPC_FC_EMBEDDED_COMPLEX:
1801 pMemory += pFormat[1];
1802 pFormat += 2;
1803 desc = pFormat + *(const SHORT*)pFormat;
1804 size = EmbeddedComplexSize(pStubMsg, desc);
1805 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1806 if (m) m(pStubMsg, pMemory, desc);
1807 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1808 pMemory += size;
1809 pFormat += 2;
1810 continue;
1811 case RPC_FC_PAD:
1812 break;
1813 default:
1814 FIXME("unhandled format %d\n", *pFormat);
1816 pFormat++;
1819 return pMemory;
1822 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1823 unsigned char *pMemory,
1824 PFORMAT_STRING pFormat,
1825 PFORMAT_STRING pPointer)
1827 PFORMAT_STRING desc;
1828 NDR_FREE m;
1829 unsigned long size;
1831 while (*pFormat != RPC_FC_END) {
1832 switch (*pFormat) {
1833 case RPC_FC_SHORT:
1834 case RPC_FC_USHORT:
1835 pMemory += 2;
1836 break;
1837 case RPC_FC_LONG:
1838 case RPC_FC_ULONG:
1839 case RPC_FC_ENUM32:
1840 pMemory += 4;
1841 break;
1842 case RPC_FC_POINTER:
1843 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1844 pPointer += 4;
1845 pMemory += 4;
1846 break;
1847 case RPC_FC_ALIGNM4:
1848 ALIGN_POINTER(pMemory, 4);
1849 break;
1850 case RPC_FC_ALIGNM8:
1851 ALIGN_POINTER(pMemory, 8);
1852 break;
1853 case RPC_FC_STRUCTPAD2:
1854 pMemory += 2;
1855 break;
1856 case RPC_FC_EMBEDDED_COMPLEX:
1857 pMemory += pFormat[1];
1858 pFormat += 2;
1859 desc = pFormat + *(const SHORT*)pFormat;
1860 size = EmbeddedComplexSize(pStubMsg, desc);
1861 m = NdrFreer[*desc & NDR_TABLE_MASK];
1862 if (m) m(pStubMsg, pMemory, desc);
1863 else FIXME("no freer for embedded type %02x\n", *desc);
1864 pMemory += size;
1865 pFormat += 2;
1866 continue;
1867 case RPC_FC_PAD:
1868 break;
1869 default:
1870 FIXME("unhandled format %d\n", *pFormat);
1872 pFormat++;
1875 return pMemory;
1878 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1879 PFORMAT_STRING pFormat)
1881 PFORMAT_STRING desc;
1882 unsigned long size = 0;
1884 while (*pFormat != RPC_FC_END) {
1885 switch (*pFormat) {
1886 case RPC_FC_SHORT:
1887 case RPC_FC_USHORT:
1888 size += 2;
1889 pStubMsg->Buffer += 2;
1890 break;
1891 case RPC_FC_LONG:
1892 case RPC_FC_ULONG:
1893 case RPC_FC_ENUM32:
1894 size += 4;
1895 pStubMsg->Buffer += 4;
1896 break;
1897 case RPC_FC_POINTER:
1898 size += 4;
1899 pStubMsg->Buffer += 4;
1900 break;
1901 case RPC_FC_ALIGNM4:
1902 ALIGN_LENGTH(size, 4);
1903 ALIGN_POINTER(pStubMsg->Buffer, 4);
1904 break;
1905 case RPC_FC_ALIGNM8:
1906 ALIGN_LENGTH(size, 8);
1907 ALIGN_POINTER(pStubMsg->Buffer, 8);
1908 break;
1909 case RPC_FC_STRUCTPAD2:
1910 size += 2;
1911 pStubMsg->Buffer += 2;
1912 break;
1913 case RPC_FC_EMBEDDED_COMPLEX:
1914 size += pFormat[1];
1915 pFormat += 2;
1916 desc = pFormat + *(const SHORT*)pFormat;
1917 size += EmbeddedComplexMemorySize(pStubMsg, desc);
1918 pFormat += 2;
1919 continue;
1920 case RPC_FC_PAD:
1921 break;
1922 default:
1923 FIXME("unhandled format %d\n", *pFormat);
1925 pFormat++;
1928 return size;
1931 /***********************************************************************
1932 * NdrComplexStructMarshall [RPCRT4.@]
1934 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1935 unsigned char *pMemory,
1936 PFORMAT_STRING pFormat)
1938 PFORMAT_STRING conf_array = NULL;
1939 PFORMAT_STRING pointer_desc = NULL;
1940 unsigned char *OldMemory = pStubMsg->Memory;
1942 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1944 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1946 pFormat += 4;
1947 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1948 pFormat += 2;
1949 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1950 pFormat += 2;
1952 pStubMsg->Memory = pMemory;
1954 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
1956 if (conf_array)
1957 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
1959 pStubMsg->Memory = OldMemory;
1961 STD_OVERFLOW_CHECK(pStubMsg);
1963 return NULL;
1966 /***********************************************************************
1967 * NdrComplexStructUnmarshall [RPCRT4.@]
1969 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1970 unsigned char **ppMemory,
1971 PFORMAT_STRING pFormat,
1972 unsigned char fMustAlloc)
1974 unsigned size = *(const WORD*)(pFormat+2);
1975 PFORMAT_STRING conf_array = NULL;
1976 PFORMAT_STRING pointer_desc = NULL;
1977 unsigned char *pMemory;
1979 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1981 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1983 if (fMustAlloc || !*ppMemory)
1985 *ppMemory = NdrAllocate(pStubMsg, size);
1986 memset(*ppMemory, 0, size);
1989 pFormat += 4;
1990 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1991 pFormat += 2;
1992 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1993 pFormat += 2;
1995 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
1997 if (conf_array)
1998 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2000 return NULL;
2003 /***********************************************************************
2004 * NdrComplexStructBufferSize [RPCRT4.@]
2006 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2007 unsigned char *pMemory,
2008 PFORMAT_STRING pFormat)
2010 PFORMAT_STRING conf_array = NULL;
2011 PFORMAT_STRING pointer_desc = NULL;
2012 unsigned char *OldMemory = pStubMsg->Memory;
2014 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2016 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2018 pFormat += 4;
2019 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2020 pFormat += 2;
2021 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2022 pFormat += 2;
2024 pStubMsg->Memory = pMemory;
2026 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2028 if (conf_array)
2029 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2031 pStubMsg->Memory = OldMemory;
2034 /***********************************************************************
2035 * NdrComplexStructMemorySize [RPCRT4.@]
2037 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2038 PFORMAT_STRING pFormat)
2040 unsigned size = *(const WORD*)(pFormat+2);
2041 PFORMAT_STRING conf_array = NULL;
2042 PFORMAT_STRING pointer_desc = NULL;
2044 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2046 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2048 pFormat += 4;
2049 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2050 pFormat += 2;
2051 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2052 pFormat += 2;
2054 ComplexStructMemorySize(pStubMsg, pFormat);
2056 if (conf_array)
2057 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2059 return size;
2062 /***********************************************************************
2063 * NdrComplexStructFree [RPCRT4.@]
2065 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2066 unsigned char *pMemory,
2067 PFORMAT_STRING pFormat)
2069 PFORMAT_STRING conf_array = NULL;
2070 PFORMAT_STRING pointer_desc = NULL;
2071 unsigned char *OldMemory = pStubMsg->Memory;
2073 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2075 pFormat += 4;
2076 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2077 pFormat += 2;
2078 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2079 pFormat += 2;
2081 pStubMsg->Memory = pMemory;
2083 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2085 if (conf_array)
2086 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2088 pStubMsg->Memory = OldMemory;
2091 /***********************************************************************
2092 * NdrConformantArrayMarshall [RPCRT4.@]
2094 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2095 unsigned char *pMemory,
2096 PFORMAT_STRING pFormat)
2098 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2099 unsigned char alignment = pFormat[1] + 1;
2101 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2102 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2104 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2105 size = pStubMsg->MaxCount;
2107 WriteConformance(pStubMsg);
2109 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2111 memcpy(pStubMsg->Buffer, pMemory, size*esize);
2112 pStubMsg->BufferMark = pStubMsg->Buffer;
2113 pStubMsg->Buffer += size*esize;
2115 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2117 STD_OVERFLOW_CHECK(pStubMsg);
2119 return NULL;
2122 /***********************************************************************
2123 * NdrConformantArrayUnmarshall [RPCRT4.@]
2125 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2126 unsigned char **ppMemory,
2127 PFORMAT_STRING pFormat,
2128 unsigned char fMustAlloc)
2130 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2131 unsigned char alignment = pFormat[1] + 1;
2133 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2134 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2136 pFormat = ReadConformance(pStubMsg, pFormat+4);
2137 size = pStubMsg->MaxCount;
2139 if (fMustAlloc || !*ppMemory)
2140 *ppMemory = NdrAllocate(pStubMsg, size*esize);
2142 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2144 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
2146 pStubMsg->BufferMark = pStubMsg->Buffer;
2147 pStubMsg->Buffer += size*esize;
2149 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2151 return NULL;
2154 /***********************************************************************
2155 * NdrConformantArrayBufferSize [RPCRT4.@]
2157 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2158 unsigned char *pMemory,
2159 PFORMAT_STRING pFormat)
2161 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2162 unsigned char alignment = pFormat[1] + 1;
2164 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2165 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2167 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2168 size = pStubMsg->MaxCount;
2170 SizeConformance(pStubMsg);
2172 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2174 /* conformance value plus array */
2175 pStubMsg->BufferLength += size*esize;
2177 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2180 /***********************************************************************
2181 * NdrConformantArrayMemorySize [RPCRT4.@]
2183 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2184 PFORMAT_STRING pFormat)
2186 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2187 unsigned char alignment = pFormat[1] + 1;
2189 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2190 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2192 pFormat = ReadConformance(pStubMsg, pFormat+4);
2193 size = pStubMsg->MaxCount;
2194 pStubMsg->MemorySize += size*esize;
2196 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2197 pStubMsg->BufferMark = pStubMsg->Buffer;
2198 pStubMsg->Buffer += size*esize;
2200 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2202 return pStubMsg->MemorySize;
2205 /***********************************************************************
2206 * NdrConformantArrayFree [RPCRT4.@]
2208 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2209 unsigned char *pMemory,
2210 PFORMAT_STRING pFormat)
2212 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2213 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2215 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2219 /***********************************************************************
2220 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2222 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2223 unsigned char* pMemory,
2224 PFORMAT_STRING pFormat )
2226 unsigned char alignment = pFormat[1] + 1;
2227 DWORD esize = *(const WORD*)(pFormat+2);
2229 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2231 if (pFormat[0] != RPC_FC_CVARRAY)
2233 ERR("invalid format type %x\n", pFormat[0]);
2234 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2235 return NULL;
2238 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2239 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2241 WriteConformance(pStubMsg);
2242 WriteVariance(pStubMsg);
2244 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2246 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, pStubMsg->ActualCount*esize);
2247 pStubMsg->BufferMark = pStubMsg->Buffer;
2248 pStubMsg->Buffer += pStubMsg->ActualCount*esize;
2250 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2252 STD_OVERFLOW_CHECK(pStubMsg);
2254 return NULL;
2258 /***********************************************************************
2259 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2261 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2262 unsigned char** ppMemory,
2263 PFORMAT_STRING pFormat,
2264 unsigned char fMustAlloc )
2266 unsigned char alignment = pFormat[1] + 1;
2267 DWORD esize = *(const WORD*)(pFormat+2);
2269 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2271 if (pFormat[0] != RPC_FC_CVARRAY)
2273 ERR("invalid format type %x\n", pFormat[0]);
2274 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2275 return NULL;
2278 pFormat = ReadConformance(pStubMsg, pFormat+4);
2279 pFormat = ReadVariance(pStubMsg, pFormat);
2281 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2283 if (!*ppMemory || fMustAlloc)
2284 *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize);
2285 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, pStubMsg->ActualCount * esize);
2286 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
2288 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2290 return NULL;
2294 /***********************************************************************
2295 * NdrConformantVaryingArrayFree [RPCRT4.@]
2297 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2298 unsigned char* pMemory,
2299 PFORMAT_STRING pFormat )
2301 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2303 if (pFormat[0] != RPC_FC_CVARRAY)
2305 ERR("invalid format type %x\n", pFormat[0]);
2306 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2307 return;
2310 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2311 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2313 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2317 /***********************************************************************
2318 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2320 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2321 unsigned char* pMemory, PFORMAT_STRING pFormat )
2323 unsigned char alignment = pFormat[1] + 1;
2324 DWORD esize = *(const WORD*)(pFormat+2);
2326 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2328 if (pFormat[0] != RPC_FC_CVARRAY)
2330 ERR("invalid format type %x\n", pFormat[0]);
2331 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2332 return;
2335 /* compute size */
2336 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2337 /* compute length */
2338 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2340 SizeConformance(pStubMsg);
2341 SizeVariance(pStubMsg);
2343 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2345 pStubMsg->BufferLength += pStubMsg->ActualCount*esize;
2347 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2351 /***********************************************************************
2352 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2354 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2355 PFORMAT_STRING pFormat )
2357 FIXME( "stub\n" );
2358 return 0;
2362 /***********************************************************************
2363 * NdrComplexArrayMarshall [RPCRT4.@]
2365 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2366 unsigned char *pMemory,
2367 PFORMAT_STRING pFormat)
2369 ULONG i, count, def;
2370 BOOL variance_present;
2371 unsigned char alignment;
2373 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2375 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2377 ERR("invalid format type %x\n", pFormat[0]);
2378 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2379 return NULL;
2382 alignment = pFormat[1] + 1;
2384 def = *(const WORD*)&pFormat[2];
2385 pFormat += 4;
2387 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2388 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2390 variance_present = IsConformanceOrVariancePresent(pFormat);
2391 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2392 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2394 WriteConformance(pStubMsg);
2395 if (variance_present)
2396 WriteVariance(pStubMsg);
2398 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2400 count = pStubMsg->ActualCount;
2401 for (i = 0; i < count; i++)
2402 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2404 STD_OVERFLOW_CHECK(pStubMsg);
2406 return NULL;
2409 /***********************************************************************
2410 * NdrComplexArrayUnmarshall [RPCRT4.@]
2412 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2413 unsigned char **ppMemory,
2414 PFORMAT_STRING pFormat,
2415 unsigned char fMustAlloc)
2417 ULONG i, count, esize;
2418 unsigned char alignment;
2419 unsigned char *pMemory;
2420 unsigned char *Buffer;
2422 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2424 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2426 ERR("invalid format type %x\n", pFormat[0]);
2427 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2428 return NULL;
2431 alignment = pFormat[1] + 1;
2433 pFormat += 4;
2435 pFormat = ReadConformance(pStubMsg, pFormat);
2436 pFormat = ReadVariance(pStubMsg, pFormat);
2438 Buffer = pStubMsg->Buffer;
2439 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2440 pStubMsg->Buffer = Buffer;
2442 if (fMustAlloc || !*ppMemory)
2444 *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize);
2445 memset(*ppMemory, 0, pStubMsg->MaxCount * esize);
2448 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2450 pMemory = *ppMemory;
2451 count = pStubMsg->ActualCount;
2452 for (i = 0; i < count; i++)
2453 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
2455 return NULL;
2458 /***********************************************************************
2459 * NdrComplexArrayBufferSize [RPCRT4.@]
2461 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2462 unsigned char *pMemory,
2463 PFORMAT_STRING pFormat)
2465 ULONG i, count, def;
2466 unsigned char alignment;
2467 BOOL variance_present;
2469 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2471 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2473 ERR("invalid format type %x\n", pFormat[0]);
2474 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2475 return;
2478 alignment = pFormat[1] + 1;
2480 def = *(const WORD*)&pFormat[2];
2481 pFormat += 4;
2483 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2484 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2485 SizeConformance(pStubMsg);
2487 variance_present = IsConformanceOrVariancePresent(pFormat);
2488 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2489 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2491 if (variance_present)
2492 SizeVariance(pStubMsg);
2494 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2496 count = pStubMsg->ActualCount;
2497 for (i = 0; i < count; i++)
2498 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2501 /***********************************************************************
2502 * NdrComplexArrayMemorySize [RPCRT4.@]
2504 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2505 PFORMAT_STRING pFormat)
2507 ULONG i, count, esize;
2508 unsigned char alignment;
2509 unsigned char *Buffer;
2510 unsigned long SavedMemorySize;
2511 unsigned long MemorySize;
2513 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2515 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2517 ERR("invalid format type %x\n", pFormat[0]);
2518 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2519 return 0;
2522 alignment = pFormat[1] + 1;
2524 pFormat += 4;
2526 pFormat = ReadConformance(pStubMsg, pFormat);
2527 pFormat = ReadVariance(pStubMsg, pFormat);
2529 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2531 SavedMemorySize = pStubMsg->MemorySize;
2533 Buffer = pStubMsg->Buffer;
2534 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2535 pStubMsg->Buffer = Buffer;
2537 MemorySize = esize * pStubMsg->MaxCount;
2539 count = pStubMsg->ActualCount;
2540 for (i = 0; i < count; i++)
2541 ComplexStructMemorySize(pStubMsg, pFormat);
2543 pStubMsg->MemorySize = SavedMemorySize;
2545 pStubMsg->MemorySize += MemorySize;
2546 return MemorySize;
2549 /***********************************************************************
2550 * NdrComplexArrayFree [RPCRT4.@]
2552 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2553 unsigned char *pMemory,
2554 PFORMAT_STRING pFormat)
2556 ULONG i, count, def;
2558 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2560 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2562 ERR("invalid format type %x\n", pFormat[0]);
2563 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2564 return;
2567 def = *(const WORD*)&pFormat[2];
2568 pFormat += 4;
2570 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2571 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2573 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2574 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2576 count = pStubMsg->ActualCount;
2577 for (i = 0; i < count; i++)
2578 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2581 static unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2583 return MAKELONG(pStubMsg->dwDestContext,
2584 pStubMsg->RpcMsg->DataRepresentation);
2587 #define USER_MARSHAL_PTR_PREFIX \
2588 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2589 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2591 /***********************************************************************
2592 * NdrUserMarshalMarshall [RPCRT4.@]
2594 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2595 unsigned char *pMemory,
2596 PFORMAT_STRING pFormat)
2598 unsigned flags = pFormat[1];
2599 unsigned index = *(const WORD*)&pFormat[2];
2600 unsigned long uflag = UserMarshalFlags(pStubMsg);
2601 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2602 TRACE("index=%d\n", index);
2604 if (flags & USER_MARSHAL_POINTER)
2606 ALIGN_POINTER(pStubMsg->Buffer, 4);
2607 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2608 pStubMsg->Buffer += 4;
2609 ALIGN_POINTER(pStubMsg->Buffer, 8);
2611 else
2612 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2614 pStubMsg->Buffer =
2615 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2616 &uflag, pStubMsg->Buffer, pMemory);
2618 STD_OVERFLOW_CHECK(pStubMsg);
2620 return NULL;
2623 /***********************************************************************
2624 * NdrUserMarshalUnmarshall [RPCRT4.@]
2626 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2627 unsigned char **ppMemory,
2628 PFORMAT_STRING pFormat,
2629 unsigned char fMustAlloc)
2631 unsigned flags = pFormat[1];
2632 unsigned index = *(const WORD*)&pFormat[2];
2633 DWORD memsize = *(const WORD*)&pFormat[4];
2634 unsigned long uflag = UserMarshalFlags(pStubMsg);
2635 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2636 TRACE("index=%d\n", index);
2638 if (flags & USER_MARSHAL_POINTER)
2640 ALIGN_POINTER(pStubMsg->Buffer, 4);
2641 /* skip pointer prefix */
2642 pStubMsg->Buffer += 4;
2643 ALIGN_POINTER(pStubMsg->Buffer, 8);
2645 else
2646 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2648 if (fMustAlloc || !*ppMemory)
2649 *ppMemory = NdrAllocate(pStubMsg, memsize);
2651 pStubMsg->Buffer =
2652 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2653 &uflag, pStubMsg->Buffer, *ppMemory);
2655 return NULL;
2658 /***********************************************************************
2659 * NdrUserMarshalBufferSize [RPCRT4.@]
2661 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2662 unsigned char *pMemory,
2663 PFORMAT_STRING pFormat)
2665 unsigned flags = pFormat[1];
2666 unsigned index = *(const WORD*)&pFormat[2];
2667 DWORD bufsize = *(const WORD*)&pFormat[6];
2668 unsigned long uflag = UserMarshalFlags(pStubMsg);
2669 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2670 TRACE("index=%d\n", index);
2672 if (flags & USER_MARSHAL_POINTER)
2674 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2675 /* skip pointer prefix */
2676 pStubMsg->BufferLength += 4;
2677 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2679 else
2680 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2682 if (bufsize) {
2683 TRACE("size=%ld\n", bufsize);
2684 pStubMsg->BufferLength += bufsize;
2685 return;
2688 pStubMsg->BufferLength =
2689 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2690 &uflag, pStubMsg->BufferLength, pMemory);
2693 /***********************************************************************
2694 * NdrUserMarshalMemorySize [RPCRT4.@]
2696 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2697 PFORMAT_STRING pFormat)
2699 unsigned flags = pFormat[1];
2700 unsigned index = *(const WORD*)&pFormat[2];
2701 DWORD memsize = *(const WORD*)&pFormat[4];
2702 DWORD bufsize = *(const WORD*)&pFormat[6];
2704 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2705 TRACE("index=%d\n", index);
2707 pStubMsg->MemorySize += memsize;
2709 if (flags & USER_MARSHAL_POINTER)
2711 ALIGN_POINTER(pStubMsg->Buffer, 4);
2712 /* skip pointer prefix */
2713 pStubMsg->Buffer += 4;
2714 ALIGN_POINTER(pStubMsg->Buffer, 8);
2716 else
2717 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2719 pStubMsg->Buffer += bufsize;
2721 return pStubMsg->MemorySize;
2724 /***********************************************************************
2725 * NdrUserMarshalFree [RPCRT4.@]
2727 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2728 unsigned char *pMemory,
2729 PFORMAT_STRING pFormat)
2731 /* unsigned flags = pFormat[1]; */
2732 unsigned index = *(const WORD*)&pFormat[2];
2733 unsigned long uflag = UserMarshalFlags(pStubMsg);
2734 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2735 TRACE("index=%d\n", index);
2737 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2738 &uflag, pMemory);
2741 /***********************************************************************
2742 * NdrClearOutParameters [RPCRT4.@]
2744 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2745 PFORMAT_STRING pFormat,
2746 void *ArgAddr)
2748 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2751 /***********************************************************************
2752 * NdrConvert [RPCRT4.@]
2754 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2756 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2757 /* FIXME: since this stub doesn't do any converting, the proper behavior
2758 is to raise an exception */
2761 /***********************************************************************
2762 * NdrConvert2 [RPCRT4.@]
2764 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2766 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2767 pStubMsg, pFormat, NumberParams);
2768 /* FIXME: since this stub doesn't do any converting, the proper behavior
2769 is to raise an exception */
2772 typedef struct _NDR_CSTRUCT_FORMAT
2774 unsigned char type;
2775 unsigned char alignment;
2776 unsigned short memory_size;
2777 short offset_to_array_description;
2778 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2780 /***********************************************************************
2781 * NdrConformantStructMarshall [RPCRT4.@]
2783 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2784 unsigned char *pMemory,
2785 PFORMAT_STRING pFormat)
2787 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2788 PFORMAT_STRING pCArrayFormat;
2789 ULONG esize;
2791 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2793 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2794 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2796 ERR("invalid format type %x\n", pCStructFormat->type);
2797 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2798 return NULL;
2801 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2802 pCStructFormat->offset_to_array_description;
2803 if (*pCArrayFormat != RPC_FC_CARRAY)
2805 ERR("invalid array format type %x\n", pCStructFormat->type);
2806 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2807 return NULL;
2809 esize = *(const WORD*)(pCArrayFormat+2);
2811 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2812 pCArrayFormat + 4, 0);
2814 WriteConformance(pStubMsg);
2816 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2818 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2820 /* copy constant sized part of struct */
2821 pStubMsg->BufferMark = pStubMsg->Buffer;
2822 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + pStubMsg->MaxCount * esize);
2823 pStubMsg->Buffer += pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2825 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2826 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2828 STD_OVERFLOW_CHECK(pStubMsg);
2830 return NULL;
2833 /***********************************************************************
2834 * NdrConformantStructUnmarshall [RPCRT4.@]
2836 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2837 unsigned char **ppMemory,
2838 PFORMAT_STRING pFormat,
2839 unsigned char fMustAlloc)
2841 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2842 PFORMAT_STRING pCArrayFormat;
2843 ULONG esize;
2845 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2847 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2848 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2850 ERR("invalid format type %x\n", pCStructFormat->type);
2851 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2852 return NULL;
2854 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2855 pCStructFormat->offset_to_array_description;
2856 if (*pCArrayFormat != RPC_FC_CARRAY)
2858 ERR("invalid array format type %x\n", pCStructFormat->type);
2859 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2860 return NULL;
2862 esize = *(const WORD*)(pCArrayFormat+2);
2864 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
2866 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2868 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2870 /* work out how much memory to allocate if we need to do so */
2871 if (!*ppMemory || fMustAlloc)
2873 SIZE_T size = pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2874 *ppMemory = NdrAllocate(pStubMsg, size);
2877 /* now copy the data */
2878 pStubMsg->BufferMark = pStubMsg->Buffer;
2879 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + pStubMsg->MaxCount * esize);
2880 pStubMsg->Buffer += pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2882 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2883 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2885 return NULL;
2888 /***********************************************************************
2889 * NdrConformantStructBufferSize [RPCRT4.@]
2891 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2892 unsigned char *pMemory,
2893 PFORMAT_STRING pFormat)
2895 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2896 PFORMAT_STRING pCArrayFormat;
2897 ULONG esize;
2899 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2901 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2902 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2904 ERR("invalid format type %x\n", pCStructFormat->type);
2905 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2906 return;
2908 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2909 pCStructFormat->offset_to_array_description;
2910 if (*pCArrayFormat != RPC_FC_CARRAY)
2912 ERR("invalid array format type %x\n", pCStructFormat->type);
2913 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2914 return;
2916 esize = *(const WORD*)(pCArrayFormat+2);
2918 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
2919 SizeConformance(pStubMsg);
2921 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
2923 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2925 pStubMsg->BufferLength += pCStructFormat->memory_size + esize * pStubMsg->MaxCount;
2927 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2928 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2931 /***********************************************************************
2932 * NdrConformantStructMemorySize [RPCRT4.@]
2934 unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2935 PFORMAT_STRING pFormat)
2937 FIXME("stub\n");
2938 return 0;
2941 /***********************************************************************
2942 * NdrConformantStructFree [RPCRT4.@]
2944 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2945 unsigned char *pMemory,
2946 PFORMAT_STRING pFormat)
2948 FIXME("stub\n");
2951 /***********************************************************************
2952 * NdrConformantVaryingStructMarshall [RPCRT4.@]
2954 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2955 unsigned char *pMemory,
2956 PFORMAT_STRING pFormat)
2958 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
2959 PFORMAT_STRING pCVArrayFormat;
2960 ULONG esize;
2962 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2964 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
2965 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
2967 ERR("invalid format type %x\n", pCVStructFormat->type);
2968 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2969 return NULL;
2972 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
2973 pCVStructFormat->offset_to_array_description;
2974 switch (*pCVArrayFormat)
2976 case RPC_FC_CVARRAY:
2977 esize = *(const WORD*)(pCVArrayFormat+2);
2979 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2980 pCVArrayFormat + 4, 0);
2981 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2982 pCVArrayFormat, 0);
2983 break;
2984 case RPC_FC_C_CSTRING:
2985 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
2986 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
2987 esize = sizeof(char);
2988 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
2989 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2990 pCVArrayFormat + 2, 0);
2991 else
2992 pStubMsg->MaxCount = pStubMsg->ActualCount;
2993 break;
2994 case RPC_FC_C_WSTRING:
2995 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
2996 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
2997 esize = sizeof(WCHAR);
2998 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
2999 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3000 pCVArrayFormat + 2, 0);
3001 else
3002 pStubMsg->MaxCount = pStubMsg->ActualCount;
3003 break;
3004 default:
3005 ERR("invalid array format type %x\n", *pCVArrayFormat);
3006 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3007 return NULL;
3010 WriteConformance(pStubMsg);
3012 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3014 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3016 /* write constant sized part */
3017 pStubMsg->BufferMark = pStubMsg->Buffer;
3018 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
3019 pStubMsg->Buffer += pCVStructFormat->memory_size;
3021 WriteVariance(pStubMsg);
3023 /* write array part */
3024 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, pStubMsg->ActualCount * esize);
3025 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
3027 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3029 STD_OVERFLOW_CHECK(pStubMsg);
3031 return NULL;
3034 /***********************************************************************
3035 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3037 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3038 unsigned char **ppMemory,
3039 PFORMAT_STRING pFormat,
3040 unsigned char fMustAlloc)
3042 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3043 PFORMAT_STRING pCVArrayFormat;
3044 ULONG esize;
3045 unsigned char cvarray_type;
3047 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3049 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3050 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3052 ERR("invalid format type %x\n", pCVStructFormat->type);
3053 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3054 return NULL;
3057 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3058 pCVStructFormat->offset_to_array_description;
3059 cvarray_type = *pCVArrayFormat;
3060 switch (cvarray_type)
3062 case RPC_FC_CVARRAY:
3063 esize = *(const WORD*)(pCVArrayFormat+2);
3064 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3065 break;
3066 case RPC_FC_C_CSTRING:
3067 esize = sizeof(char);
3068 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3069 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3070 else
3071 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3072 break;
3073 case RPC_FC_C_WSTRING:
3074 esize = sizeof(WCHAR);
3075 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3076 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3077 else
3078 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3079 break;
3080 default:
3081 ERR("invalid array format type %x\n", *pCVArrayFormat);
3082 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3083 return NULL;
3086 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3088 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3090 /* work out how much memory to allocate if we need to do so */
3091 if (!*ppMemory || fMustAlloc)
3093 SIZE_T size = pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3094 *ppMemory = NdrAllocate(pStubMsg, size);
3097 /* copy the constant data */
3098 pStubMsg->BufferMark = pStubMsg->Buffer;
3099 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3100 pStubMsg->Buffer += pCVStructFormat->memory_size;
3102 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat);
3104 /* copy the array data */
3105 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3106 pStubMsg->ActualCount * esize);
3107 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
3109 if (cvarray_type == RPC_FC_C_CSTRING)
3110 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3111 else if (cvarray_type == RPC_FC_C_WSTRING)
3112 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3114 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3116 return NULL;
3119 /***********************************************************************
3120 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3122 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3123 unsigned char *pMemory,
3124 PFORMAT_STRING pFormat)
3126 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3127 PFORMAT_STRING pCVArrayFormat;
3128 ULONG esize;
3130 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3132 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3133 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3135 ERR("invalid format type %x\n", pCVStructFormat->type);
3136 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3137 return;
3140 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3141 pCVStructFormat->offset_to_array_description;
3142 switch (*pCVArrayFormat)
3144 case RPC_FC_CVARRAY:
3145 esize = *(const WORD*)(pCVArrayFormat+2);
3147 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3148 pCVArrayFormat + 4, 0);
3149 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3150 pCVArrayFormat + 4, 0);
3151 break;
3152 case RPC_FC_C_CSTRING:
3153 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3154 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3155 esize = sizeof(char);
3156 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3157 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3158 pCVArrayFormat + 2, 0);
3159 else
3160 pStubMsg->MaxCount = pStubMsg->ActualCount;
3161 break;
3162 case RPC_FC_C_WSTRING:
3163 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3164 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3165 esize = sizeof(WCHAR);
3166 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3167 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3168 pCVArrayFormat + 2, 0);
3169 else
3170 pStubMsg->MaxCount = pStubMsg->ActualCount;
3171 break;
3172 default:
3173 ERR("invalid array format type %x\n", *pCVArrayFormat);
3174 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3175 return;
3178 SizeConformance(pStubMsg);
3180 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3182 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3184 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3185 SizeVariance(pStubMsg);
3186 pStubMsg->BufferLength += esize * pStubMsg->MaxCount;
3188 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3191 /***********************************************************************
3192 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3194 unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3195 PFORMAT_STRING pFormat)
3197 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3198 PFORMAT_STRING pCVArrayFormat;
3199 ULONG esize;
3200 unsigned char cvarray_type;
3202 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3204 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3205 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3207 ERR("invalid format type %x\n", pCVStructFormat->type);
3208 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3209 return 0;
3212 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3213 pCVStructFormat->offset_to_array_description;
3214 cvarray_type = *pCVArrayFormat;
3215 switch (cvarray_type)
3217 case RPC_FC_CVARRAY:
3218 esize = *(const WORD*)(pCVArrayFormat+2);
3219 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3220 break;
3221 case RPC_FC_C_CSTRING:
3222 esize = sizeof(char);
3223 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3224 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3225 else
3226 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3227 break;
3228 case RPC_FC_C_WSTRING:
3229 esize = sizeof(WCHAR);
3230 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3231 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3232 else
3233 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3234 break;
3235 default:
3236 ERR("invalid array format type %x\n", *pCVArrayFormat);
3237 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3238 return 0;
3241 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3243 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3245 pStubMsg->Buffer += pCVStructFormat->memory_size;
3246 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat);
3247 pStubMsg->Buffer += pCVStructFormat->memory_size + pStubMsg->ActualCount * esize;
3249 pStubMsg->MemorySize += pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3251 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3253 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3256 /***********************************************************************
3257 * NdrConformantVaryingStructFree [RPCRT4.@]
3259 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3260 unsigned char *pMemory,
3261 PFORMAT_STRING pFormat)
3263 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3264 PFORMAT_STRING pCVArrayFormat;
3265 ULONG esize;
3267 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3269 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3270 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3272 ERR("invalid format type %x\n", pCVStructFormat->type);
3273 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3274 return;
3277 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3278 pCVStructFormat->offset_to_array_description;
3279 switch (*pCVArrayFormat)
3281 case RPC_FC_CVARRAY:
3282 esize = *(const WORD*)(pCVArrayFormat+2);
3284 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3285 pCVArrayFormat + 4, 0);
3286 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3287 pCVArrayFormat, 0);
3288 break;
3289 case RPC_FC_C_CSTRING:
3290 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3291 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3292 esize = sizeof(char);
3293 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3294 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3295 pCVArrayFormat + 2, 0);
3296 else
3297 pStubMsg->MaxCount = pStubMsg->ActualCount;
3298 break;
3299 case RPC_FC_C_WSTRING:
3300 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3301 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3302 esize = sizeof(WCHAR);
3303 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3304 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3305 pCVArrayFormat + 2, 0);
3306 else
3307 pStubMsg->MaxCount = pStubMsg->ActualCount;
3308 break;
3309 default:
3310 ERR("invalid array format type %x\n", *pCVArrayFormat);
3311 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3312 return;
3315 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3317 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3320 typedef struct
3322 unsigned char type;
3323 unsigned char alignment;
3324 unsigned short total_size;
3325 } NDR_SMFARRAY_FORMAT;
3327 typedef struct
3329 unsigned char type;
3330 unsigned char alignment;
3331 unsigned long total_size;
3332 } NDR_LGFARRAY_FORMAT;
3334 /***********************************************************************
3335 * NdrFixedArrayMarshall [RPCRT4.@]
3337 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3338 unsigned char *pMemory,
3339 PFORMAT_STRING pFormat)
3341 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3342 unsigned long total_size;
3344 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3346 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3347 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3349 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3350 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3351 return NULL;
3354 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3356 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3358 total_size = pSmFArrayFormat->total_size;
3359 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3361 else
3363 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3364 total_size = pLgFArrayFormat->total_size;
3365 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3367 memcpy(pStubMsg->Buffer, pMemory, total_size);
3368 pStubMsg->Buffer += total_size;
3370 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3372 return NULL;
3375 /***********************************************************************
3376 * NdrFixedArrayUnmarshall [RPCRT4.@]
3378 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3379 unsigned char **ppMemory,
3380 PFORMAT_STRING pFormat,
3381 unsigned char fMustAlloc)
3383 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3384 unsigned long total_size;
3386 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3388 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3389 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3391 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3392 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3393 return NULL;
3396 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3398 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3400 total_size = pSmFArrayFormat->total_size;
3401 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3403 else
3405 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3406 total_size = pLgFArrayFormat->total_size;
3407 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3410 if (fMustAlloc || !*ppMemory)
3411 *ppMemory = NdrAllocate(pStubMsg, total_size);
3412 memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3413 pStubMsg->Buffer += total_size;
3415 pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3417 return NULL;
3420 /***********************************************************************
3421 * NdrFixedArrayBufferSize [RPCRT4.@]
3423 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3424 unsigned char *pMemory,
3425 PFORMAT_STRING pFormat)
3427 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3428 unsigned long total_size;
3430 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3432 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3433 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3435 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3436 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3437 return;
3440 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3442 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3444 total_size = pSmFArrayFormat->total_size;
3445 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3447 else
3449 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3450 total_size = pLgFArrayFormat->total_size;
3451 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3453 pStubMsg->BufferLength += total_size;
3455 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3458 /***********************************************************************
3459 * NdrFixedArrayMemorySize [RPCRT4.@]
3461 unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3462 PFORMAT_STRING pFormat)
3464 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3465 unsigned long total_size;
3467 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3469 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3470 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3472 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3473 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3474 return 0;
3477 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3479 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3481 total_size = pSmFArrayFormat->total_size;
3482 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3484 else
3486 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3487 total_size = pLgFArrayFormat->total_size;
3488 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3490 pStubMsg->Buffer += total_size;
3491 pStubMsg->MemorySize += total_size;
3493 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3495 return total_size;
3498 /***********************************************************************
3499 * NdrFixedArrayFree [RPCRT4.@]
3501 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3502 unsigned char *pMemory,
3503 PFORMAT_STRING pFormat)
3505 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3507 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3509 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3510 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3512 ERR("invalid format type %x\n", pSmFArrayFormat->type);
3513 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3514 return;
3517 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3518 pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3519 else
3521 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3522 pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3525 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3528 /***********************************************************************
3529 * NdrVaryingArrayMarshall [RPCRT4.@]
3531 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3532 unsigned char *pMemory,
3533 PFORMAT_STRING pFormat)
3535 FIXME("stub\n");
3536 return NULL;
3539 /***********************************************************************
3540 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3542 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3543 unsigned char **ppMemory,
3544 PFORMAT_STRING pFormat,
3545 unsigned char fMustAlloc)
3547 FIXME("stub\n");
3548 return NULL;
3551 /***********************************************************************
3552 * NdrVaryingArrayBufferSize [RPCRT4.@]
3554 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3555 unsigned char *pMemory,
3556 PFORMAT_STRING pFormat)
3558 FIXME("stub\n");
3561 /***********************************************************************
3562 * NdrVaryingArrayMemorySize [RPCRT4.@]
3564 unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3565 PFORMAT_STRING pFormat)
3567 FIXME("stub\n");
3568 return 0;
3571 /***********************************************************************
3572 * NdrVaryingArrayFree [RPCRT4.@]
3574 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3575 unsigned char *pMemory,
3576 PFORMAT_STRING pFormat)
3578 FIXME("stub\n");
3581 /***********************************************************************
3582 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
3584 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3585 unsigned char *pMemory,
3586 PFORMAT_STRING pFormat)
3588 FIXME("stub\n");
3589 return NULL;
3592 /***********************************************************************
3593 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
3595 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3596 unsigned char **ppMemory,
3597 PFORMAT_STRING pFormat,
3598 unsigned char fMustAlloc)
3600 FIXME("stub\n");
3601 return NULL;
3604 /***********************************************************************
3605 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
3607 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3608 unsigned char *pMemory,
3609 PFORMAT_STRING pFormat)
3611 FIXME("stub\n");
3614 /***********************************************************************
3615 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
3617 unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3618 PFORMAT_STRING pFormat)
3620 FIXME("stub\n");
3621 return 0;
3624 /***********************************************************************
3625 * NdrEncapsulatedUnionFree [RPCRT4.@]
3627 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
3628 unsigned char *pMemory,
3629 PFORMAT_STRING pFormat)
3631 FIXME("stub\n");
3634 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
3635 unsigned long discriminant,
3636 PFORMAT_STRING pFormat)
3638 unsigned short num_arms, arm, type;
3640 num_arms = *(const SHORT*)pFormat & 0x0fff;
3641 pFormat += 2;
3642 for(arm = 0; arm < num_arms; arm++)
3644 if(discriminant == *(const ULONG*)pFormat)
3646 pFormat += 4;
3647 break;
3649 pFormat += 6;
3652 type = *(const unsigned short*)pFormat;
3653 TRACE("type %04x\n", type);
3654 if(arm == num_arms) /* default arm extras */
3656 if(type == 0xffff)
3658 ERR("no arm for 0x%lx and no default case\n", discriminant);
3659 RpcRaiseException(RPC_S_INVALID_TAG);
3660 return NULL;
3662 if(type == 0)
3664 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
3665 return NULL;
3668 return pFormat;
3671 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
3672 ULONG value,
3673 PFORMAT_STRING pFormat)
3675 pFormat += *(const SHORT*)pFormat;
3676 pFormat += 2;
3678 return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
3681 /***********************************************************************
3682 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
3684 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3685 unsigned char *pMemory,
3686 PFORMAT_STRING pFormat)
3688 unsigned short type;
3689 unsigned char switch_type;
3691 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3692 pFormat++;
3694 switch_type = *pFormat;
3695 pFormat++;
3697 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
3698 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
3699 /* Marshall discriminant */
3700 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
3702 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
3703 if(!pFormat)
3704 return NULL;
3706 type = *(const unsigned short*)pFormat;
3707 if((type & 0xff00) == 0x8000)
3709 unsigned char basetype = LOBYTE(type);
3710 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
3712 else
3714 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3715 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
3716 if (m)
3718 unsigned char *saved_buffer = NULL;
3719 switch(*desc)
3721 case RPC_FC_RP:
3722 case RPC_FC_UP:
3723 case RPC_FC_OP:
3724 case RPC_FC_FP:
3725 saved_buffer = pStubMsg->Buffer;
3726 pStubMsg->Buffer += 4; /* for pointer ID */
3727 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
3728 break;
3729 default:
3730 m(pStubMsg, pMemory, desc);
3733 else FIXME("no marshaller for embedded type %02x\n", *desc);
3735 return NULL;
3738 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
3739 PFORMAT_STRING *ppFormat)
3741 long discriminant = 0;
3743 switch(**ppFormat)
3745 case RPC_FC_BYTE:
3746 case RPC_FC_CHAR:
3747 case RPC_FC_SMALL:
3748 case RPC_FC_USMALL:
3749 discriminant = *(UCHAR *)pStubMsg->Buffer;
3750 pStubMsg->Buffer += sizeof(UCHAR);
3751 break;
3752 case RPC_FC_WCHAR:
3753 case RPC_FC_SHORT:
3754 case RPC_FC_USHORT:
3755 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
3756 discriminant = *(USHORT *)pStubMsg->Buffer;
3757 pStubMsg->Buffer += sizeof(USHORT);
3758 break;
3759 case RPC_FC_LONG:
3760 case RPC_FC_ULONG:
3761 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
3762 discriminant = *(ULONG *)pStubMsg->Buffer;
3763 pStubMsg->Buffer += sizeof(ULONG);
3764 break;
3765 default:
3766 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
3768 (*ppFormat)++;
3770 if (pStubMsg->fHasNewCorrDesc)
3771 *ppFormat += 6;
3772 else
3773 *ppFormat += 4;
3774 return discriminant;
3777 /**********************************************************************
3778 * NdrNonEncapsulatedUnionUnmarshall[RPCRT4.@]
3780 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3781 unsigned char **ppMemory,
3782 PFORMAT_STRING pFormat,
3783 unsigned char fMustAlloc)
3785 long discriminant;
3786 unsigned short type, size;
3788 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3789 pFormat++;
3791 /* Unmarshall discriminant */
3792 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
3793 TRACE("unmarshalled discriminant %lx\n", discriminant);
3795 pFormat += *(const SHORT*)pFormat;
3797 size = *(const unsigned short*)pFormat;
3798 pFormat += 2;
3800 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
3801 if(!pFormat)
3802 return NULL;
3804 if(!*ppMemory || fMustAlloc)
3805 *ppMemory = NdrAllocate(pStubMsg, size);
3807 type = *(const unsigned short*)pFormat;
3808 if((type & 0xff00) == 0x8000)
3810 unsigned char basetype = LOBYTE(type);
3811 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
3813 else
3815 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3816 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3817 if (m)
3819 unsigned char *saved_buffer = NULL;
3820 switch(*desc)
3822 case RPC_FC_RP:
3823 case RPC_FC_UP:
3824 case RPC_FC_OP:
3825 case RPC_FC_FP:
3826 ALIGN_POINTER(pStubMsg->Buffer, 4);
3827 saved_buffer = pStubMsg->Buffer;
3828 pStubMsg->Buffer += 4; /* for pointer ID */
3829 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
3830 break;
3831 default:
3832 m(pStubMsg, ppMemory, desc, fMustAlloc);
3835 else FIXME("no marshaller for embedded type %02x\n", *desc);
3837 return NULL;
3840 /***********************************************************************
3841 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
3843 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3844 unsigned char *pMemory,
3845 PFORMAT_STRING pFormat)
3847 unsigned short type;
3848 unsigned char switch_type;
3850 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3851 pFormat++;
3853 switch_type = *pFormat;
3854 pFormat++;
3856 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
3857 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
3858 /* Add discriminant size */
3859 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
3861 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
3862 if(!pFormat)
3863 return;
3865 type = *(const unsigned short*)pFormat;
3866 if((type & 0xff00) == 0x8000)
3868 unsigned char basetype = LOBYTE(type);
3869 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
3871 else
3873 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3874 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3875 if (m)
3877 switch(*desc)
3879 case RPC_FC_RP:
3880 case RPC_FC_UP:
3881 case RPC_FC_OP:
3882 case RPC_FC_FP:
3883 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3884 pStubMsg->BufferLength += 4; /* for pointer ID */
3885 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
3886 break;
3887 default:
3888 m(pStubMsg, pMemory, desc);
3891 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3893 return;
3896 /***********************************************************************
3897 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
3899 unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3900 PFORMAT_STRING pFormat)
3902 unsigned long discriminant;
3903 unsigned short type, size;
3905 pFormat++;
3906 /* Unmarshall discriminant */
3907 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
3908 TRACE("unmarshalled discriminant 0x%lx\n", discriminant);
3910 pFormat += *(const SHORT*)pFormat;
3912 size = *(const unsigned short*)pFormat;
3913 pFormat += 2;
3915 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
3916 if(!pFormat)
3917 return 0;
3919 pStubMsg->Memory += size;
3921 type = *(const unsigned short*)pFormat;
3922 if((type & 0xff00) == 0x8000)
3924 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
3926 else
3928 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3929 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
3930 unsigned char *saved_buffer;
3931 if (m)
3933 switch(*desc)
3935 case RPC_FC_RP:
3936 case RPC_FC_UP:
3937 case RPC_FC_OP:
3938 case RPC_FC_FP:
3939 ALIGN_POINTER(pStubMsg->Buffer, 4);
3940 saved_buffer = pStubMsg->Buffer;
3941 pStubMsg->Buffer += 4;
3942 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
3943 pStubMsg->MemorySize += 4;
3944 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
3945 break;
3946 default:
3947 return m(pStubMsg, desc);
3950 else FIXME("no marshaller for embedded type %02x\n", *desc);
3953 TRACE("size %d\n", size);
3954 return size;
3957 /***********************************************************************
3958 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
3960 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
3961 unsigned char *pMemory,
3962 PFORMAT_STRING pFormat)
3964 FIXME("stub\n");
3967 /***********************************************************************
3968 * NdrByteCountPointerMarshall [RPCRT4.@]
3970 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3971 unsigned char *pMemory,
3972 PFORMAT_STRING pFormat)
3974 FIXME("stub\n");
3975 return NULL;
3978 /***********************************************************************
3979 * NdrByteCountPointerUnmarshall [RPCRT4.@]
3981 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3982 unsigned char **ppMemory,
3983 PFORMAT_STRING pFormat,
3984 unsigned char fMustAlloc)
3986 FIXME("stub\n");
3987 return NULL;
3990 /***********************************************************************
3991 * NdrByteCountPointerBufferSize [RPCRT4.@]
3993 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3994 unsigned char *pMemory,
3995 PFORMAT_STRING pFormat)
3997 FIXME("stub\n");
4000 /***********************************************************************
4001 * NdrByteCountPointerMemorySize [RPCRT4.@]
4003 unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4004 PFORMAT_STRING pFormat)
4006 FIXME("stub\n");
4007 return 0;
4010 /***********************************************************************
4011 * NdrByteCountPointerFree [RPCRT4.@]
4013 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
4014 unsigned char *pMemory,
4015 PFORMAT_STRING pFormat)
4017 FIXME("stub\n");
4020 /***********************************************************************
4021 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4023 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4024 unsigned char *pMemory,
4025 PFORMAT_STRING pFormat)
4027 FIXME("stub\n");
4028 return NULL;
4031 /***********************************************************************
4032 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4034 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4035 unsigned char **ppMemory,
4036 PFORMAT_STRING pFormat,
4037 unsigned char fMustAlloc)
4039 FIXME("stub\n");
4040 return NULL;
4043 /***********************************************************************
4044 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4046 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4047 unsigned char *pMemory,
4048 PFORMAT_STRING pFormat)
4050 FIXME("stub\n");
4053 /***********************************************************************
4054 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4056 unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4057 PFORMAT_STRING pFormat)
4059 FIXME("stub\n");
4060 return 0;
4063 /***********************************************************************
4064 * NdrXmitOrRepAsFree [RPCRT4.@]
4066 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4067 unsigned char *pMemory,
4068 PFORMAT_STRING pFormat)
4070 FIXME("stub\n");
4073 /***********************************************************************
4074 * NdrBaseTypeMarshall [internal]
4076 static unsigned char *WINAPI NdrBaseTypeMarshall(
4077 PMIDL_STUB_MESSAGE pStubMsg,
4078 unsigned char *pMemory,
4079 PFORMAT_STRING pFormat)
4081 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4083 switch(*pFormat)
4085 case RPC_FC_BYTE:
4086 case RPC_FC_CHAR:
4087 case RPC_FC_SMALL:
4088 case RPC_FC_USMALL:
4089 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4090 pStubMsg->Buffer += sizeof(UCHAR);
4091 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4092 break;
4093 case RPC_FC_WCHAR:
4094 case RPC_FC_SHORT:
4095 case RPC_FC_USHORT:
4096 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4097 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4098 pStubMsg->Buffer += sizeof(USHORT);
4099 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4100 break;
4101 case RPC_FC_LONG:
4102 case RPC_FC_ULONG:
4103 case RPC_FC_ERROR_STATUS_T:
4104 case RPC_FC_ENUM32:
4105 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4106 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4107 pStubMsg->Buffer += sizeof(ULONG);
4108 TRACE("value: 0x%08lx\n", *(ULONG *)pMemory);
4109 break;
4110 case RPC_FC_FLOAT:
4111 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4112 *(float *)pStubMsg->Buffer = *(float *)pMemory;
4113 pStubMsg->Buffer += sizeof(float);
4114 break;
4115 case RPC_FC_DOUBLE:
4116 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4117 *(double *)pStubMsg->Buffer = *(double *)pMemory;
4118 pStubMsg->Buffer += sizeof(double);
4119 break;
4120 case RPC_FC_HYPER:
4121 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4122 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4123 pStubMsg->Buffer += sizeof(ULONGLONG);
4124 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4125 break;
4126 case RPC_FC_ENUM16:
4127 /* only 16-bits on the wire, so do a sanity check */
4128 if (*(UINT *)pMemory > USHRT_MAX)
4129 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4130 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4131 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4132 pStubMsg->Buffer += sizeof(USHORT);
4133 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4134 break;
4135 default:
4136 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4139 STD_OVERFLOW_CHECK(pStubMsg);
4141 /* FIXME: what is the correct return value? */
4142 return NULL;
4145 /***********************************************************************
4146 * NdrBaseTypeUnmarshall [internal]
4148 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4149 PMIDL_STUB_MESSAGE pStubMsg,
4150 unsigned char **ppMemory,
4151 PFORMAT_STRING pFormat,
4152 unsigned char fMustAlloc)
4154 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4156 if (fMustAlloc || !*ppMemory)
4158 unsigned char *Buffer = pStubMsg->Buffer;
4159 unsigned long MemorySize = pStubMsg->MemorySize;
4160 *ppMemory = NdrAllocate(pStubMsg, NdrBaseTypeMemorySize(pStubMsg, pFormat));
4161 pStubMsg->MemorySize = MemorySize;
4162 pStubMsg->Buffer = Buffer;
4165 TRACE("*ppMemory: %p\n", *ppMemory);
4167 #define BASE_TYPE_UNMARSHALL(type) \
4168 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4169 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4170 pStubMsg->Buffer += sizeof(type);
4172 switch(*pFormat)
4174 case RPC_FC_BYTE:
4175 case RPC_FC_CHAR:
4176 case RPC_FC_SMALL:
4177 case RPC_FC_USMALL:
4178 BASE_TYPE_UNMARSHALL(UCHAR);
4179 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4180 break;
4181 case RPC_FC_WCHAR:
4182 case RPC_FC_SHORT:
4183 case RPC_FC_USHORT:
4184 BASE_TYPE_UNMARSHALL(USHORT);
4185 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4186 break;
4187 case RPC_FC_LONG:
4188 case RPC_FC_ULONG:
4189 case RPC_FC_ERROR_STATUS_T:
4190 case RPC_FC_ENUM32:
4191 BASE_TYPE_UNMARSHALL(ULONG);
4192 TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory);
4193 break;
4194 case RPC_FC_FLOAT:
4195 BASE_TYPE_UNMARSHALL(float);
4196 TRACE("value: %f\n", **(float **)ppMemory);
4197 break;
4198 case RPC_FC_DOUBLE:
4199 BASE_TYPE_UNMARSHALL(double);
4200 TRACE("value: %f\n", **(double **)ppMemory);
4201 break;
4202 case RPC_FC_HYPER:
4203 BASE_TYPE_UNMARSHALL(ULONGLONG);
4204 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4205 break;
4206 case RPC_FC_ENUM16:
4207 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4208 /* 16-bits on the wire, but int in memory */
4209 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4210 pStubMsg->Buffer += sizeof(USHORT);
4211 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4212 break;
4213 default:
4214 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4216 #undef BASE_TYPE_UNMARSHALL
4218 /* FIXME: what is the correct return value? */
4220 return NULL;
4223 /***********************************************************************
4224 * NdrBaseTypeBufferSize [internal]
4226 static void WINAPI NdrBaseTypeBufferSize(
4227 PMIDL_STUB_MESSAGE pStubMsg,
4228 unsigned char *pMemory,
4229 PFORMAT_STRING pFormat)
4231 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4233 switch(*pFormat)
4235 case RPC_FC_BYTE:
4236 case RPC_FC_CHAR:
4237 case RPC_FC_SMALL:
4238 case RPC_FC_USMALL:
4239 pStubMsg->BufferLength += sizeof(UCHAR);
4240 break;
4241 case RPC_FC_WCHAR:
4242 case RPC_FC_SHORT:
4243 case RPC_FC_USHORT:
4244 case RPC_FC_ENUM16:
4245 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4246 pStubMsg->BufferLength += sizeof(USHORT);
4247 break;
4248 case RPC_FC_LONG:
4249 case RPC_FC_ULONG:
4250 case RPC_FC_ENUM32:
4251 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4252 pStubMsg->BufferLength += sizeof(ULONG);
4253 break;
4254 case RPC_FC_FLOAT:
4255 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4256 pStubMsg->BufferLength += sizeof(float);
4257 break;
4258 case RPC_FC_DOUBLE:
4259 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4260 pStubMsg->BufferLength += sizeof(double);
4261 break;
4262 case RPC_FC_HYPER:
4263 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4264 pStubMsg->BufferLength += sizeof(ULONGLONG);
4265 break;
4266 case RPC_FC_ERROR_STATUS_T:
4267 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4268 pStubMsg->BufferLength += sizeof(error_status_t);
4269 break;
4270 default:
4271 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4275 /***********************************************************************
4276 * NdrBaseTypeMemorySize [internal]
4278 static unsigned long WINAPI NdrBaseTypeMemorySize(
4279 PMIDL_STUB_MESSAGE pStubMsg,
4280 PFORMAT_STRING pFormat)
4282 switch(*pFormat)
4284 case RPC_FC_BYTE:
4285 case RPC_FC_CHAR:
4286 case RPC_FC_SMALL:
4287 case RPC_FC_USMALL:
4288 pStubMsg->Buffer += sizeof(UCHAR);
4289 pStubMsg->MemorySize += sizeof(UCHAR);
4290 return sizeof(UCHAR);
4291 case RPC_FC_WCHAR:
4292 case RPC_FC_SHORT:
4293 case RPC_FC_USHORT:
4294 pStubMsg->Buffer += sizeof(USHORT);
4295 pStubMsg->MemorySize += sizeof(USHORT);
4296 return sizeof(USHORT);
4297 case RPC_FC_LONG:
4298 case RPC_FC_ULONG:
4299 pStubMsg->Buffer += sizeof(ULONG);
4300 pStubMsg->MemorySize += sizeof(ULONG);
4301 return sizeof(ULONG);
4302 case RPC_FC_FLOAT:
4303 pStubMsg->Buffer += sizeof(float);
4304 pStubMsg->MemorySize += sizeof(float);
4305 return sizeof(float);
4306 case RPC_FC_DOUBLE:
4307 pStubMsg->Buffer += sizeof(double);
4308 pStubMsg->MemorySize += sizeof(double);
4309 return sizeof(double);
4310 case RPC_FC_HYPER:
4311 pStubMsg->Buffer += sizeof(ULONGLONG);
4312 pStubMsg->MemorySize += sizeof(ULONGLONG);
4313 return sizeof(ULONGLONG);
4314 case RPC_FC_ERROR_STATUS_T:
4315 pStubMsg->Buffer += sizeof(error_status_t);
4316 pStubMsg->MemorySize += sizeof(error_status_t);
4317 return sizeof(error_status_t);
4318 case RPC_FC_ENUM16:
4319 case RPC_FC_ENUM32:
4320 pStubMsg->Buffer += sizeof(INT);
4321 pStubMsg->MemorySize += sizeof(INT);
4322 return sizeof(INT);
4323 default:
4324 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4325 return 0;
4329 /***********************************************************************
4330 * NdrBaseTypeFree [internal]
4332 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4333 unsigned char *pMemory,
4334 PFORMAT_STRING pFormat)
4336 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4338 /* nothing to do */
4341 /***********************************************************************
4342 * NdrClientContextMarshall
4344 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4345 NDR_CCONTEXT ContextHandle,
4346 int fCheck)
4348 TRACE("(%p, %p, %d): stub\n", pStubMsg, ContextHandle, fCheck);
4349 /* FIXME: what does fCheck do? */
4350 NDRCContextMarshall(ContextHandle,
4351 pStubMsg->Buffer);
4353 pStubMsg->Buffer += cbNDRContext;
4356 /***********************************************************************
4357 * NdrClientContextUnmarshall
4359 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4360 NDR_CCONTEXT * pContextHandle,
4361 RPC_BINDING_HANDLE BindHandle)
4363 TRACE("(%p, %p, %p): stub\n", pStubMsg, pContextHandle, BindHandle);
4364 NDRCContextUnmarshall(pContextHandle,
4365 BindHandle,
4366 pStubMsg->Buffer,
4367 pStubMsg->RpcMsg->DataRepresentation);
4369 pStubMsg->Buffer += cbNDRContext;
4372 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4373 NDR_SCONTEXT ContextHandle,
4374 NDR_RUNDOWN RundownRoutine )
4376 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4379 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4381 FIXME("(%p): stub\n", pStubMsg);
4382 return NULL;
4385 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4386 unsigned char* pMemory,
4387 PFORMAT_STRING pFormat)
4389 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
4392 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
4393 PFORMAT_STRING pFormat)
4395 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4396 return NULL;
4399 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4400 NDR_SCONTEXT ContextHandle,
4401 NDR_RUNDOWN RundownRoutine,
4402 PFORMAT_STRING pFormat)
4404 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
4407 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4408 PFORMAT_STRING pFormat)
4410 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4411 return NULL;
4414 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
4416 typedef struct ndr_context_handle
4418 DWORD attributes;
4419 GUID uuid;
4420 } ndr_context_handle;
4422 struct context_handle_entry
4424 struct list entry;
4425 DWORD magic;
4426 RPC_BINDING_HANDLE handle;
4427 ndr_context_handle wire_data;
4430 static struct list context_handle_list = LIST_INIT(context_handle_list);
4432 static CRITICAL_SECTION ndr_context_cs;
4433 static CRITICAL_SECTION_DEBUG ndr_context_debug =
4435 0, 0, &ndr_context_cs,
4436 { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
4437 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
4439 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
4441 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
4443 struct context_handle_entry *che = (struct context_handle_entry*) CContext;
4445 if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
4446 return NULL;
4447 return che;
4450 static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
4452 struct context_handle_entry *che;
4453 LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
4454 if (IsEqualGUID(&che->wire_data.uuid, uuid))
4455 return che;
4456 return NULL;
4459 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
4461 struct context_handle_entry *che;
4462 RPC_BINDING_HANDLE handle = NULL;
4464 TRACE("%p\n", CContext);
4466 EnterCriticalSection(&ndr_context_cs);
4467 che = get_context_entry(CContext);
4468 if (che)
4469 handle = che->handle;
4470 LeaveCriticalSection(&ndr_context_cs);
4472 if (!handle)
4473 RpcRaiseException(ERROR_INVALID_HANDLE);
4474 return handle;
4477 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
4479 struct context_handle_entry *che;
4481 TRACE("%p %p\n", CContext, pBuff);
4483 if (CContext)
4485 EnterCriticalSection(&ndr_context_cs);
4486 che = get_context_entry(CContext);
4487 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
4488 LeaveCriticalSection(&ndr_context_cs);
4490 else
4492 ndr_context_handle *wire_data = (ndr_context_handle *)pBuff;
4493 wire_data->attributes = 0;
4494 wire_data->uuid = GUID_NULL;
4498 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
4499 RPC_BINDING_HANDLE hBinding,
4500 ndr_context_handle *chi)
4502 struct context_handle_entry *che = NULL;
4504 /* a null UUID means we should free the context handle */
4505 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
4507 if (*CContext)
4509 che = get_context_entry(*CContext);
4510 if (!che)
4511 return ERROR_INVALID_HANDLE;
4512 list_remove(&che->entry);
4513 HeapFree(GetProcessHeap(), 0, che);
4514 che = NULL;
4517 /* if there's no existing entry matching the GUID, allocate one */
4518 else if (!(che = context_entry_from_guid(&chi->uuid)))
4520 che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
4521 if (!che)
4522 return ERROR_NOT_ENOUGH_MEMORY;
4523 che->magic = NDR_CONTEXT_HANDLE_MAGIC;
4524 che->handle = hBinding;
4525 list_add_tail(&context_handle_list, &che->entry);
4526 memcpy(&che->wire_data, chi, sizeof *chi);
4529 *CContext = che;
4531 return ERROR_SUCCESS;
4534 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
4535 RPC_BINDING_HANDLE hBinding,
4536 void *pBuff,
4537 unsigned long DataRepresentation)
4539 UINT r;
4541 TRACE("*%p=(%p) %p %p %08lx\n",
4542 CContext, *CContext, hBinding, pBuff, DataRepresentation);
4544 EnterCriticalSection(&ndr_context_cs);
4545 r = ndr_update_context_handle(CContext, hBinding, pBuff);
4546 LeaveCriticalSection(&ndr_context_cs);
4547 if (r)
4548 RpcRaiseException(r);
4551 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
4552 void *pBuff,
4553 NDR_RUNDOWN userRunDownIn)
4555 FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
4558 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
4559 NDR_SCONTEXT CContext,
4560 void *pBuff,
4561 NDR_RUNDOWN userRunDownIn)
4563 FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
4566 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
4567 NDR_SCONTEXT CContext,
4568 void *pBuff,
4569 NDR_RUNDOWN userRunDownIn,
4570 void *CtxGuard,
4571 unsigned long Flags)
4573 FIXME("(%p %p %p %p %p %lu): stub\n",
4574 hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
4577 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
4578 unsigned long DataRepresentation)
4580 FIXME("(%p %08lx): stub\n", pBuff, DataRepresentation);
4581 return NULL;
4584 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
4585 void *pBuff,
4586 unsigned long DataRepresentation)
4588 FIXME("(%p %p %08lx): stub\n", hBinding, pBuff, DataRepresentation);
4589 return NULL;
4592 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
4593 void *pBuff,
4594 unsigned long DataRepresentation,
4595 void *CtxGuard,
4596 unsigned long Flags)
4598 FIXME("(%p %p %08lx %p %lu): stub\n",
4599 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
4600 return NULL;