user: Added fast 16->32 mapping for WM_COPYDATA, WM_GETDLGCODE and WM_NEXTMENU.
[wine] / dlls / rpcrt4 / ndr_marshall.c
1 /*
2  * NDR data marshalling
3  *
4  * Copyright 2002 Greg Turner
5  * Copyright 2003-2006 CodeWeavers
6  *
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.
11  *
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.
16  *
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
20  *
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
32  */
33
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <assert.h>
38 #include <limits.h>
39
40 #include "windef.h"
41 #include "winbase.h"
42 #include "winerror.h"
43 #include "winreg.h"
44
45 #include "ndr_misc.h"
46 #include "rpcndr.h"
47
48 #include "wine/unicode.h"
49 #include "wine/rpcfc.h"
50
51 #include "wine/debug.h"
52
53 WINE_DEFAULT_DEBUG_CHANNEL(ole);
54
55 #if defined(__i386__)
56 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
57     (*((UINT32 *)(pchar)) = (uint32))
58
59 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
60     (*((UINT32 *)(pchar)))
61 #else
62   /* these would work for i386 too, but less efficient */
63 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
64     (*(pchar)     = LOBYTE(LOWORD(uint32)), \
65      *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
66      *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
67      *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
68      (uint32)) /* allow as r-value */
69
70 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
71     (MAKELONG( \
72       MAKEWORD(*(pchar), *((pchar)+1)), \
73       MAKEWORD(*((pchar)+2), *((pchar)+3))))
74 #endif
75
76 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
77   (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
78    *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
79    *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
80    *(pchar)     = HIBYTE(HIWORD(uint32)), \
81    (uint32)) /* allow as r-value */
82
83 #define BIG_ENDIAN_UINT32_READ(pchar) \
84   (MAKELONG( \
85     MAKEWORD(*((pchar)+3), *((pchar)+2)), \
86     MAKEWORD(*((pchar)+1), *(pchar))))
87
88 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90     BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92     BIG_ENDIAN_UINT32_READ(pchar)
93 #else
94 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
95     LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
96 # define NDR_LOCAL_UINT32_READ(pchar) \
97     LITTLE_ENDIAN_UINT32_READ(pchar)
98 #endif
99
100 /* _Align must be the desired alignment,
101  * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
102 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
103 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
104 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
105 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
106
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108     TRACE("buffer=%d/%ld\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109     if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110         ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
111   } while (0)
112
113 #define NDR_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
115
116 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
118 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static unsigned long WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
121
122 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
123   0,
124   NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
125   NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
126   NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
127   NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
128   /* 0x10 */
129   NdrBaseTypeMarshall,
130   /* 0x11 */
131   NdrPointerMarshall, NdrPointerMarshall,
132   NdrPointerMarshall, NdrPointerMarshall,
133   /* 0x15 */
134   NdrSimpleStructMarshall, NdrSimpleStructMarshall,
135   NdrConformantStructMarshall, NdrConformantStructMarshall,
136   NdrConformantVaryingStructMarshall,
137   NdrComplexStructMarshall,
138   /* 0x1b */
139   NdrConformantArrayMarshall, 
140   NdrConformantVaryingArrayMarshall,
141   NdrFixedArrayMarshall, NdrFixedArrayMarshall,
142   NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
143   NdrComplexArrayMarshall,
144   /* 0x22 */
145   NdrConformantStringMarshall, 0, 0,
146   NdrConformantStringMarshall,
147   NdrNonConformantStringMarshall, 0, 0, 0,
148   /* 0x2a */
149   NdrEncapsulatedUnionMarshall,
150   NdrNonEncapsulatedUnionMarshall,
151   NdrByteCountPointerMarshall,
152   NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
153   /* 0x2f */
154   NdrInterfacePointerMarshall,
155   /* 0xb0 */
156   0, 0, 0, 0,
157   NdrUserMarshalMarshall
158 };
159 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
160   0,
161   NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
162   NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
163   NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
164   NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
165   /* 0x10 */
166   NdrBaseTypeUnmarshall,
167   /* 0x11 */
168   NdrPointerUnmarshall, NdrPointerUnmarshall,
169   NdrPointerUnmarshall, NdrPointerUnmarshall,
170   /* 0x15 */
171   NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
172   NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
173   NdrConformantVaryingStructUnmarshall,
174   NdrComplexStructUnmarshall,
175   /* 0x1b */
176   NdrConformantArrayUnmarshall, 
177   NdrConformantVaryingArrayUnmarshall,
178   NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
179   NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
180   NdrComplexArrayUnmarshall,
181   /* 0x22 */
182   NdrConformantStringUnmarshall, 0, 0,
183   NdrConformantStringUnmarshall,
184   NdrNonConformantStringUnmarshall, 0, 0, 0,
185   /* 0x2a */
186   NdrEncapsulatedUnionUnmarshall,
187   NdrNonEncapsulatedUnionUnmarshall,
188   NdrByteCountPointerUnmarshall,
189   NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
190   /* 0x2f */
191   NdrInterfacePointerUnmarshall,
192   /* 0xb0 */
193   0, 0, 0, 0,
194   NdrUserMarshalUnmarshall
195 };
196 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
197   0,
198   NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
199   NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
200   NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
201   NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
202   /* 0x10 */
203   NdrBaseTypeBufferSize,
204   /* 0x11 */
205   NdrPointerBufferSize, NdrPointerBufferSize,
206   NdrPointerBufferSize, NdrPointerBufferSize,
207   /* 0x15 */
208   NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
209   NdrConformantStructBufferSize, NdrConformantStructBufferSize,
210   NdrConformantVaryingStructBufferSize,
211   NdrComplexStructBufferSize,
212   /* 0x1b */
213   NdrConformantArrayBufferSize, 
214   NdrConformantVaryingArrayBufferSize,
215   NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
216   NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
217   NdrComplexArrayBufferSize,
218   /* 0x22 */
219   NdrConformantStringBufferSize, 0, 0,
220   NdrConformantStringBufferSize,
221   NdrNonConformantStringBufferSize, 0, 0, 0,
222   /* 0x2a */
223   NdrEncapsulatedUnionBufferSize,
224   NdrNonEncapsulatedUnionBufferSize,
225   NdrByteCountPointerBufferSize,
226   NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
227   /* 0x2f */
228   NdrInterfacePointerBufferSize,
229   /* 0xb0 */
230   0, 0, 0, 0,
231   NdrUserMarshalBufferSize
232 };
233 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
234   0,
235   NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
236   NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
237   NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
238   NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
239   /* 0x10 */
240   NdrBaseTypeMemorySize,
241   /* 0x11 */
242   NdrPointerMemorySize, NdrPointerMemorySize,
243   NdrPointerMemorySize, NdrPointerMemorySize,
244   /* 0x15 */
245   NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
246   NdrConformantStructMemorySize, NdrConformantStructMemorySize,
247   NdrConformantVaryingStructMemorySize,
248   NdrComplexStructMemorySize,
249   /* 0x1b */
250   NdrConformantArrayMemorySize,
251   NdrConformantVaryingArrayMemorySize,
252   NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
253   NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
254   NdrComplexArrayMemorySize,
255   /* 0x22 */
256   NdrConformantStringMemorySize, 0, 0,
257   NdrConformantStringMemorySize,
258   NdrNonConformantStringMemorySize, 0, 0, 0,
259   /* 0x2a */
260   NdrEncapsulatedUnionMemorySize,
261   NdrNonEncapsulatedUnionMemorySize,
262   NdrByteCountPointerMemorySize,
263   NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
264   /* 0x2f */
265   NdrInterfacePointerMemorySize,
266   /* 0xb0 */
267   0, 0, 0, 0,
268   NdrUserMarshalMemorySize
269 };
270 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
271   0,
272   NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
273   NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
274   NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
275   NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
276   /* 0x10 */
277   NdrBaseTypeFree,
278   /* 0x11 */
279   NdrPointerFree, NdrPointerFree,
280   NdrPointerFree, NdrPointerFree,
281   /* 0x15 */
282   NdrSimpleStructFree, NdrSimpleStructFree,
283   NdrConformantStructFree, NdrConformantStructFree,
284   NdrConformantVaryingStructFree,
285   NdrComplexStructFree,
286   /* 0x1b */
287   NdrConformantArrayFree, 
288   NdrConformantVaryingArrayFree,
289   NdrFixedArrayFree, NdrFixedArrayFree,
290   NdrVaryingArrayFree, NdrVaryingArrayFree,
291   NdrComplexArrayFree,
292   /* 0x22 */
293   0, 0, 0,
294   0, 0, 0, 0, 0,
295   /* 0x2a */
296   NdrEncapsulatedUnionFree,
297   NdrNonEncapsulatedUnionFree,
298   0,
299   NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
300   /* 0x2f */
301   NdrInterfacePointerFree,
302   /* 0xb0 */
303   0, 0, 0, 0,
304   NdrUserMarshalFree
305 };
306
307 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
308 {
309   /* hmm, this is probably supposed to do more? */
310   return pStubMsg->pfnAllocate(len);
311 }
312
313 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
314 {
315   pStubMsg->pfnFree(Pointer);
316 }
317
318 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
319 {
320     return (*(const ULONG *)pFormat != -1);
321 }
322
323 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
324 {
325   ALIGN_POINTER(pStubMsg->Buffer, 4);
326   pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
327   pStubMsg->Buffer += 4;
328   TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
329   if (pStubMsg->fHasNewCorrDesc)
330     return pFormat+6;
331   else
332     return pFormat+4;
333 }
334
335 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
336 {
337   if (pFormat && !IsConformanceOrVariancePresent(pFormat))
338   {
339     pStubMsg->Offset = 0;
340     pStubMsg->ActualCount = pStubMsg->MaxCount;
341     goto done;
342   }
343
344   ALIGN_POINTER(pStubMsg->Buffer, 4);
345   pStubMsg->Offset      = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
346   pStubMsg->Buffer += 4;
347   TRACE("offset is %ld\n", pStubMsg->Offset);
348   pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
349   pStubMsg->Buffer += 4;
350   TRACE("variance is %ld\n", pStubMsg->ActualCount);
351
352 done:
353   if (pStubMsg->fHasNewCorrDesc)
354     return pFormat+6;
355   else
356     return pFormat+4;
357 }
358
359 /* writes the conformance value to the buffer */
360 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
361 {
362     ALIGN_POINTER(pStubMsg->Buffer, 4);
363     NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
364     pStubMsg->Buffer += 4;
365 }
366
367 /* writes the variance values to the buffer */
368 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
369 {
370     ALIGN_POINTER(pStubMsg->Buffer, 4);
371     NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
372     pStubMsg->Buffer += 4;
373     NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
374     pStubMsg->Buffer += 4;
375 }
376
377 /* requests buffer space for the conformance value */
378 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
379 {
380     ALIGN_LENGTH(pStubMsg->BufferLength, 4);
381     pStubMsg->BufferLength += 4;
382 }
383
384 /* requests buffer space for the variance values */
385 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
386 {
387     ALIGN_LENGTH(pStubMsg->BufferLength, 4);
388     pStubMsg->BufferLength += 8;
389 }
390
391 PFORMAT_STRING ComputeConformanceOrVariance(
392     MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
393     PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount)
394 {
395   BYTE dtype = pFormat[0] & 0xf;
396   short ofs = *(short *)&pFormat[2];
397   LPVOID ptr = NULL;
398   DWORD data = 0;
399
400   if (!IsConformanceOrVariancePresent(pFormat)) {
401     /* null descriptor */
402     *pCount = def;
403     goto finish_conf;
404   }
405
406   switch (pFormat[0] & 0xf0) {
407   case RPC_FC_NORMAL_CONFORMANCE:
408     TRACE("normal conformance, ofs=%d\n", ofs);
409     ptr = pMemory;
410     break;
411   case RPC_FC_POINTER_CONFORMANCE:
412     TRACE("pointer conformance, ofs=%d\n", ofs);
413     ptr = pStubMsg->Memory;
414     break;
415   case RPC_FC_TOP_LEVEL_CONFORMANCE:
416     TRACE("toplevel conformance, ofs=%d\n", ofs);
417     if (pStubMsg->StackTop) {
418       ptr = pStubMsg->StackTop;
419     }
420     else {
421       /* -Os mode, *pCount is already set */
422       goto finish_conf;
423     }
424     break;
425   case RPC_FC_CONSTANT_CONFORMANCE:
426     data = ofs | ((DWORD)pFormat[1] << 16);
427     TRACE("constant conformance, val=%ld\n", data);
428     *pCount = data;
429     goto finish_conf;
430   case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
431     FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
432     if (pStubMsg->StackTop) {
433       ptr = pStubMsg->StackTop;
434     }
435     else {
436       /* ? */
437       goto done_conf_grab;
438     }
439     break;
440   default:
441     FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
442   }
443
444   switch (pFormat[1]) {
445   case RPC_FC_DEREFERENCE:
446     ptr = *(LPVOID*)((char *)ptr + ofs);
447     break;
448   case RPC_FC_CALLBACK:
449   {
450     unsigned char *old_stack_top = pStubMsg->StackTop;
451     pStubMsg->StackTop = ptr;
452
453     /* ofs is index into StubDesc->apfnExprEval */
454     TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
455     pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
456
457     pStubMsg->StackTop = old_stack_top;
458     goto finish_conf;
459   }
460   default:
461     ptr = (char *)ptr + ofs;
462     break;
463   }
464
465   switch (dtype) {
466   case RPC_FC_LONG:
467   case RPC_FC_ULONG:
468     data = *(DWORD*)ptr;
469     break;
470   case RPC_FC_SHORT:
471     data = *(SHORT*)ptr;
472     break;
473   case RPC_FC_USHORT:
474     data = *(USHORT*)ptr;
475     break;
476   case RPC_FC_CHAR:
477   case RPC_FC_SMALL:
478     data = *(CHAR*)ptr;
479     break;
480   case RPC_FC_BYTE:
481   case RPC_FC_USMALL:
482     data = *(UCHAR*)ptr;
483     break;
484   default:
485     FIXME("unknown conformance data type %x\n", dtype);
486     goto done_conf_grab;
487   }
488   TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
489
490 done_conf_grab:
491   switch (pFormat[1]) {
492   case 0: /* no op */
493     *pCount = data;
494     break;
495   case RPC_FC_DEREFERENCE:
496     /* already handled */
497     break;
498   case RPC_FC_ADD_1:
499     *pCount = data + 1;
500     break;
501   case RPC_FC_SUB_1:
502     *pCount = data - 1;
503     break;
504   case RPC_FC_MULT_2:
505     *pCount = data * 2;
506     break;
507   case RPC_FC_DIV_2:
508     *pCount = data / 2;
509     break;
510   default:
511     FIXME("unknown conformance op %d\n", pFormat[1]);
512     goto finish_conf;
513   }
514
515 finish_conf:
516   TRACE("resulting conformance is %ld\n", *pCount);
517   if (pStubMsg->fHasNewCorrDesc)
518     return pFormat+6;
519   else
520     return pFormat+4;
521 }
522
523
524 /*
525  * NdrConformantString:
526  * 
527  * What MS calls a ConformantString is, in DCE terminology,
528  * a Varying-Conformant String.
529  * [
530  *   maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
531  *   offset: DWORD (actual string data begins at (offset) CHARTYPE's
532  *           into unmarshalled string) 
533  *   length: DWORD (# of CHARTYPE characters, inclusive of '\0')
534  *   [ 
535  *     data: CHARTYPE[maxlen]
536  *   ] 
537  * ], where CHARTYPE is the appropriate character type (specified externally)
538  *
539  */
540
541 /***********************************************************************
542  *            NdrConformantStringMarshall [RPCRT4.@]
543  */
544 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
545   unsigned char *pszMessage, PFORMAT_STRING pFormat)
546
547   unsigned long esize;
548
549   TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
550   
551   if (*pFormat == RPC_FC_C_CSTRING) {
552     TRACE("string=%s\n", debugstr_a((char*)pszMessage));
553     pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
554     esize = 1;
555   }
556   else if (*pFormat == RPC_FC_C_WSTRING) {
557     TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
558     pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
559     esize = 2;
560   }
561   else {
562     ERR("Unhandled string type: %#x\n", *pFormat); 
563     /* FIXME: raise an exception. */
564     return NULL;
565   }
566
567   if (pFormat[1] == RPC_FC_STRING_SIZED)
568     pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
569   else
570     pStubMsg->MaxCount = pStubMsg->ActualCount;
571   pStubMsg->Offset = 0;
572   WriteConformance(pStubMsg);
573   WriteVariance(pStubMsg);
574
575   memcpy(pStubMsg->Buffer, pszMessage, pStubMsg->ActualCount*esize); /* the string itself */
576   pStubMsg->Buffer += pStubMsg->ActualCount*esize;
577
578   STD_OVERFLOW_CHECK(pStubMsg);
579
580   /* success */
581   return NULL; /* is this always right? */
582 }
583
584 /***********************************************************************
585  *           NdrConformantStringBufferSize [RPCRT4.@]
586  */
587 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
588   unsigned char* pMemory, PFORMAT_STRING pFormat)
589 {
590   TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
591
592   SizeConformance(pStubMsg);
593   SizeVariance(pStubMsg);
594
595   if (*pFormat == RPC_FC_C_CSTRING) {
596     /* we need + 1 octet for '\0' */
597     TRACE("string=%s\n", debugstr_a((char*)pMemory));
598     pStubMsg->BufferLength += strlen((char*)pMemory) + 1;
599   }
600   else if (*pFormat == RPC_FC_C_WSTRING) {
601     /* we need + 2 octets for L'\0' */
602     TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
603     pStubMsg->BufferLength += strlenW((LPWSTR)pMemory)*2 + 2;
604   }
605   else {
606     ERR("Unhandled string type: %#x\n", *pFormat); 
607     /* FIXME: raise an exception */
608   }
609 }
610
611 /************************************************************************
612  *            NdrConformantStringMemorySize [RPCRT4.@]
613  */
614 unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
615   PFORMAT_STRING pFormat )
616 {
617   unsigned long rslt = 0;
618
619   TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
620    
621   assert(pStubMsg && pFormat);
622
623   if (*pFormat == RPC_FC_C_CSTRING) {
624     rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
625   }
626   else if (*pFormat == RPC_FC_C_WSTRING) {
627     rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
628   }
629   else {
630     ERR("Unhandled string type: %#x\n", *pFormat);
631     /* FIXME: raise an exception */
632   }
633
634   if (pFormat[1] != RPC_FC_PAD) {
635     FIXME("sized string format=%d\n", pFormat[1]);
636   }
637
638   TRACE("  --> %lu\n", rslt);
639   return rslt;
640 }
641
642 /************************************************************************
643  *           NdrConformantStringUnmarshall [RPCRT4.@]
644  */
645 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
646   unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
647 {
648   unsigned long len, esize;
649
650   TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
651     pStubMsg, *ppMemory, pFormat, fMustAlloc);
652
653   assert(pFormat && ppMemory && pStubMsg);
654
655   ReadConformance(pStubMsg, NULL);
656   ReadVariance(pStubMsg, NULL);
657
658   if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
659   else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
660   else {
661     ERR("Unhandled string type: %#x\n", *pFormat);
662     /* FIXME: raise an exception */
663     esize = 0;
664   }
665
666   len = pStubMsg->ActualCount;
667
668   if (fMustAlloc || !*ppMemory)
669     *ppMemory = NdrAllocate(pStubMsg, len*esize);
670
671   memcpy(*ppMemory, pStubMsg->Buffer, len*esize);
672
673   pStubMsg->Buffer += len*esize;
674
675   if (*pFormat == RPC_FC_C_CSTRING) {
676     TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
677   }
678   else if (*pFormat == RPC_FC_C_WSTRING) {
679     TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
680   }
681
682   return NULL; /* FIXME: is this always right? */
683 }
684
685 /***********************************************************************
686  *           NdrNonConformantStringMarshall [RPCRT4.@]
687  */
688 unsigned char *  WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
689                                 unsigned char *pMemory,
690                                 PFORMAT_STRING pFormat)
691 {
692     FIXME("stub\n");
693     return NULL;
694 }
695
696 /***********************************************************************
697  *           NdrNonConformantStringUnmarshall [RPCRT4.@]
698  */
699 unsigned char *  WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
700                                 unsigned char **ppMemory,
701                                 PFORMAT_STRING pFormat,
702                                 unsigned char fMustAlloc)
703 {
704     FIXME("stub\n");
705     return NULL;
706 }
707
708 /***********************************************************************
709  *           NdrNonConformantStringBufferSize [RPCRT4.@]
710  */
711 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
712                                 unsigned char *pMemory,
713                                 PFORMAT_STRING pFormat)
714 {
715     FIXME("stub\n");
716 }
717
718 /***********************************************************************
719  *           NdrNonConformantStringMemorySize [RPCRT4.@]
720  */
721 unsigned long WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
722                                 PFORMAT_STRING pFormat)
723 {
724     FIXME("stub\n");
725     return 0;
726 }
727
728 static inline void dump_pointer_attr(unsigned char attr)
729 {
730     if (attr & RPC_FC_P_ALLOCALLNODES)
731         TRACE(" RPC_FC_P_ALLOCALLNODES");
732     if (attr & RPC_FC_P_DONTFREE)
733         TRACE(" RPC_FC_P_DONTFREE");
734     if (attr & RPC_FC_P_ONSTACK)
735         TRACE(" RPC_FC_P_ONSTACK");
736     if (attr & RPC_FC_P_SIMPLEPOINTER)
737         TRACE(" RPC_FC_P_SIMPLEPOINTER");
738     if (attr & RPC_FC_P_DEREF)
739         TRACE(" RPC_FC_P_DEREF");
740     TRACE("\n");
741 }
742
743 /***********************************************************************
744  *           PointerMarshall
745  */
746 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
747                             unsigned char *Buffer,
748                             unsigned char *Pointer,
749                             PFORMAT_STRING pFormat)
750 {
751   unsigned type = pFormat[0], attr = pFormat[1];
752   PFORMAT_STRING desc;
753   NDR_MARSHALL m;
754
755   TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
756   TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
757   pFormat += 2;
758   if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
759   else desc = pFormat + *(const SHORT*)pFormat;
760
761   switch (type) {
762   case RPC_FC_RP: /* ref pointer (always non-null) */
763 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
764     if (!Pointer)
765       RpcRaiseException(RPC_X_NULL_REF_POINTER);
766 #endif
767     break;
768   case RPC_FC_UP: /* unique pointer */
769   case RPC_FC_OP: /* object pointer - same as unique here */
770     TRACE("writing %p to buffer\n", Pointer);
771     NDR_LOCAL_UINT32_WRITE(Buffer, (unsigned long)Pointer);
772     break;
773   case RPC_FC_FP:
774   default:
775     FIXME("unhandled ptr type=%02x\n", type);
776     RpcRaiseException(RPC_X_BAD_STUB_DATA);
777   }
778
779   TRACE("calling marshaller for type 0x%x\n", (int)*desc);
780
781   if (Pointer) {
782     if (attr & RPC_FC_P_DEREF) {
783       Pointer = *(unsigned char**)Pointer;
784       TRACE("deref => %p\n", Pointer);
785     }
786     m = NdrMarshaller[*desc & NDR_TABLE_MASK];
787     if (m) m(pStubMsg, Pointer, desc);
788     else FIXME("no marshaller for data type=%02x\n", *desc);
789   }
790
791   STD_OVERFLOW_CHECK(pStubMsg);
792 }
793
794 /***********************************************************************
795  *           PointerUnmarshall
796  */
797 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
798                               unsigned char *Buffer,
799                               unsigned char **pPointer,
800                               PFORMAT_STRING pFormat,
801                               unsigned char fMustAlloc)
802 {
803   unsigned type = pFormat[0], attr = pFormat[1];
804   PFORMAT_STRING desc;
805   NDR_UNMARSHALL m;
806   DWORD pointer_id = 0;
807
808   TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
809   TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
810   pFormat += 2;
811   if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
812   else desc = pFormat + *(const SHORT*)pFormat;
813
814   switch (type) {
815   case RPC_FC_RP: /* ref pointer (always non-null) */
816     pointer_id = ~0UL;
817     break;
818   case RPC_FC_UP: /* unique pointer */
819     pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
820     TRACE("pointer_id is 0x%08lx\n", pointer_id);
821     break;
822   case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
823     pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
824     TRACE("pointer_id is 0x%08lx\n", pointer_id);
825     if (!fMustAlloc && *pPointer)
826         FIXME("free object pointer %p\n", *pPointer);
827     break;
828   case RPC_FC_FP:
829   default:
830     FIXME("unhandled ptr type=%02x\n", type);
831     RpcRaiseException(RPC_X_BAD_STUB_DATA);
832   }
833
834   if (pointer_id) {
835     if (attr & RPC_FC_P_DEREF) {
836       if (!*pPointer || fMustAlloc)
837         *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
838       pPointer = *(unsigned char***)pPointer;
839       TRACE("deref => %p\n", pPointer);
840     }
841     m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
842     if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
843     else FIXME("no unmarshaller for data type=%02x\n", *desc);
844   }
845
846   TRACE("pointer=%p\n", *pPointer);
847 }
848
849 /***********************************************************************
850  *           PointerBufferSize
851  */
852 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
853                               unsigned char *Pointer,
854                               PFORMAT_STRING pFormat)
855 {
856   unsigned type = pFormat[0], attr = pFormat[1];
857   PFORMAT_STRING desc;
858   NDR_BUFFERSIZE m;
859
860   TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
861   TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
862   pFormat += 2;
863   if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
864   else desc = pFormat + *(const SHORT*)pFormat;
865
866   switch (type) {
867   case RPC_FC_RP: /* ref pointer (always non-null) */
868     break;
869   case RPC_FC_OP:
870   case RPC_FC_UP:
871     /* NULL pointer has no further representation */
872     if (!Pointer)
873         return;
874     break;
875   case RPC_FC_FP:
876   default:
877     FIXME("unhandled ptr type=%02x\n", type);
878     RpcRaiseException(RPC_X_BAD_STUB_DATA);
879   }
880
881   if (attr & RPC_FC_P_DEREF) {
882     Pointer = *(unsigned char**)Pointer;
883     TRACE("deref => %p\n", Pointer);
884   }
885
886   m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
887   if (m) m(pStubMsg, Pointer, desc);
888   else FIXME("no buffersizer for data type=%02x\n", *desc);
889 }
890
891 /***********************************************************************
892  *           PointerMemorySize [RPCRT4.@]
893  */
894 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
895                                        unsigned char *Buffer,
896                                        PFORMAT_STRING pFormat)
897 {
898   unsigned type = pFormat[0], attr = pFormat[1];
899   PFORMAT_STRING desc;
900   NDR_MEMORYSIZE m;
901
902   FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
903   TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
904   pFormat += 2;
905   if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
906   else desc = pFormat + *(const SHORT*)pFormat;
907
908   switch (type) {
909   case RPC_FC_RP: /* ref pointer (always non-null) */
910     break;
911   default:
912     FIXME("unhandled ptr type=%02x\n", type);
913     RpcRaiseException(RPC_X_BAD_STUB_DATA);
914   }
915
916   if (attr & RPC_FC_P_DEREF) {
917     TRACE("deref\n");
918   }
919
920   m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
921   if (m) m(pStubMsg, desc);
922   else FIXME("no memorysizer for data type=%02x\n", *desc);
923
924   return 0;
925 }
926
927 /***********************************************************************
928  *           PointerFree [RPCRT4.@]
929  */
930 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
931                         unsigned char *Pointer,
932                         PFORMAT_STRING pFormat)
933 {
934   unsigned type = pFormat[0], attr = pFormat[1];
935   PFORMAT_STRING desc;
936   NDR_FREE m;
937
938   TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
939   TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
940   if (attr & RPC_FC_P_DONTFREE) return;
941   pFormat += 2;
942   if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
943   else desc = pFormat + *(const SHORT*)pFormat;
944
945   if (!Pointer) return;
946
947   if (attr & RPC_FC_P_DEREF) {
948     Pointer = *(unsigned char**)Pointer;
949     TRACE("deref => %p\n", Pointer);
950   }
951
952   m = NdrFreer[*desc & NDR_TABLE_MASK];
953   if (m) m(pStubMsg, Pointer, desc);
954
955   /* hmm... is this sensible?
956    * perhaps we should check if the memory comes from NdrAllocate,
957    * and deallocate only if so - checking if the pointer is between
958    * BufferStart and BufferEnd is probably no good since the buffer
959    * may be reallocated when the server wants to marshal the reply */
960   switch (*desc) {
961   case RPC_FC_BOGUS_STRUCT:
962   case RPC_FC_BOGUS_ARRAY:
963   case RPC_FC_USER_MARSHAL:
964   case RPC_FC_CARRAY:
965   case RPC_FC_CVARRAY:
966     break;
967   default:
968     FIXME("unhandled data type=%02x\n", *desc);
969     break;
970   case RPC_FC_C_CSTRING:
971   case RPC_FC_C_WSTRING:
972     if (pStubMsg->ReuseBuffer) goto notfree;
973     break;
974   case RPC_FC_IP:
975     goto notfree;
976   }
977
978   if (attr & RPC_FC_P_ONSTACK) {
979     TRACE("not freeing stack ptr %p\n", Pointer);
980     return;
981   }
982   TRACE("freeing %p\n", Pointer);
983   NdrFree(pStubMsg, Pointer);
984   return;
985 notfree:
986   TRACE("not freeing %p\n", Pointer);
987 }
988
989 /***********************************************************************
990  *           EmbeddedPointerMarshall
991  */
992 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
993                                                unsigned char *pMemory,
994                                                PFORMAT_STRING pFormat)
995 {
996   unsigned char *Mark = pStubMsg->BufferMark;
997   unsigned long Offset = pStubMsg->Offset;
998   unsigned ofs, rep, count, stride, xofs;
999   unsigned i;
1000
1001   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1002
1003   if (*pFormat != RPC_FC_PP) return NULL;
1004   pFormat += 2;
1005
1006   while (pFormat[0] != RPC_FC_END) {
1007     switch (pFormat[0]) {
1008     default:
1009       FIXME("unknown repeat type %d\n", pFormat[0]);
1010     case RPC_FC_NO_REPEAT:
1011       rep = 1;
1012       stride = 0;
1013       ofs = 0;
1014       count = 1;
1015       xofs = 0;
1016       pFormat += 2;
1017       break;
1018     case RPC_FC_FIXED_REPEAT:
1019       rep = *(const WORD*)&pFormat[2];
1020       stride = *(const WORD*)&pFormat[4];
1021       ofs = *(const WORD*)&pFormat[6];
1022       count = *(const WORD*)&pFormat[8];
1023       xofs = 0;
1024       pFormat += 10;
1025       break;
1026     case RPC_FC_VARIABLE_REPEAT:
1027       rep = pStubMsg->MaxCount;
1028       stride = *(const WORD*)&pFormat[2];
1029       ofs = *(const WORD*)&pFormat[4];
1030       count = *(const WORD*)&pFormat[6];
1031       xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1032       pFormat += 8;
1033       break;
1034     }
1035     for (i = 0; i < rep; i++) {
1036       PFORMAT_STRING info = pFormat;
1037       unsigned char *membase = pMemory + (i * stride);
1038       unsigned char *bufbase = Mark + (i * stride);
1039       unsigned u;
1040       /* ofs doesn't seem to matter in this context */
1041       for (u=0; u<count; u++,info+=8) {
1042         unsigned char *memptr = membase + *(const SHORT*)&info[0];
1043         unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1044         unsigned char *saved_memory = pStubMsg->Memory;
1045
1046         pStubMsg->Memory = pMemory;
1047         PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1048         pStubMsg->Memory = saved_memory;
1049       }
1050     }
1051     pFormat += 8 * count;
1052   }
1053
1054   STD_OVERFLOW_CHECK(pStubMsg);
1055
1056   return NULL;
1057 }
1058
1059 /***********************************************************************
1060  *           EmbeddedPointerUnmarshall
1061  */
1062 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1063                                                  unsigned char **ppMemory,
1064                                                  PFORMAT_STRING pFormat,
1065                                                  unsigned char fMustAlloc)
1066 {
1067   unsigned char *Mark = pStubMsg->BufferMark;
1068   unsigned long Offset = pStubMsg->Offset;
1069   unsigned ofs, rep, count, stride, xofs;
1070   unsigned i;
1071
1072   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1073
1074   if (*pFormat != RPC_FC_PP) return NULL;
1075   pFormat += 2;
1076
1077   while (pFormat[0] != RPC_FC_END) {
1078     TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1079     switch (pFormat[0]) {
1080     default:
1081       FIXME("unknown repeat type %d\n", pFormat[0]);
1082     case RPC_FC_NO_REPEAT:
1083       rep = 1;
1084       stride = 0;
1085       ofs = 0;
1086       count = 1;
1087       xofs = 0;
1088       pFormat += 2;
1089       break;
1090     case RPC_FC_FIXED_REPEAT:
1091       rep = *(const WORD*)&pFormat[2];
1092       stride = *(const WORD*)&pFormat[4];
1093       ofs = *(const WORD*)&pFormat[6];
1094       count = *(const WORD*)&pFormat[8];
1095       xofs = 0;
1096       pFormat += 10;
1097       break;
1098     case RPC_FC_VARIABLE_REPEAT:
1099       rep = pStubMsg->MaxCount;
1100       stride = *(const WORD*)&pFormat[2];
1101       ofs = *(const WORD*)&pFormat[4];
1102       count = *(const WORD*)&pFormat[6];
1103       xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1104       pFormat += 8;
1105       break;
1106     }
1107     /* ofs doesn't seem to matter in this context */
1108     for (i = 0; i < rep; i++) {
1109       PFORMAT_STRING info = pFormat;
1110       unsigned char *membase = *ppMemory + (i * stride);
1111       unsigned char *bufbase = Mark + (i * stride);
1112       unsigned u;
1113       for (u=0; u<count; u++,info+=8) {
1114         unsigned char *memptr = membase + *(const SHORT*)&info[0];
1115         unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1116         PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);
1117       }
1118     }
1119     pFormat += 8 * count;
1120   }
1121
1122   return NULL;
1123 }
1124
1125 /***********************************************************************
1126  *           EmbeddedPointerBufferSize
1127  */
1128 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1129                                       unsigned char *pMemory,
1130                                       PFORMAT_STRING pFormat)
1131 {
1132   unsigned long Offset = pStubMsg->Offset;
1133   unsigned ofs, rep, count, stride, xofs;
1134   unsigned i;
1135
1136   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1137
1138   if (pStubMsg->IgnoreEmbeddedPointers) return;
1139
1140   if (*pFormat != RPC_FC_PP) return;
1141   pFormat += 2;
1142
1143   while (pFormat[0] != RPC_FC_END) {
1144     switch (pFormat[0]) {
1145     default:
1146       FIXME("unknown repeat type %d\n", pFormat[0]);
1147     case RPC_FC_NO_REPEAT:
1148       rep = 1;
1149       stride = 0;
1150       ofs = 0;
1151       count = 1;
1152       xofs = 0;
1153       pFormat += 2;
1154       break;
1155     case RPC_FC_FIXED_REPEAT:
1156       rep = *(const WORD*)&pFormat[2];
1157       stride = *(const WORD*)&pFormat[4];
1158       ofs = *(const WORD*)&pFormat[6];
1159       count = *(const WORD*)&pFormat[8];
1160       xofs = 0;
1161       pFormat += 10;
1162       break;
1163     case RPC_FC_VARIABLE_REPEAT:
1164       rep = pStubMsg->MaxCount;
1165       stride = *(const WORD*)&pFormat[2];
1166       ofs = *(const WORD*)&pFormat[4];
1167       count = *(const WORD*)&pFormat[6];
1168       xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1169       pFormat += 8;
1170       break;
1171     }
1172     /* ofs doesn't seem to matter in this context */
1173     for (i = 0; i < rep; i++) {
1174       PFORMAT_STRING info = pFormat;
1175       unsigned char *membase = pMemory + (i * stride);
1176       unsigned u;
1177       for (u=0; u<count; u++,info+=8) {
1178         unsigned char *memptr = membase + *(const SHORT*)&info[0];
1179         unsigned char *saved_memory = pStubMsg->Memory;
1180
1181         pStubMsg->Memory = pMemory;
1182         PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1183         pStubMsg->Memory = saved_memory;
1184       }
1185     }
1186     pFormat += 8 * count;
1187   }
1188 }
1189
1190 /***********************************************************************
1191  *           EmbeddedPointerMemorySize
1192  */
1193 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1194                                                PFORMAT_STRING pFormat)
1195 {
1196   unsigned long Offset = pStubMsg->Offset;
1197   unsigned char *Mark = pStubMsg->BufferMark;
1198   unsigned ofs, rep, count, stride, xofs;
1199   unsigned i;
1200
1201   FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1202
1203   if (*pFormat != RPC_FC_PP) return 0;
1204   pFormat += 2;
1205
1206   while (pFormat[0] != RPC_FC_END) {
1207     switch (pFormat[0]) {
1208     default:
1209       FIXME("unknown repeat type %d\n", pFormat[0]);
1210     case RPC_FC_NO_REPEAT:
1211       rep = 1;
1212       stride = 0;
1213       ofs = 0;
1214       count = 1;
1215       xofs = 0;
1216       pFormat += 2;
1217       break;
1218     case RPC_FC_FIXED_REPEAT:
1219       rep = *(const WORD*)&pFormat[2];
1220       stride = *(const WORD*)&pFormat[4];
1221       ofs = *(const WORD*)&pFormat[6];
1222       count = *(const WORD*)&pFormat[8];
1223       xofs = 0;
1224       pFormat += 10;
1225       break;
1226     case RPC_FC_VARIABLE_REPEAT:
1227       rep = pStubMsg->MaxCount;
1228       stride = *(const WORD*)&pFormat[2];
1229       ofs = *(const WORD*)&pFormat[4];
1230       count = *(const WORD*)&pFormat[6];
1231       xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1232       pFormat += 8;
1233       break;
1234     }
1235     /* ofs doesn't seem to matter in this context */
1236     for (i = 0; i < rep; i++) {
1237       PFORMAT_STRING info = pFormat;
1238       unsigned char *bufbase = Mark + (i * stride);
1239       unsigned u;
1240       for (u=0; u<count; u++,info+=8) {
1241         unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1242         PointerMemorySize(pStubMsg, bufptr, info+4);
1243       }
1244     }
1245     pFormat += 8 * count;
1246   }
1247
1248   return 0;
1249 }
1250
1251 /***********************************************************************
1252  *           EmbeddedPointerFree
1253  */
1254 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1255                                 unsigned char *pMemory,
1256                                 PFORMAT_STRING pFormat)
1257 {
1258   unsigned long Offset = pStubMsg->Offset;
1259   unsigned ofs, rep, count, stride, xofs;
1260   unsigned i;
1261
1262   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1263   if (*pFormat != RPC_FC_PP) return;
1264   pFormat += 2;
1265
1266   while (pFormat[0] != RPC_FC_END) {
1267     switch (pFormat[0]) {
1268     default:
1269       FIXME("unknown repeat type %d\n", pFormat[0]);
1270     case RPC_FC_NO_REPEAT:
1271       rep = 1;
1272       stride = 0;
1273       ofs = 0;
1274       count = 1;
1275       xofs = 0;
1276       pFormat += 2;
1277       break;
1278     case RPC_FC_FIXED_REPEAT:
1279       rep = *(const WORD*)&pFormat[2];
1280       stride = *(const WORD*)&pFormat[4];
1281       ofs = *(const WORD*)&pFormat[6];
1282       count = *(const WORD*)&pFormat[8];
1283       xofs = 0;
1284       pFormat += 10;
1285       break;
1286     case RPC_FC_VARIABLE_REPEAT:
1287       rep = pStubMsg->MaxCount;
1288       stride = *(const WORD*)&pFormat[2];
1289       ofs = *(const WORD*)&pFormat[4];
1290       count = *(const WORD*)&pFormat[6];
1291       xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1292       pFormat += 8;
1293       break;
1294     }
1295     /* ofs doesn't seem to matter in this context */
1296     for (i = 0; i < rep; i++) {
1297       PFORMAT_STRING info = pFormat;
1298       unsigned char *membase = pMemory + (i * stride);
1299       unsigned u;
1300       for (u=0; u<count; u++,info+=8) {
1301         unsigned char *memptr = membase + *(const SHORT*)&info[0];
1302         unsigned char *saved_memory = pStubMsg->Memory;
1303
1304         pStubMsg->Memory = pMemory;
1305         PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1306         pStubMsg->Memory = saved_memory;
1307       }
1308     }
1309     pFormat += 8 * count;
1310   }
1311 }
1312
1313 /***********************************************************************
1314  *           NdrPointerMarshall [RPCRT4.@]
1315  */
1316 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1317                                           unsigned char *pMemory,
1318                                           PFORMAT_STRING pFormat)
1319 {
1320   unsigned char *Buffer;
1321
1322   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1323
1324   /* incremement the buffer here instead of in PointerMarshall,
1325    * as that is used by embedded pointers which already handle the incrementing
1326    * the buffer, and shouldn't write any additional pointer data to the wire */
1327   if (*pFormat != RPC_FC_RP)
1328   {
1329     ALIGN_POINTER(pStubMsg->Buffer, 4);
1330     Buffer = pStubMsg->Buffer;
1331     pStubMsg->Buffer += 4;
1332   }
1333   else
1334     Buffer = pStubMsg->Buffer;
1335
1336   PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1337
1338   STD_OVERFLOW_CHECK(pStubMsg);
1339
1340   return NULL;
1341 }
1342
1343 /***********************************************************************
1344  *           NdrPointerUnmarshall [RPCRT4.@]
1345  */
1346 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1347                                             unsigned char **ppMemory,
1348                                             PFORMAT_STRING pFormat,
1349                                             unsigned char fMustAlloc)
1350 {
1351   unsigned char *Buffer;
1352
1353   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1354
1355   /* incremement the buffer here instead of in PointerUnmarshall,
1356    * as that is used by embedded pointers which already handle the incrementing
1357    * the buffer, and shouldn't read any additional pointer data from the
1358    * buffer */
1359   if (*pFormat != RPC_FC_RP)
1360   {
1361     ALIGN_POINTER(pStubMsg->Buffer, 4);
1362     Buffer = pStubMsg->Buffer;
1363     pStubMsg->Buffer += 4;
1364   }
1365   else
1366     Buffer = pStubMsg->Buffer;
1367
1368   PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1369
1370   return NULL;
1371 }
1372
1373 /***********************************************************************
1374  *           NdrPointerBufferSize [RPCRT4.@]
1375  */
1376 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1377                                       unsigned char *pMemory,
1378                                       PFORMAT_STRING pFormat)
1379 {
1380   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1381
1382   /* incremement the buffer length here instead of in PointerBufferSize,
1383    * as that is used by embedded pointers which already handle the buffer
1384    * length, and shouldn't write anything more to the wire */
1385   if (*pFormat != RPC_FC_RP)
1386   {
1387     ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1388     pStubMsg->BufferLength += 4;
1389   }
1390
1391   PointerBufferSize(pStubMsg, pMemory, pFormat);
1392 }
1393
1394 /***********************************************************************
1395  *           NdrPointerMemorySize [RPCRT4.@]
1396  */
1397 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1398                                           PFORMAT_STRING pFormat)
1399 {
1400   /* unsigned size = *(LPWORD)(pFormat+2); */
1401   FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1402   PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1403   return 0;
1404 }
1405
1406 /***********************************************************************
1407  *           NdrPointerFree [RPCRT4.@]
1408  */
1409 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1410                            unsigned char *pMemory,
1411                            PFORMAT_STRING pFormat)
1412 {
1413   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1414   PointerFree(pStubMsg, pMemory, pFormat);
1415 }
1416
1417 /***********************************************************************
1418  *           NdrSimpleTypeMarshall [RPCRT4.@]
1419  */
1420 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1421                                    unsigned char FormatChar )
1422 {
1423     FIXME("stub\n");
1424 }
1425
1426 /***********************************************************************
1427  *           NdrSimpleTypeUnmarshall [RPCRT4.@]
1428  */
1429 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1430                                      unsigned char FormatChar )
1431 {
1432     FIXME("stub\n");
1433 }
1434
1435 /***********************************************************************
1436  *           NdrSimpleStructMarshall [RPCRT4.@]
1437  */
1438 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1439                                                unsigned char *pMemory,
1440                                                PFORMAT_STRING pFormat)
1441 {
1442   unsigned size = *(const WORD*)(pFormat+2);
1443   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1444
1445   ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1446
1447   memcpy(pStubMsg->Buffer, pMemory, size);
1448   pStubMsg->BufferMark = pStubMsg->Buffer;
1449   pStubMsg->Buffer += size;
1450
1451   if (pFormat[0] != RPC_FC_STRUCT)
1452     EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1453
1454   STD_OVERFLOW_CHECK(pStubMsg);
1455
1456   return NULL;
1457 }
1458
1459 /***********************************************************************
1460  *           NdrSimpleStructUnmarshall [RPCRT4.@]
1461  */
1462 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1463                                                  unsigned char **ppMemory,
1464                                                  PFORMAT_STRING pFormat,
1465                                                  unsigned char fMustAlloc)
1466 {
1467   unsigned size = *(const WORD*)(pFormat+2);
1468   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1469
1470   ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1471
1472   if (fMustAlloc) {
1473     *ppMemory = NdrAllocate(pStubMsg, size);
1474     memcpy(*ppMemory, pStubMsg->Buffer, size);
1475   } else {
1476     if (!pStubMsg->IsClient && !*ppMemory)
1477       /* for servers, we just point straight into the RPC buffer */
1478       *ppMemory = pStubMsg->Buffer;
1479     else
1480       /* for clients, memory should be provided by caller */
1481       memcpy(*ppMemory, pStubMsg->Buffer, size);
1482   }
1483
1484   pStubMsg->BufferMark = pStubMsg->Buffer;
1485   pStubMsg->Buffer += size;
1486
1487   if (pFormat[0] != RPC_FC_STRUCT)
1488     EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1489
1490   return NULL;
1491 }
1492
1493 /***********************************************************************
1494  *           NdrSimpleStructBufferSize [RPCRT4.@]
1495  */
1496 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1497                                       unsigned char *pMemory,
1498                                       PFORMAT_STRING pFormat)
1499 {
1500   unsigned size = *(const WORD*)(pFormat+2);
1501   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1502
1503   ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1504
1505   pStubMsg->BufferLength += size;
1506   if (pFormat[0] != RPC_FC_STRUCT)
1507     EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1508 }
1509
1510 /***********************************************************************
1511  *           NdrSimpleStructMemorySize [RPCRT4.@]
1512  */
1513 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1514                                                PFORMAT_STRING pFormat)
1515 {
1516   unsigned short size = *(LPWORD)(pFormat+2);
1517
1518   TRACE("(%p,%p)\n", pStubMsg, pFormat);
1519
1520   ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1521   pStubMsg->MemorySize += size;
1522   pStubMsg->Buffer += size;
1523
1524   if (pFormat[0] != RPC_FC_STRUCT)
1525     EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1526   return size;
1527 }
1528
1529 /***********************************************************************
1530  *           NdrSimpleStructFree [RPCRT4.@]
1531  */
1532 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1533                                 unsigned char *pMemory,
1534                                 PFORMAT_STRING pFormat)
1535 {
1536   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1537   if (pFormat[0] != RPC_FC_STRUCT)
1538     EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1539 }
1540
1541
1542 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1543                                          PFORMAT_STRING pFormat)
1544 {
1545   switch (*pFormat) {
1546   case RPC_FC_STRUCT:
1547   case RPC_FC_PSTRUCT:
1548   case RPC_FC_CSTRUCT:
1549   case RPC_FC_BOGUS_STRUCT:
1550     return *(const WORD*)&pFormat[2];
1551   case RPC_FC_USER_MARSHAL:
1552     return *(const WORD*)&pFormat[4];
1553   case RPC_FC_NON_ENCAPSULATED_UNION:
1554     pFormat += 2;
1555     if (pStubMsg->fHasNewCorrDesc)
1556         pFormat += 6;
1557     else
1558         pFormat += 4;
1559
1560     pFormat += *(const SHORT*)pFormat;
1561     return *(const SHORT*)pFormat;
1562   case RPC_FC_IP:
1563     return sizeof(void *);
1564   default:
1565     FIXME("unhandled embedded type %02x\n", *pFormat);
1566   }
1567   return 0;
1568 }
1569
1570
1571 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1572                                                PFORMAT_STRING pFormat)
1573 {
1574   NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1575
1576   if (!m)
1577   {
1578     FIXME("no memorysizer for data type=%02x\n", *pFormat);
1579     return 0;
1580   }
1581
1582   return m(pStubMsg, pFormat);
1583 }
1584
1585
1586 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1587                                        unsigned char *pMemory,
1588                                        PFORMAT_STRING pFormat,
1589                                        PFORMAT_STRING pPointer)
1590 {
1591   PFORMAT_STRING desc;
1592   NDR_MARSHALL m;
1593   unsigned long size;
1594
1595   while (*pFormat != RPC_FC_END) {
1596     switch (*pFormat) {
1597     case RPC_FC_SHORT:
1598     case RPC_FC_USHORT:
1599       TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1600       memcpy(pStubMsg->Buffer, pMemory, 2);
1601       pStubMsg->Buffer += 2;
1602       pMemory += 2;
1603       break;
1604     case RPC_FC_LONG:
1605     case RPC_FC_ULONG:
1606     case RPC_FC_ENUM32:
1607       TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1608       memcpy(pStubMsg->Buffer, pMemory, 4);
1609       pStubMsg->Buffer += 4;
1610       pMemory += 4;
1611       break;
1612     case RPC_FC_POINTER:
1613       TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1614       NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1615       pPointer += 4;
1616       pMemory += 4;
1617       break;
1618     case RPC_FC_ALIGNM4:
1619       ALIGN_POINTER(pMemory, 4);
1620       break;
1621     case RPC_FC_ALIGNM8:
1622       ALIGN_POINTER(pMemory, 8);
1623       break;
1624     case RPC_FC_STRUCTPAD2:
1625       pMemory += 2;
1626       break;
1627     case RPC_FC_EMBEDDED_COMPLEX:
1628       pMemory += pFormat[1];
1629       pFormat += 2;
1630       desc = pFormat + *(const SHORT*)pFormat;
1631       size = EmbeddedComplexSize(pStubMsg, desc);
1632       TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1633       m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1634       if (m) m(pStubMsg, pMemory, desc);
1635       else FIXME("no marshaller for embedded type %02x\n", *desc);
1636       pMemory += size;
1637       pFormat += 2;
1638       continue;
1639     case RPC_FC_PAD:
1640       break;
1641     default:
1642       FIXME("unhandled format %02x\n", *pFormat);
1643     }
1644     pFormat++;
1645   }
1646
1647   return pMemory;
1648 }
1649
1650 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1651                                          unsigned char *pMemory,
1652                                          PFORMAT_STRING pFormat,
1653                                          PFORMAT_STRING pPointer,
1654                                          unsigned char fMustAlloc)
1655 {
1656   PFORMAT_STRING desc;
1657   NDR_UNMARSHALL m;
1658   unsigned long size;
1659
1660   while (*pFormat != RPC_FC_END) {
1661     switch (*pFormat) {
1662     case RPC_FC_SHORT:
1663     case RPC_FC_USHORT:
1664       memcpy(pMemory, pStubMsg->Buffer, 2);
1665       TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1666       pStubMsg->Buffer += 2;
1667       pMemory += 2;
1668       break;
1669     case RPC_FC_LONG:
1670     case RPC_FC_ULONG:
1671     case RPC_FC_ENUM32:
1672       memcpy(pMemory, pStubMsg->Buffer, 4);
1673       TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1674       pStubMsg->Buffer += 4;
1675       pMemory += 4;
1676       break;
1677     case RPC_FC_POINTER:
1678       TRACE("pointer => %p\n", pMemory);
1679       NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, TRUE);
1680       pPointer += 4;
1681       pMemory += 4;
1682       break;
1683     case RPC_FC_ALIGNM4:
1684       ALIGN_POINTER(pMemory, 4);
1685       break;
1686     case RPC_FC_ALIGNM8:
1687       ALIGN_POINTER(pMemory, 8);
1688       break;
1689     case RPC_FC_STRUCTPAD2:
1690       pMemory += 2;
1691       break;
1692     case RPC_FC_EMBEDDED_COMPLEX:
1693       pMemory += pFormat[1];
1694       pFormat += 2;
1695       desc = pFormat + *(const SHORT*)pFormat;
1696       size = EmbeddedComplexSize(pStubMsg, desc);
1697       TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1698       m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1699       memset(pMemory, 0, size); /* just in case */
1700       if (m) m(pStubMsg, &pMemory, desc, fMustAlloc);
1701       else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1702       pMemory += size;
1703       pFormat += 2;
1704       continue;
1705     case RPC_FC_PAD:
1706       break;
1707     default:
1708       FIXME("unhandled format %d\n", *pFormat);
1709     }
1710     pFormat++;
1711   }
1712
1713   return pMemory;
1714 }
1715
1716 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1717                                          unsigned char *pMemory,
1718                                          PFORMAT_STRING pFormat,
1719                                          PFORMAT_STRING pPointer)
1720 {
1721   PFORMAT_STRING desc;
1722   NDR_BUFFERSIZE m;
1723   unsigned long size;
1724
1725   while (*pFormat != RPC_FC_END) {
1726     switch (*pFormat) {
1727     case RPC_FC_SHORT:
1728     case RPC_FC_USHORT:
1729       pStubMsg->BufferLength += 2;
1730       pMemory += 2;
1731       break;
1732     case RPC_FC_LONG:
1733     case RPC_FC_ULONG:
1734     case RPC_FC_ENUM32:
1735       pStubMsg->BufferLength += 4;
1736       pMemory += 4;
1737       break;
1738     case RPC_FC_POINTER:
1739       NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1740       pPointer += 4;
1741       pMemory += 4;
1742       break;
1743     case RPC_FC_ALIGNM4:
1744       ALIGN_POINTER(pMemory, 4);
1745       break;
1746     case RPC_FC_ALIGNM8:
1747       ALIGN_POINTER(pMemory, 8);
1748       break;
1749     case RPC_FC_STRUCTPAD2:
1750       pMemory += 2;
1751       break;
1752     case RPC_FC_EMBEDDED_COMPLEX:
1753       pMemory += pFormat[1];
1754       pFormat += 2;
1755       desc = pFormat + *(const SHORT*)pFormat;
1756       size = EmbeddedComplexSize(pStubMsg, desc);
1757       m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1758       if (m) m(pStubMsg, pMemory, desc);
1759       else FIXME("no buffersizer for embedded type %02x\n", *desc);
1760       pMemory += size;
1761       pFormat += 2;
1762       continue;
1763     case RPC_FC_PAD:
1764       break;
1765     default:
1766       FIXME("unhandled format %d\n", *pFormat);
1767     }
1768     pFormat++;
1769   }
1770
1771   return pMemory;
1772 }
1773
1774 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1775                                    unsigned char *pMemory,
1776                                    PFORMAT_STRING pFormat,
1777                                    PFORMAT_STRING pPointer)
1778 {
1779   PFORMAT_STRING desc;
1780   NDR_FREE m;
1781   unsigned long size;
1782
1783   while (*pFormat != RPC_FC_END) {
1784     switch (*pFormat) {
1785     case RPC_FC_SHORT:
1786     case RPC_FC_USHORT:
1787       pMemory += 2;
1788       break;
1789     case RPC_FC_LONG:
1790     case RPC_FC_ULONG:
1791     case RPC_FC_ENUM32:
1792       pMemory += 4;
1793       break;
1794     case RPC_FC_POINTER:
1795       NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1796       pPointer += 4;
1797       pMemory += 4;
1798       break;
1799     case RPC_FC_ALIGNM4:
1800       ALIGN_POINTER(pMemory, 4);
1801       break;
1802     case RPC_FC_ALIGNM8:
1803       ALIGN_POINTER(pMemory, 8);
1804       break;
1805     case RPC_FC_STRUCTPAD2:
1806       pMemory += 2;
1807       break;
1808     case RPC_FC_EMBEDDED_COMPLEX:
1809       pMemory += pFormat[1];
1810       pFormat += 2;
1811       desc = pFormat + *(const SHORT*)pFormat;
1812       size = EmbeddedComplexSize(pStubMsg, desc);
1813       m = NdrFreer[*desc & NDR_TABLE_MASK];
1814       if (m) m(pStubMsg, pMemory, desc);
1815       else FIXME("no freer for embedded type %02x\n", *desc);
1816       pMemory += size;
1817       pFormat += 2;
1818       continue;
1819     case RPC_FC_PAD:
1820       break;
1821     default:
1822       FIXME("unhandled format %d\n", *pFormat);
1823     }
1824     pFormat++;
1825   }
1826
1827   return pMemory;
1828 }
1829
1830 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1831                                        PFORMAT_STRING pFormat)
1832 {
1833   PFORMAT_STRING desc;
1834   unsigned long size = 0;
1835
1836   while (*pFormat != RPC_FC_END) {
1837     switch (*pFormat) {
1838     case RPC_FC_SHORT:
1839     case RPC_FC_USHORT:
1840       size += 2;
1841       pStubMsg->Buffer += 2;
1842       break;
1843     case RPC_FC_LONG:
1844     case RPC_FC_ULONG:
1845       size += 4;
1846       pStubMsg->Buffer += 4;
1847       break;
1848     case RPC_FC_POINTER:
1849       size += 4;
1850       pStubMsg->Buffer += 4;
1851       break;
1852     case RPC_FC_ALIGNM4:
1853       ALIGN_LENGTH(size, 4);
1854       ALIGN_POINTER(pStubMsg->Buffer, 4);
1855       break;
1856     case RPC_FC_ALIGNM8:
1857       ALIGN_LENGTH(size, 8);
1858       ALIGN_POINTER(pStubMsg->Buffer, 8);
1859       break;
1860     case RPC_FC_STRUCTPAD2:
1861       size += 2;
1862       pStubMsg->Buffer += 2;
1863       break;
1864     case RPC_FC_EMBEDDED_COMPLEX:
1865       size += pFormat[1];
1866       pFormat += 2;
1867       desc = pFormat + *(const SHORT*)pFormat;
1868       size += EmbeddedComplexMemorySize(pStubMsg, desc);
1869       pFormat += 2;
1870       continue;
1871     case RPC_FC_PAD:
1872       break;
1873     default:
1874       FIXME("unhandled format %d\n", *pFormat);
1875     }
1876     pFormat++;
1877   }
1878
1879   return size;
1880 }
1881
1882 /***********************************************************************
1883  *           NdrComplexStructMarshall [RPCRT4.@]
1884  */
1885 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1886                                                 unsigned char *pMemory,
1887                                                 PFORMAT_STRING pFormat)
1888 {
1889   PFORMAT_STRING conf_array = NULL;
1890   PFORMAT_STRING pointer_desc = NULL;
1891   unsigned char *OldMemory = pStubMsg->Memory;
1892
1893   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1894
1895   ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1896
1897   pFormat += 4;
1898   if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1899   pFormat += 2;
1900   if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1901   pFormat += 2;
1902
1903   pStubMsg->Memory = pMemory;
1904
1905   ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
1906
1907   if (conf_array)
1908     NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
1909
1910   pStubMsg->Memory = OldMemory;
1911
1912   STD_OVERFLOW_CHECK(pStubMsg);
1913
1914   return NULL;
1915 }
1916
1917 /***********************************************************************
1918  *           NdrComplexStructUnmarshall [RPCRT4.@]
1919  */
1920 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1921                                                   unsigned char **ppMemory,
1922                                                   PFORMAT_STRING pFormat,
1923                                                   unsigned char fMustAlloc)
1924 {
1925   unsigned size = *(const WORD*)(pFormat+2);
1926   PFORMAT_STRING conf_array = NULL;
1927   PFORMAT_STRING pointer_desc = NULL;
1928   unsigned char *pMemory;
1929
1930   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1931
1932   ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1933
1934   if (fMustAlloc || !*ppMemory)
1935   {
1936     *ppMemory = NdrAllocate(pStubMsg, size);
1937     memset(*ppMemory, 0, size);
1938   }
1939
1940   pFormat += 4;
1941   if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1942   pFormat += 2;
1943   if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1944   pFormat += 2;
1945
1946   pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
1947
1948   if (conf_array)
1949     NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
1950
1951   return NULL;
1952 }
1953
1954 /***********************************************************************
1955  *           NdrComplexStructBufferSize [RPCRT4.@]
1956  */
1957 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1958                                        unsigned char *pMemory,
1959                                        PFORMAT_STRING pFormat)
1960 {
1961   PFORMAT_STRING conf_array = NULL;
1962   PFORMAT_STRING pointer_desc = NULL;
1963   unsigned char *OldMemory = pStubMsg->Memory;
1964
1965   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1966
1967   ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1968
1969   pFormat += 4;
1970   if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1971   pFormat += 2;
1972   if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1973   pFormat += 2;
1974
1975   pStubMsg->Memory = pMemory;
1976
1977   pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
1978
1979   if (conf_array)
1980     NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
1981
1982   pStubMsg->Memory = OldMemory;
1983 }
1984
1985 /***********************************************************************
1986  *           NdrComplexStructMemorySize [RPCRT4.@]
1987  */
1988 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1989                                                 PFORMAT_STRING pFormat)
1990 {
1991   unsigned size = *(const WORD*)(pFormat+2);
1992   PFORMAT_STRING conf_array = NULL;
1993   PFORMAT_STRING pointer_desc = NULL;
1994
1995   TRACE("(%p,%p)\n", pStubMsg, pFormat);
1996
1997   ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1998
1999   pFormat += 4;
2000   if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2001   pFormat += 2;
2002   if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2003   pFormat += 2;
2004
2005   ComplexStructMemorySize(pStubMsg, pFormat);
2006
2007   if (conf_array)
2008     NdrConformantArrayMemorySize(pStubMsg, conf_array);
2009
2010   return size;
2011 }
2012
2013 /***********************************************************************
2014  *           NdrComplexStructFree [RPCRT4.@]
2015  */
2016 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2017                                  unsigned char *pMemory,
2018                                  PFORMAT_STRING pFormat)
2019 {
2020   PFORMAT_STRING conf_array = NULL;
2021   PFORMAT_STRING pointer_desc = NULL;
2022   unsigned char *OldMemory = pStubMsg->Memory;
2023
2024   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2025
2026   pFormat += 4;
2027   if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2028   pFormat += 2;
2029   if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2030   pFormat += 2;
2031
2032   pStubMsg->Memory = pMemory;
2033
2034   pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2035
2036   if (conf_array)
2037     NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2038
2039   pStubMsg->Memory = OldMemory;
2040 }
2041
2042 /***********************************************************************
2043  *           NdrConformantArrayMarshall [RPCRT4.@]
2044  */
2045 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2046                                                   unsigned char *pMemory,
2047                                                   PFORMAT_STRING pFormat)
2048 {
2049   DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2050   unsigned char alignment = pFormat[1] + 1;
2051
2052   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2053   if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2054
2055   pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2056   size = pStubMsg->MaxCount;
2057
2058   WriteConformance(pStubMsg);
2059
2060   ALIGN_POINTER(pStubMsg->Buffer, alignment);
2061
2062   memcpy(pStubMsg->Buffer, pMemory, size*esize);
2063   pStubMsg->BufferMark = pStubMsg->Buffer;
2064   pStubMsg->Buffer += size*esize;
2065
2066   EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2067
2068   STD_OVERFLOW_CHECK(pStubMsg);
2069
2070   return NULL;
2071 }
2072
2073 /***********************************************************************
2074  *           NdrConformantArrayUnmarshall [RPCRT4.@]
2075  */
2076 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2077                                                     unsigned char **ppMemory,
2078                                                     PFORMAT_STRING pFormat,
2079                                                     unsigned char fMustAlloc)
2080 {
2081   DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2082   unsigned char alignment = pFormat[1] + 1;
2083
2084   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2085   if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2086
2087   pFormat = ReadConformance(pStubMsg, pFormat+4);
2088   size = pStubMsg->MaxCount;
2089
2090   if (fMustAlloc || !*ppMemory)
2091     *ppMemory = NdrAllocate(pStubMsg, size*esize);
2092
2093   ALIGN_POINTER(pStubMsg->Buffer, alignment);
2094
2095   memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
2096
2097   pStubMsg->BufferMark = pStubMsg->Buffer;
2098   pStubMsg->Buffer += size*esize;
2099
2100   EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2101
2102   return NULL;
2103 }
2104
2105 /***********************************************************************
2106  *           NdrConformantArrayBufferSize [RPCRT4.@]
2107  */
2108 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2109                                          unsigned char *pMemory,
2110                                          PFORMAT_STRING pFormat)
2111 {
2112   DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2113   unsigned char alignment = pFormat[1] + 1;
2114
2115   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2116   if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2117
2118   pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2119   size = pStubMsg->MaxCount;
2120
2121   SizeConformance(pStubMsg);
2122
2123   ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2124
2125   /* conformance value plus array */
2126   pStubMsg->BufferLength += size*esize;
2127
2128   EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2129 }
2130
2131 /***********************************************************************
2132  *           NdrConformantArrayMemorySize [RPCRT4.@]
2133  */
2134 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2135                                                   PFORMAT_STRING pFormat)
2136 {
2137   DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2138   unsigned char alignment = pFormat[1] + 1;
2139
2140   TRACE("(%p,%p)\n", pStubMsg, pFormat);
2141   if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2142
2143   pFormat = ReadConformance(pStubMsg, pFormat+4);
2144   size = pStubMsg->MaxCount;
2145   pStubMsg->MemorySize += size*esize;
2146
2147   ALIGN_POINTER(pStubMsg->Buffer, alignment);
2148   pStubMsg->BufferMark = pStubMsg->Buffer;
2149   pStubMsg->Buffer += size*esize;
2150
2151   EmbeddedPointerMemorySize(pStubMsg, pFormat);
2152
2153   return pStubMsg->MemorySize;
2154 }
2155
2156 /***********************************************************************
2157  *           NdrConformantArrayFree [RPCRT4.@]
2158  */
2159 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2160                                    unsigned char *pMemory,
2161                                    PFORMAT_STRING pFormat)
2162 {
2163   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2164   if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2165
2166   EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2167 }
2168
2169
2170 /***********************************************************************
2171  *           NdrConformantVaryingArrayMarshall  [RPCRT4.@]
2172  */
2173 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2174                                                          unsigned char* pMemory,
2175                                                          PFORMAT_STRING pFormat )
2176 {
2177     unsigned char alignment = pFormat[1] + 1;
2178     DWORD esize = *(const WORD*)(pFormat+2);
2179
2180     TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2181
2182     if (pFormat[0] != RPC_FC_CVARRAY)
2183     {
2184         ERR("invalid format type %x\n", pFormat[0]);
2185         RpcRaiseException(RPC_S_INTERNAL_ERROR);
2186         return NULL;
2187     }
2188
2189     pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2190     pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2191
2192     WriteConformance(pStubMsg);
2193     WriteVariance(pStubMsg);
2194
2195     ALIGN_POINTER(pStubMsg->Buffer, alignment);
2196
2197     memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, pStubMsg->ActualCount*esize);
2198     pStubMsg->BufferMark = pStubMsg->Buffer;
2199     pStubMsg->Buffer += pStubMsg->ActualCount*esize;
2200
2201     EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2202
2203     STD_OVERFLOW_CHECK(pStubMsg);
2204
2205     return NULL;
2206 }
2207
2208
2209 /***********************************************************************
2210  *           NdrConformantVaryingArrayUnmarshall  [RPCRT4.@]
2211  */
2212 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2213                                                            unsigned char** ppMemory,
2214                                                            PFORMAT_STRING pFormat,
2215                                                            unsigned char fMustAlloc )
2216 {
2217     unsigned char alignment = pFormat[1] + 1;
2218     DWORD esize = *(const WORD*)(pFormat+2);
2219
2220     TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2221
2222     if (pFormat[0] != RPC_FC_CVARRAY)
2223     {
2224         ERR("invalid format type %x\n", pFormat[0]);
2225         RpcRaiseException(RPC_S_INTERNAL_ERROR);
2226         return NULL;
2227     }
2228
2229     pFormat = ReadConformance(pStubMsg, pFormat);
2230     pFormat = ReadVariance(pStubMsg, pFormat);
2231
2232     ALIGN_POINTER(pStubMsg->Buffer, alignment);
2233
2234     if (!*ppMemory || fMustAlloc)
2235         *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize);
2236     memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, pStubMsg->ActualCount * esize);
2237     pStubMsg->Buffer += pStubMsg->ActualCount * esize;
2238
2239     EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2240
2241     return NULL;
2242 }
2243
2244
2245 /***********************************************************************
2246  *           NdrConformantVaryingArrayFree  [RPCRT4.@]
2247  */
2248 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2249                                            unsigned char* pMemory,
2250                                            PFORMAT_STRING pFormat )
2251 {
2252     TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2253
2254     if (pFormat[0] != RPC_FC_CVARRAY)
2255     {
2256         ERR("invalid format type %x\n", pFormat[0]);
2257         RpcRaiseException(RPC_S_INTERNAL_ERROR);
2258         return;
2259     }
2260
2261     pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2262     pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2263
2264     EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2265 }
2266
2267
2268 /***********************************************************************
2269  *           NdrConformantVaryingArrayBufferSize  [RPCRT4.@]
2270  */
2271 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2272                                                  unsigned char* pMemory, PFORMAT_STRING pFormat )
2273 {
2274     unsigned char alignment = pFormat[1] + 1;
2275     DWORD esize = *(const WORD*)(pFormat+2);
2276
2277     TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2278
2279     if (pFormat[0] != RPC_FC_CVARRAY)
2280     {
2281         ERR("invalid format type %x\n", pFormat[0]);
2282         RpcRaiseException(RPC_S_INTERNAL_ERROR);
2283         return;
2284     }
2285
2286     /* compute size */
2287     pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2288     /* compute length */
2289     pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2290
2291     SizeConformance(pStubMsg);
2292     SizeVariance(pStubMsg);
2293
2294     ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2295
2296     pStubMsg->BufferLength += pStubMsg->ActualCount*esize;
2297
2298     EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2299 }
2300
2301
2302 /***********************************************************************
2303  *           NdrConformantVaryingArrayMemorySize  [RPCRT4.@]
2304  */
2305 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2306                                                           PFORMAT_STRING pFormat )
2307 {
2308     FIXME( "stub\n" );
2309     return 0;
2310 }
2311
2312
2313 /***********************************************************************
2314  *           NdrComplexArrayMarshall [RPCRT4.@]
2315  */
2316 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2317                                                unsigned char *pMemory,
2318                                                PFORMAT_STRING pFormat)
2319 {
2320   ULONG i, count, def;
2321   BOOL variance_present;
2322   unsigned char alignment;
2323
2324   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2325
2326   if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2327   {
2328       ERR("invalid format type %x\n", pFormat[0]);
2329       RpcRaiseException(RPC_S_INTERNAL_ERROR);
2330       return NULL;
2331   }
2332
2333   alignment = pFormat[1] + 1;
2334
2335   def = *(const WORD*)&pFormat[2];
2336   pFormat += 4;
2337
2338   pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2339   TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2340
2341   variance_present = IsConformanceOrVariancePresent(pFormat);
2342   pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2343   TRACE("variance = %ld\n", pStubMsg->ActualCount);
2344
2345   WriteConformance(pStubMsg);
2346   if (variance_present)
2347     WriteVariance(pStubMsg);
2348
2349   ALIGN_POINTER(pStubMsg->Buffer, alignment);
2350
2351   count = pStubMsg->ActualCount;
2352   for (i = 0; i < count; i++)
2353     pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2354
2355   STD_OVERFLOW_CHECK(pStubMsg);
2356
2357   return NULL;
2358 }
2359
2360 /***********************************************************************
2361  *           NdrComplexArrayUnmarshall [RPCRT4.@]
2362  */
2363 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2364                                                  unsigned char **ppMemory,
2365                                                  PFORMAT_STRING pFormat,
2366                                                  unsigned char fMustAlloc)
2367 {
2368   ULONG i, count, esize;
2369   unsigned char alignment;
2370   unsigned char *pMemory;
2371   unsigned char *Buffer;
2372
2373   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2374
2375   if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2376   {
2377       ERR("invalid format type %x\n", pFormat[0]);
2378       RpcRaiseException(RPC_S_INTERNAL_ERROR);
2379       return NULL;
2380   }
2381
2382   alignment = pFormat[1] + 1;
2383
2384   pFormat += 4;
2385
2386   pFormat = ReadConformance(pStubMsg, pFormat);
2387   pFormat = ReadVariance(pStubMsg, pFormat);
2388
2389   Buffer = pStubMsg->Buffer;
2390   esize = ComplexStructMemorySize(pStubMsg, pFormat);
2391   pStubMsg->Buffer = Buffer;
2392
2393   if (fMustAlloc || !*ppMemory)
2394   {
2395     *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize);
2396     memset(*ppMemory, 0, pStubMsg->MaxCount * esize);
2397   }
2398
2399   ALIGN_POINTER(pStubMsg->Buffer, alignment);
2400
2401   pMemory = *ppMemory;
2402   count = pStubMsg->ActualCount;
2403   for (i = 0; i < count; i++)
2404     pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2405
2406   return NULL;
2407 }
2408
2409 /***********************************************************************
2410  *           NdrComplexArrayBufferSize [RPCRT4.@]
2411  */
2412 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2413                                       unsigned char *pMemory,
2414                                       PFORMAT_STRING pFormat)
2415 {
2416   ULONG i, count, def;
2417   unsigned char alignment;
2418   BOOL variance_present;
2419
2420   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2421
2422   if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2423   {
2424       ERR("invalid format type %x\n", pFormat[0]);
2425       RpcRaiseException(RPC_S_INTERNAL_ERROR);
2426       return;
2427   }
2428
2429   alignment = pFormat[1] + 1;
2430
2431   def = *(const WORD*)&pFormat[2];
2432   pFormat += 4;
2433
2434   pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2435   TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2436   SizeConformance(pStubMsg);
2437
2438   variance_present = IsConformanceOrVariancePresent(pFormat);
2439   pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2440   TRACE("variance = %ld\n", pStubMsg->ActualCount);
2441
2442   if (variance_present)
2443     SizeVariance(pStubMsg);
2444
2445   ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2446
2447   count = pStubMsg->ActualCount;
2448   for (i = 0; i < count; i++)
2449     pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2450 }
2451
2452 /***********************************************************************
2453  *           NdrComplexArrayMemorySize [RPCRT4.@]
2454  */
2455 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2456                                                PFORMAT_STRING pFormat)
2457 {
2458   ULONG i, count, esize;
2459   unsigned char alignment;
2460   unsigned char *Buffer;
2461   unsigned long SavedMemorySize;
2462   unsigned long MemorySize;
2463
2464   TRACE("(%p,%p)\n", pStubMsg, pFormat);
2465
2466   if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2467   {
2468       ERR("invalid format type %x\n", pFormat[0]);
2469       RpcRaiseException(RPC_S_INTERNAL_ERROR);
2470       return 0;
2471   }
2472
2473   alignment = pFormat[1] + 1;
2474
2475   pFormat += 4;
2476
2477   pFormat = ReadConformance(pStubMsg, pFormat);
2478   pFormat = ReadVariance(pStubMsg, pFormat);
2479
2480   ALIGN_POINTER(pStubMsg->Buffer, alignment);
2481
2482   SavedMemorySize = pStubMsg->MemorySize;
2483
2484   Buffer = pStubMsg->Buffer;
2485   esize = ComplexStructMemorySize(pStubMsg, pFormat);
2486   pStubMsg->Buffer = Buffer;
2487
2488   MemorySize = esize * pStubMsg->MaxCount;
2489
2490   count = pStubMsg->ActualCount;
2491   for (i = 0; i < count; i++)
2492     ComplexStructMemorySize(pStubMsg, pFormat);
2493
2494   pStubMsg->MemorySize = SavedMemorySize;
2495
2496   pStubMsg->MemorySize += MemorySize;
2497   return MemorySize;
2498 }
2499
2500 /***********************************************************************
2501  *           NdrComplexArrayFree [RPCRT4.@]
2502  */
2503 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2504                                 unsigned char *pMemory,
2505                                 PFORMAT_STRING pFormat)
2506 {
2507   ULONG i, count, def;
2508
2509   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2510
2511   if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2512   {
2513       ERR("invalid format type %x\n", pFormat[0]);
2514       RpcRaiseException(RPC_S_INTERNAL_ERROR);
2515       return;
2516   }
2517
2518   def = *(const WORD*)&pFormat[2];
2519   pFormat += 4;
2520
2521   pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2522   TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2523
2524   pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2525   TRACE("variance = %ld\n", pStubMsg->ActualCount);
2526
2527   count = pStubMsg->ActualCount;
2528   for (i = 0; i < count; i++)
2529     pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2530 }
2531
2532 unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2533 {
2534   return MAKELONG(pStubMsg->dwDestContext,
2535                   pStubMsg->RpcMsg->DataRepresentation);
2536 }
2537
2538 #define USER_MARSHAL_PTR_PREFIX \
2539         ( (DWORD)'U'         | ( (DWORD)'s' << 8 ) | \
2540         ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2541
2542 /***********************************************************************
2543  *           NdrUserMarshalMarshall [RPCRT4.@]
2544  */
2545 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2546                                               unsigned char *pMemory,
2547                                               PFORMAT_STRING pFormat)
2548 {
2549   unsigned flags = pFormat[1];
2550   unsigned index = *(const WORD*)&pFormat[2];
2551   unsigned long uflag = UserMarshalFlags(pStubMsg);
2552   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2553   TRACE("index=%d\n", index);
2554
2555   if (flags & USER_MARSHAL_POINTER)
2556   {
2557     ALIGN_POINTER(pStubMsg->Buffer, 4);
2558     NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
2559     pStubMsg->Buffer += 4;
2560     ALIGN_POINTER(pStubMsg->Buffer, 8);
2561   }
2562   else
2563     ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2564
2565   pStubMsg->Buffer =
2566     pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2567       &uflag, pStubMsg->Buffer, pMemory);
2568
2569   STD_OVERFLOW_CHECK(pStubMsg);
2570
2571   return NULL;
2572 }
2573
2574 /***********************************************************************
2575  *           NdrUserMarshalUnmarshall [RPCRT4.@]
2576  */
2577 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2578                                                  unsigned char **ppMemory,
2579                                                  PFORMAT_STRING pFormat,
2580                                                  unsigned char fMustAlloc)
2581 {
2582   unsigned flags = pFormat[1];
2583   unsigned index = *(const WORD*)&pFormat[2];
2584   DWORD memsize = *(const WORD*)&pFormat[4];
2585   unsigned long uflag = UserMarshalFlags(pStubMsg);
2586   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2587   TRACE("index=%d\n", index);
2588
2589   if (flags & USER_MARSHAL_POINTER)
2590   {
2591     ALIGN_POINTER(pStubMsg->Buffer, 4);
2592     /* skip pointer prefix */
2593     pStubMsg->Buffer += 4;
2594     ALIGN_POINTER(pStubMsg->Buffer, 8);
2595   }
2596   else
2597     ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2598
2599   if (fMustAlloc || !*ppMemory)
2600     *ppMemory = NdrAllocate(pStubMsg, memsize);
2601
2602   pStubMsg->Buffer =
2603     pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2604       &uflag, pStubMsg->Buffer, *ppMemory);
2605
2606   return NULL;
2607 }
2608
2609 /***********************************************************************
2610  *           NdrUserMarshalBufferSize [RPCRT4.@]
2611  */
2612 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2613                                       unsigned char *pMemory,
2614                                       PFORMAT_STRING pFormat)
2615 {
2616   unsigned flags = pFormat[1];
2617   unsigned index = *(const WORD*)&pFormat[2];
2618   DWORD bufsize = *(const WORD*)&pFormat[6];
2619   unsigned long uflag = UserMarshalFlags(pStubMsg);
2620   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2621   TRACE("index=%d\n", index);
2622
2623   if (flags & USER_MARSHAL_POINTER)
2624   {
2625     ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2626     /* skip pointer prefix */
2627     pStubMsg->BufferLength += 4;
2628     ALIGN_LENGTH(pStubMsg->BufferLength, 8);
2629   }
2630   else
2631     ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
2632
2633   if (bufsize) {
2634     TRACE("size=%ld\n", bufsize);
2635     pStubMsg->BufferLength += bufsize;
2636     return;
2637   }
2638
2639   pStubMsg->BufferLength =
2640     pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2641       &uflag, pStubMsg->BufferLength, pMemory);
2642 }
2643
2644 /***********************************************************************
2645  *           NdrUserMarshalMemorySize [RPCRT4.@]
2646  */
2647 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2648                                               PFORMAT_STRING pFormat)
2649 {
2650   unsigned flags = pFormat[1];
2651   unsigned index = *(const WORD*)&pFormat[2];
2652   DWORD memsize = *(const WORD*)&pFormat[4];
2653   DWORD bufsize = *(const WORD*)&pFormat[6];
2654
2655   TRACE("(%p,%p)\n", pStubMsg, pFormat);
2656   TRACE("index=%d\n", index);
2657
2658   pStubMsg->MemorySize += memsize;
2659
2660   if (flags & USER_MARSHAL_POINTER)
2661   {
2662     ALIGN_POINTER(pStubMsg->Buffer, 4);
2663     /* skip pointer prefix */
2664     pStubMsg->Buffer += 4;
2665     ALIGN_POINTER(pStubMsg->Buffer, 8);
2666   }
2667   else
2668     ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
2669
2670   pStubMsg->Buffer += bufsize;
2671
2672   return pStubMsg->MemorySize;
2673 }
2674
2675 /***********************************************************************
2676  *           NdrUserMarshalFree [RPCRT4.@]
2677  */
2678 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2679                                 unsigned char *pMemory,
2680                                 PFORMAT_STRING pFormat)
2681 {
2682 /*  unsigned flags = pFormat[1]; */
2683   unsigned index = *(const WORD*)&pFormat[2];
2684   unsigned long uflag = UserMarshalFlags(pStubMsg);
2685   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2686   TRACE("index=%d\n", index);
2687
2688   pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2689     &uflag, pMemory);
2690 }
2691
2692 /***********************************************************************
2693  *           NdrClearOutParameters [RPCRT4.@]
2694  */
2695 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2696                                   PFORMAT_STRING pFormat,
2697                                   void *ArgAddr)
2698 {
2699   FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2700 }
2701
2702 /***********************************************************************
2703  *           NdrConvert [RPCRT4.@]
2704  */
2705 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2706 {
2707   FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2708   /* FIXME: since this stub doesn't do any converting, the proper behavior
2709      is to raise an exception */
2710 }
2711
2712 /***********************************************************************
2713  *           NdrConvert2 [RPCRT4.@]
2714  */
2715 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2716 {
2717   FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2718     pStubMsg, pFormat, NumberParams);
2719   /* FIXME: since this stub doesn't do any converting, the proper behavior
2720      is to raise an exception */
2721 }
2722
2723 typedef struct _NDR_CSTRUCT_FORMAT
2724 {
2725     unsigned char type;
2726     unsigned char alignment;
2727     unsigned short memory_size;
2728     short offset_to_array_description;
2729 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2730
2731 /***********************************************************************
2732  *           NdrConformantStructMarshall [RPCRT4.@]
2733  */
2734 unsigned char *  WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2735                                 unsigned char *pMemory,
2736                                 PFORMAT_STRING pFormat)
2737 {
2738     const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2739     PFORMAT_STRING pCArrayFormat;
2740     ULONG esize;
2741
2742     TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2743
2744     pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2745     if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2746     {
2747         ERR("invalid format type %x\n", pCStructFormat->type);
2748         RpcRaiseException(RPC_S_INTERNAL_ERROR);
2749         return NULL;
2750     }
2751
2752     pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2753         pCStructFormat->offset_to_array_description;
2754     if (*pCArrayFormat != RPC_FC_CARRAY)
2755     {
2756         ERR("invalid array format type %x\n", pCStructFormat->type);
2757         RpcRaiseException(RPC_S_INTERNAL_ERROR);
2758         return NULL;
2759     }
2760     esize = *(const WORD*)(pCArrayFormat+2);
2761
2762     ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2763                        pCArrayFormat + 4, 0);
2764
2765     WriteConformance(pStubMsg);
2766
2767     ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2768
2769     TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2770
2771     /* copy constant sized part of struct */
2772     pStubMsg->BufferMark = pStubMsg->Buffer;
2773     memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + pStubMsg->MaxCount * esize);
2774     pStubMsg->Buffer += pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2775
2776     if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2777         EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2778
2779     STD_OVERFLOW_CHECK(pStubMsg);
2780
2781     return NULL;
2782 }
2783
2784 /***********************************************************************
2785  *           NdrConformantStructUnmarshall [RPCRT4.@]
2786  */
2787 unsigned char *  WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2788                                 unsigned char **ppMemory,
2789                                 PFORMAT_STRING pFormat,
2790                                 unsigned char fMustAlloc)
2791 {
2792     const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2793     PFORMAT_STRING pCArrayFormat;
2794     ULONG esize;
2795
2796     TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2797
2798     pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2799     if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2800     {
2801         ERR("invalid format type %x\n", pCStructFormat->type);
2802         RpcRaiseException(RPC_S_INTERNAL_ERROR);
2803         return NULL;
2804     }
2805     pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2806         pCStructFormat->offset_to_array_description;
2807     if (*pCArrayFormat != RPC_FC_CARRAY)
2808     {
2809         ERR("invalid array format type %x\n", pCStructFormat->type);
2810         RpcRaiseException(RPC_S_INTERNAL_ERROR);
2811         return NULL;
2812     }
2813     esize = *(const WORD*)(pCArrayFormat+2);
2814
2815     pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
2816
2817     ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2818
2819     TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2820
2821     /* work out how much memory to allocate if we need to do so */
2822     if (!*ppMemory || fMustAlloc)
2823     {
2824         SIZE_T size = pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2825         *ppMemory = NdrAllocate(pStubMsg, size);
2826     }
2827
2828     /* now copy the data */
2829     pStubMsg->BufferMark = pStubMsg->Buffer;
2830     memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + pStubMsg->MaxCount * esize);
2831     pStubMsg->Buffer += pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2832
2833     if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2834         EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2835
2836     return NULL;
2837 }
2838
2839 /***********************************************************************
2840  *           NdrConformantStructBufferSize [RPCRT4.@]
2841  */
2842 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2843                                 unsigned char *pMemory,
2844                                 PFORMAT_STRING pFormat)
2845 {
2846     const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2847     PFORMAT_STRING pCArrayFormat;
2848     ULONG esize;
2849
2850     TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2851
2852     pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2853     if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2854     {
2855         ERR("invalid format type %x\n", pCStructFormat->type);
2856         RpcRaiseException(RPC_S_INTERNAL_ERROR);
2857         return;
2858     }
2859     pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2860         pCStructFormat->offset_to_array_description;
2861     if (*pCArrayFormat != RPC_FC_CARRAY)
2862     {
2863         ERR("invalid array format type %x\n", pCStructFormat->type);
2864         RpcRaiseException(RPC_S_INTERNAL_ERROR);
2865         return;
2866     }
2867     esize = *(const WORD*)(pCArrayFormat+2);
2868
2869     pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
2870     SizeConformance(pStubMsg);
2871
2872     ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
2873
2874     TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2875
2876     pStubMsg->BufferLength += pCStructFormat->memory_size + esize * pStubMsg->MaxCount;
2877
2878     if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2879         EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2880 }
2881
2882 /***********************************************************************
2883  *           NdrConformantStructMemorySize [RPCRT4.@]
2884  */
2885 unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2886                                 PFORMAT_STRING pFormat)
2887 {
2888     FIXME("stub\n");
2889     return 0;
2890 }
2891
2892 /***********************************************************************
2893  *           NdrConformantStructFree [RPCRT4.@]
2894  */
2895 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2896                                 unsigned char *pMemory,
2897                                 PFORMAT_STRING pFormat)
2898 {
2899     FIXME("stub\n");
2900 }
2901
2902 /***********************************************************************
2903  *           NdrConformantVaryingStructMarshall [RPCRT4.@]
2904  */
2905 unsigned char *  WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2906                                 unsigned char *pMemory,
2907                                 PFORMAT_STRING pFormat)
2908 {
2909     const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
2910     PFORMAT_STRING pCVArrayFormat;
2911     ULONG esize;
2912
2913     TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2914
2915     pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
2916     if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
2917     {
2918         ERR("invalid format type %x\n", pCVStructFormat->type);
2919         RpcRaiseException(RPC_S_INTERNAL_ERROR);
2920         return NULL;
2921     }
2922
2923     pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
2924         pCVStructFormat->offset_to_array_description;
2925     switch (*pCVArrayFormat)
2926     {
2927     case RPC_FC_CVARRAY:
2928         esize = *(const WORD*)(pCVArrayFormat+2);
2929
2930         pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2931                                             pCVArrayFormat + 4, 0);
2932         pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2933                                          pCVArrayFormat, 0);
2934         break;
2935     case RPC_FC_C_CSTRING:
2936         TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
2937         pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
2938         esize = sizeof(char);
2939         if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
2940             pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2941                                                 pCVArrayFormat + 2, 0);
2942         else
2943             pStubMsg->MaxCount = pStubMsg->ActualCount;
2944         break;
2945     case RPC_FC_C_WSTRING:
2946         TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
2947         pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
2948         esize = sizeof(WCHAR);
2949         if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
2950             pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2951                                                 pCVArrayFormat + 2, 0);
2952         else
2953             pStubMsg->MaxCount = pStubMsg->ActualCount;
2954         break;
2955     default:
2956         ERR("invalid array format type %x\n", *pCVArrayFormat);
2957         RpcRaiseException(RPC_S_INTERNAL_ERROR);
2958         return NULL;
2959     }
2960
2961     WriteConformance(pStubMsg);
2962
2963     ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
2964
2965     TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
2966
2967     /* write constant sized part */
2968     pStubMsg->BufferMark = pStubMsg->Buffer;
2969     memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
2970     pStubMsg->Buffer += pCVStructFormat->memory_size;
2971
2972     WriteVariance(pStubMsg);
2973
2974     /* write array part */
2975     memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, pStubMsg->ActualCount * esize);
2976     pStubMsg->Buffer += pStubMsg->ActualCount * esize;
2977
2978     EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2979
2980     STD_OVERFLOW_CHECK(pStubMsg);
2981
2982     return NULL;
2983 }
2984
2985 /***********************************************************************
2986  *           NdrConformantVaryingStructUnmarshall [RPCRT4.@]
2987  */
2988 unsigned char *  WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2989                                 unsigned char **ppMemory,
2990                                 PFORMAT_STRING pFormat,
2991                                 unsigned char fMustAlloc)
2992 {
2993     const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
2994     PFORMAT_STRING pCVArrayFormat;
2995     ULONG esize;
2996     unsigned char cvarray_type;
2997
2998     TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2999
3000     pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3001     if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3002     {
3003         ERR("invalid format type %x\n", pCVStructFormat->type);
3004         RpcRaiseException(RPC_S_INTERNAL_ERROR);
3005         return NULL;
3006     }
3007
3008     pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3009         pCVStructFormat->offset_to_array_description;
3010     cvarray_type = *pCVArrayFormat;
3011     switch (cvarray_type)
3012     {
3013     case RPC_FC_CVARRAY:
3014         esize = *(const WORD*)(pCVArrayFormat+2);
3015         pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3016         break;
3017     case RPC_FC_C_CSTRING:
3018         esize = sizeof(char);
3019         if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3020             pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3021         else
3022             pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3023         break;
3024     case RPC_FC_C_WSTRING:
3025         esize = sizeof(WCHAR);
3026         if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3027             pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3028         else
3029             pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3030         break;
3031     default:
3032         ERR("invalid array format type %x\n", *pCVArrayFormat);
3033         RpcRaiseException(RPC_S_INTERNAL_ERROR);
3034         return NULL;
3035     }
3036
3037     ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3038
3039     TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3040
3041     /* work out how much memory to allocate if we need to do so */
3042     if (!*ppMemory || fMustAlloc)
3043     {
3044         SIZE_T size = pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3045         *ppMemory = NdrAllocate(pStubMsg, size);
3046     }
3047
3048     /* copy the constant data */
3049     pStubMsg->BufferMark = pStubMsg->Buffer;
3050     memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
3051     pStubMsg->Buffer += pCVStructFormat->memory_size;
3052
3053     pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat);
3054
3055     /* copy the array data */
3056     memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
3057            pStubMsg->ActualCount * esize);
3058     pStubMsg->Buffer += pStubMsg->ActualCount * esize;
3059
3060     if (cvarray_type == RPC_FC_C_CSTRING)
3061         TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
3062     else if (cvarray_type == RPC_FC_C_WSTRING)
3063         TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
3064
3065     EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3066
3067     return NULL;
3068 }
3069
3070 /***********************************************************************
3071  *           NdrConformantVaryingStructBufferSize [RPCRT4.@]
3072  */
3073 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3074                                 unsigned char *pMemory,
3075                                 PFORMAT_STRING pFormat)
3076 {
3077     const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3078     PFORMAT_STRING pCVArrayFormat;
3079     ULONG esize;
3080
3081     TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3082
3083     pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3084     if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3085     {
3086         ERR("invalid format type %x\n", pCVStructFormat->type);
3087         RpcRaiseException(RPC_S_INTERNAL_ERROR);
3088         return;
3089     }
3090
3091     pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3092         pCVStructFormat->offset_to_array_description;
3093     switch (*pCVArrayFormat)
3094     {
3095     case RPC_FC_CVARRAY:
3096         esize = *(const WORD*)(pCVArrayFormat+2);
3097
3098         pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3099                                             pCVArrayFormat + 4, 0);
3100         pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3101                                          pCVArrayFormat + 4, 0);
3102         break;
3103     case RPC_FC_C_CSTRING:
3104         TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3105         pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3106         esize = sizeof(char);
3107         if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3108             pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3109                                                 pCVArrayFormat + 2, 0);
3110         else
3111             pStubMsg->MaxCount = pStubMsg->ActualCount;
3112         break;
3113     case RPC_FC_C_WSTRING:
3114         TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3115         pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3116         esize = sizeof(WCHAR);
3117         if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3118             pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3119                                                 pCVArrayFormat + 2, 0);
3120         else
3121             pStubMsg->MaxCount = pStubMsg->ActualCount;
3122         break;
3123     default:
3124         ERR("invalid array format type %x\n", *pCVArrayFormat);
3125         RpcRaiseException(RPC_S_INTERNAL_ERROR);
3126         return;
3127     }
3128
3129     SizeConformance(pStubMsg);
3130
3131     ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3132
3133     TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3134
3135     pStubMsg->BufferLength += pCVStructFormat->memory_size;
3136     SizeVariance(pStubMsg);
3137     pStubMsg->BufferLength += esize * pStubMsg->MaxCount;
3138
3139     EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3140 }
3141
3142 /***********************************************************************
3143  *           NdrConformantVaryingStructMemorySize [RPCRT4.@]
3144  */
3145 unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3146                                 PFORMAT_STRING pFormat)
3147 {
3148     const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3149     PFORMAT_STRING pCVArrayFormat;
3150     ULONG esize;
3151     unsigned char cvarray_type;
3152
3153     TRACE("(%p, %p)\n", pStubMsg, pFormat);
3154
3155     pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3156     if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3157     {
3158         ERR("invalid format type %x\n", pCVStructFormat->type);
3159         RpcRaiseException(RPC_S_INTERNAL_ERROR);
3160         return 0;
3161     }
3162
3163     pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3164         pCVStructFormat->offset_to_array_description;
3165     cvarray_type = *pCVArrayFormat;
3166     switch (cvarray_type)
3167     {
3168     case RPC_FC_CVARRAY:
3169         esize = *(const WORD*)(pCVArrayFormat+2);
3170         pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3171         break;
3172     case RPC_FC_C_CSTRING:
3173         esize = sizeof(char);
3174         if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3175             pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3176         else
3177             pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3178         break;
3179     case RPC_FC_C_WSTRING:
3180         esize = sizeof(WCHAR);
3181         if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3182             pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3183         else
3184             pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3185         break;
3186     default:
3187         ERR("invalid array format type %x\n", *pCVArrayFormat);
3188         RpcRaiseException(RPC_S_INTERNAL_ERROR);
3189         return 0;
3190     }
3191
3192     ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3193
3194     TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3195
3196     pStubMsg->Buffer += pCVStructFormat->memory_size;
3197     pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat);
3198     pStubMsg->Buffer += pCVStructFormat->memory_size + pStubMsg->ActualCount * esize;
3199
3200     pStubMsg->MemorySize += pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3201
3202     EmbeddedPointerMemorySize(pStubMsg, pFormat);
3203
3204     return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3205 }
3206
3207 /***********************************************************************
3208  *           NdrConformantVaryingStructFree [RPCRT4.@]
3209  */
3210 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3211                                 unsigned char *pMemory,
3212                                 PFORMAT_STRING pFormat)
3213 {
3214     const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3215     PFORMAT_STRING pCVArrayFormat;
3216     ULONG esize;
3217
3218     TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3219
3220     pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3221     if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3222     {
3223         ERR("invalid format type %x\n", pCVStructFormat->type);
3224         RpcRaiseException(RPC_S_INTERNAL_ERROR);
3225         return;
3226     }
3227
3228     pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3229         pCVStructFormat->offset_to_array_description;
3230     switch (*pCVArrayFormat)
3231     {
3232     case RPC_FC_CVARRAY:
3233         esize = *(const WORD*)(pCVArrayFormat+2);
3234
3235         pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3236                                             pCVArrayFormat + 4, 0);
3237         pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3238                                          pCVArrayFormat, 0);
3239         break;
3240     case RPC_FC_C_CSTRING:
3241         TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3242         pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3243         esize = sizeof(char);
3244         if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3245             pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3246                                                 pCVArrayFormat + 2, 0);
3247         else
3248             pStubMsg->MaxCount = pStubMsg->ActualCount;
3249         break;
3250     case RPC_FC_C_WSTRING:
3251         TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3252         pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3253         esize = sizeof(WCHAR);
3254         if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3255             pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3256                                                 pCVArrayFormat + 2, 0);
3257         else
3258             pStubMsg->MaxCount = pStubMsg->ActualCount;
3259         break;
3260     default:
3261         ERR("invalid array format type %x\n", *pCVArrayFormat);
3262         RpcRaiseException(RPC_S_INTERNAL_ERROR);
3263         return;
3264     }
3265
3266     TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3267
3268     EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3269 }
3270
3271 typedef struct
3272 {
3273     unsigned char type;
3274     unsigned char alignment;
3275     unsigned short total_size;
3276 } NDR_SMFARRAY_FORMAT;
3277
3278 typedef struct
3279 {
3280     unsigned char type;
3281     unsigned char alignment;
3282     unsigned long total_size;
3283 } NDR_LGFARRAY_FORMAT;
3284
3285 /***********************************************************************
3286  *           NdrFixedArrayMarshall [RPCRT4.@]
3287  */
3288 unsigned char *  WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3289                                 unsigned char *pMemory,
3290                                 PFORMAT_STRING pFormat)
3291 {
3292     const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3293     unsigned long total_size;
3294
3295     TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3296
3297     if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3298         (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3299     {
3300         ERR("invalid format type %x\n", pSmFArrayFormat->type);
3301         RpcRaiseException(RPC_S_INTERNAL_ERROR);
3302         return NULL;
3303     }
3304
3305     ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3306
3307     if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3308     {
3309         total_size = pSmFArrayFormat->total_size;
3310         pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3311     }
3312     else
3313     {
3314         const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3315         total_size = pLgFArrayFormat->total_size;
3316         pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3317     }
3318     memcpy(pStubMsg->Buffer, pMemory, total_size);
3319     pStubMsg->Buffer += total_size;
3320
3321     pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3322
3323     return NULL;
3324 }
3325
3326 /***********************************************************************
3327  *           NdrFixedArrayUnmarshall [RPCRT4.@]
3328  */
3329 unsigned char *  WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3330                                 unsigned char **ppMemory,
3331                                 PFORMAT_STRING pFormat,
3332                                 unsigned char fMustAlloc)
3333 {
3334     const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3335     unsigned long total_size;
3336
3337     TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3338
3339     if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3340         (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3341     {
3342         ERR("invalid format type %x\n", pSmFArrayFormat->type);
3343         RpcRaiseException(RPC_S_INTERNAL_ERROR);
3344         return NULL;
3345     }
3346
3347     ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3348
3349     if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3350     {
3351         total_size = pSmFArrayFormat->total_size;
3352         pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3353     }
3354     else
3355     {
3356         const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3357         total_size = pLgFArrayFormat->total_size;
3358         pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3359     }
3360
3361     if (fMustAlloc || !*ppMemory)
3362         *ppMemory = NdrAllocate(pStubMsg, total_size);
3363     memcpy(*ppMemory, pStubMsg->Buffer, total_size);
3364     pStubMsg->Buffer += total_size;
3365
3366     pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
3367
3368     return NULL;
3369 }
3370
3371 /***********************************************************************
3372  *           NdrFixedArrayBufferSize [RPCRT4.@]
3373  */
3374 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3375                                 unsigned char *pMemory,
3376                                 PFORMAT_STRING pFormat)
3377 {
3378     const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3379     unsigned long total_size;
3380
3381     TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3382
3383     if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3384         (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3385     {
3386         ERR("invalid format type %x\n", pSmFArrayFormat->type);
3387         RpcRaiseException(RPC_S_INTERNAL_ERROR);
3388         return;
3389     }
3390
3391     ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
3392
3393     if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3394     {
3395         total_size = pSmFArrayFormat->total_size;
3396         pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3397     }
3398     else
3399     {
3400         const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3401         total_size = pLgFArrayFormat->total_size;
3402         pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3403     }
3404     pStubMsg->BufferLength += total_size;
3405
3406     EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3407 }
3408
3409 /***********************************************************************
3410  *           NdrFixedArrayMemorySize [RPCRT4.@]
3411  */
3412 unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3413                                 PFORMAT_STRING pFormat)
3414 {
3415     const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3416     unsigned long total_size;
3417
3418     TRACE("(%p, %p)\n", pStubMsg, pFormat);
3419
3420     if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3421         (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3422     {
3423         ERR("invalid format type %x\n", pSmFArrayFormat->type);
3424         RpcRaiseException(RPC_S_INTERNAL_ERROR);
3425         return 0;
3426     }
3427
3428     ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
3429
3430     if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3431     {
3432         total_size = pSmFArrayFormat->total_size;
3433         pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3434     }
3435     else
3436     {
3437         const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3438         total_size = pLgFArrayFormat->total_size;
3439         pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3440     }
3441     pStubMsg->Buffer += total_size;
3442     pStubMsg->MemorySize += total_size;
3443
3444     EmbeddedPointerMemorySize(pStubMsg, pFormat);
3445
3446     return total_size;
3447 }
3448
3449 /***********************************************************************
3450  *           NdrFixedArrayFree [RPCRT4.@]
3451  */
3452 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3453                                 unsigned char *pMemory,
3454                                 PFORMAT_STRING pFormat)
3455 {
3456     const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
3457
3458     TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3459
3460     if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
3461         (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
3462     {
3463         ERR("invalid format type %x\n", pSmFArrayFormat->type);
3464         RpcRaiseException(RPC_S_INTERNAL_ERROR);
3465         return;
3466     }
3467
3468     if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
3469         pFormat = (unsigned char *)(pSmFArrayFormat + 1);
3470     else
3471     {
3472         const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
3473         pFormat = (unsigned char *)(pLgFArrayFormat + 1);
3474     }
3475
3476     EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3477 }
3478
3479 /***********************************************************************
3480  *           NdrVaryingArrayMarshall [RPCRT4.@]
3481  */
3482 unsigned char *  WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3483                                 unsigned char *pMemory,
3484                                 PFORMAT_STRING pFormat)
3485 {
3486     FIXME("stub\n");
3487     return NULL;
3488 }
3489
3490 /***********************************************************************
3491  *           NdrVaryingArrayUnmarshall [RPCRT4.@]
3492  */
3493 unsigned char *  WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3494                                 unsigned char **ppMemory,
3495                                 PFORMAT_STRING pFormat,
3496                                 unsigned char fMustAlloc)
3497 {
3498     FIXME("stub\n");
3499     return NULL;
3500 }
3501
3502 /***********************************************************************
3503  *           NdrVaryingArrayBufferSize [RPCRT4.@]
3504  */
3505 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3506                                 unsigned char *pMemory,
3507                                 PFORMAT_STRING pFormat)
3508 {
3509     FIXME("stub\n");
3510 }
3511
3512 /***********************************************************************
3513  *           NdrVaryingArrayMemorySize [RPCRT4.@]
3514  */
3515 unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3516                                 PFORMAT_STRING pFormat)
3517 {
3518     FIXME("stub\n");
3519     return 0;
3520 }
3521
3522 /***********************************************************************
3523  *           NdrVaryingArrayFree [RPCRT4.@]
3524  */
3525 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3526                                 unsigned char *pMemory,
3527                                 PFORMAT_STRING pFormat)
3528 {
3529     FIXME("stub\n");
3530 }
3531
3532 /***********************************************************************
3533  *           NdrEncapsulatedUnionMarshall [RPCRT4.@]
3534  */
3535 unsigned char *  WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3536                                 unsigned char *pMemory,
3537                                 PFORMAT_STRING pFormat)
3538 {
3539     FIXME("stub\n");
3540     return NULL;
3541 }
3542
3543 /***********************************************************************
3544  *           NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
3545  */
3546 unsigned char *  WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3547                                 unsigned char **ppMemory,
3548                                 PFORMAT_STRING pFormat,
3549                                 unsigned char fMustAlloc)
3550 {
3551     FIXME("stub\n");
3552     return NULL;
3553 }
3554
3555 /***********************************************************************
3556  *           NdrEncapsulatedUnionBufferSize [RPCRT4.@]
3557  */
3558 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3559                                 unsigned char *pMemory,
3560                                 PFORMAT_STRING pFormat)
3561 {
3562     FIXME("stub\n");
3563 }
3564
3565 /***********************************************************************
3566  *           NdrEncapsulatedUnionMemorySize [RPCRT4.@]
3567  */
3568 unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3569                                 PFORMAT_STRING pFormat)
3570 {
3571     FIXME("stub\n");
3572     return 0;
3573 }
3574
3575 /***********************************************************************
3576  *           NdrEncapsulatedUnionFree [RPCRT4.@]
3577  */
3578 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
3579                                 unsigned char *pMemory,
3580                                 PFORMAT_STRING pFormat)
3581 {
3582     FIXME("stub\n");
3583 }
3584
3585 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
3586                                                              unsigned long discriminant,
3587                                                              PFORMAT_STRING pFormat)
3588 {
3589     unsigned short num_arms, arm, type;
3590
3591     num_arms = *(const SHORT*)pFormat & 0x0fff;
3592     pFormat += 2;
3593     for(arm = 0; arm < num_arms; arm++)
3594     {
3595         if(discriminant == *(const ULONG*)pFormat)
3596         {
3597             pFormat += 4;
3598             break;
3599         }
3600         pFormat += 6;
3601     }
3602
3603     type = *(const unsigned short*)pFormat;
3604     TRACE("type %04x\n", type);
3605     if(arm == num_arms) /* default arm extras */
3606     {
3607         if(type == 0xffff)
3608         {
3609             ERR("no arm for 0x%lx and no default case\n", discriminant);
3610             RpcRaiseException(RPC_S_INVALID_TAG);
3611             return NULL;
3612         }
3613         if(type == 0)
3614         {
3615             TRACE("falling back to empty default case for 0x%lx\n", discriminant);
3616             return NULL;
3617         }
3618     }
3619     return pFormat;
3620 }
3621
3622 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
3623                                                      ULONG value,
3624                                                      PFORMAT_STRING pFormat)
3625 {
3626     pFormat += *(const SHORT*)pFormat;
3627     pFormat += 2;
3628
3629     return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
3630 }
3631
3632 /***********************************************************************
3633  *           NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
3634  */
3635 unsigned char *  WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3636                                 unsigned char *pMemory,
3637                                 PFORMAT_STRING pFormat)
3638 {
3639     unsigned short type;
3640     unsigned char switch_type;
3641
3642     TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3643     pFormat++;
3644
3645     switch_type = *pFormat;
3646     pFormat++;
3647
3648     pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
3649     TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
3650     /* Marshall discriminant */
3651     NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
3652
3653     pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
3654     if(!pFormat)
3655         return NULL;
3656
3657     type = *(const unsigned short*)pFormat;
3658     if((type & 0xff00) == 0x8000)
3659     {
3660         unsigned char basetype = LOBYTE(type);
3661         return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
3662     }
3663     else
3664     {
3665         PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3666         NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
3667         if (m)
3668         {
3669             unsigned char *saved_buffer = NULL;
3670             switch(*desc)
3671             {
3672             case RPC_FC_RP:
3673             case RPC_FC_UP:
3674             case RPC_FC_OP:
3675             case RPC_FC_FP:
3676                 saved_buffer = pStubMsg->Buffer;
3677                 pStubMsg->Buffer += 4; /* for pointer ID */
3678                 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
3679                 break;
3680             default:
3681                 m(pStubMsg, pMemory, desc);
3682             }
3683         }
3684         else FIXME("no marshaller for embedded type %02x\n", *desc);
3685     }
3686     return NULL;
3687 }
3688
3689 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
3690                                     PFORMAT_STRING *ppFormat)
3691 {
3692     long discriminant = 0;
3693
3694     switch(**ppFormat)
3695     {
3696     case RPC_FC_BYTE:
3697     case RPC_FC_CHAR:
3698     case RPC_FC_SMALL:
3699     case RPC_FC_USMALL:
3700         discriminant = *(UCHAR *)pStubMsg->Buffer;
3701         pStubMsg->Buffer += sizeof(UCHAR);
3702         break;
3703     case RPC_FC_WCHAR:
3704     case RPC_FC_SHORT:
3705     case RPC_FC_USHORT:
3706         ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
3707         discriminant = *(USHORT *)pStubMsg->Buffer;
3708         pStubMsg->Buffer += sizeof(USHORT);
3709         break;
3710     case RPC_FC_LONG:
3711     case RPC_FC_ULONG:
3712         ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
3713         discriminant = *(ULONG *)pStubMsg->Buffer;
3714         pStubMsg->Buffer += sizeof(ULONG);
3715         break;
3716     default:
3717         FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
3718     }
3719     (*ppFormat)++;
3720
3721     if (pStubMsg->fHasNewCorrDesc)
3722         *ppFormat += 6;
3723     else
3724         *ppFormat += 4;
3725     return discriminant;
3726 }
3727
3728 /**********************************************************************
3729  *           NdrNonEncapsulatedUnionUnmarshall[RPCRT4.@]
3730  */
3731 unsigned char *  WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3732                                 unsigned char **ppMemory,
3733                                 PFORMAT_STRING pFormat,
3734                                 unsigned char fMustAlloc)
3735 {
3736     long discriminant;
3737     unsigned short type, size;
3738
3739     TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3740     pFormat++;
3741
3742     /* Unmarshall discriminant */
3743     discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
3744     TRACE("unmarshalled discriminant %lx\n", discriminant);
3745
3746     pFormat += *(const SHORT*)pFormat;
3747
3748     size = *(const unsigned short*)pFormat;
3749     pFormat += 2;
3750
3751     pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
3752     if(!pFormat)
3753         return NULL;
3754
3755     if(!*ppMemory || fMustAlloc)
3756         *ppMemory = NdrAllocate(pStubMsg, size);
3757
3758     type = *(const unsigned short*)pFormat;
3759     if((type & 0xff00) == 0x8000)
3760     {
3761         unsigned char basetype = LOBYTE(type);
3762         return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
3763     }
3764     else
3765     {
3766         PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3767         NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3768         if (m)
3769         {
3770             unsigned char *saved_buffer = NULL;
3771             switch(*desc)
3772             {
3773             case RPC_FC_RP:
3774             case RPC_FC_UP:
3775             case RPC_FC_OP:
3776             case RPC_FC_FP:
3777                 ALIGN_POINTER(pStubMsg->Buffer, 4);
3778                 saved_buffer = pStubMsg->Buffer;
3779                 pStubMsg->Buffer += 4; /* for pointer ID */
3780                 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, TRUE);
3781                 break;
3782             default:
3783                 m(pStubMsg, ppMemory, desc, fMustAlloc);
3784             }
3785         }
3786         else FIXME("no marshaller for embedded type %02x\n", *desc);
3787     }
3788     return NULL;
3789 }
3790
3791 /***********************************************************************
3792  *           NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
3793  */
3794 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3795                                 unsigned char *pMemory,
3796                                 PFORMAT_STRING pFormat)
3797 {
3798     unsigned short type;
3799     unsigned char switch_type;
3800
3801     TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3802     pFormat++;
3803
3804     switch_type = *pFormat;
3805     pFormat++;
3806
3807     pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
3808     TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
3809     /* Add discriminant size */
3810     NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
3811
3812     pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
3813     if(!pFormat)
3814         return;
3815
3816     type = *(const unsigned short*)pFormat;
3817     if((type & 0xff00) == 0x8000)
3818     {
3819         unsigned char basetype = LOBYTE(type);
3820         NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
3821     }
3822     else
3823     {
3824         PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3825         NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3826         if (m)
3827         {
3828             switch(*desc)
3829             {
3830             case RPC_FC_RP:
3831             case RPC_FC_UP:
3832             case RPC_FC_OP:
3833             case RPC_FC_FP:
3834                 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3835                 pStubMsg->BufferLength += 4; /* for pointer ID */
3836                 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
3837                 break;
3838             default:
3839                 m(pStubMsg, pMemory, desc);
3840             }
3841         }
3842         else FIXME("no buffersizer for embedded type %02x\n", *desc);
3843     }
3844     return;
3845 }
3846
3847 /***********************************************************************
3848  *           NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
3849  */
3850 unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3851                                 PFORMAT_STRING pFormat)
3852 {
3853     unsigned long discriminant;
3854     unsigned short type, size;
3855
3856     pFormat++;
3857     /* Unmarshall discriminant */
3858     discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
3859     TRACE("unmarshalled discriminant 0x%lx\n", discriminant);
3860
3861     pFormat += *(const SHORT*)pFormat;
3862
3863     size = *(const unsigned short*)pFormat;
3864     pFormat += 2;
3865
3866     pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
3867     if(!pFormat)
3868         return 0;
3869
3870     pStubMsg->Memory += size;
3871
3872     type = *(const unsigned short*)pFormat;
3873     if((type & 0xff00) == 0x8000)
3874     {
3875         return NdrBaseTypeMemorySize(pStubMsg, pFormat);
3876     }
3877     else
3878     {
3879         PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3880         NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
3881         unsigned char *saved_buffer;
3882         if (m)
3883         {
3884             switch(*desc)
3885             {
3886             case RPC_FC_RP:
3887             case RPC_FC_UP:
3888             case RPC_FC_OP:
3889             case RPC_FC_FP:
3890                 ALIGN_POINTER(pStubMsg->Buffer, 4);
3891                 saved_buffer = pStubMsg->Buffer;
3892                 pStubMsg->Buffer += 4;
3893                 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
3894                 pStubMsg->MemorySize += 4;
3895                 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
3896                 break;
3897             default:
3898                 return m(pStubMsg, desc);
3899             }
3900         }
3901         else FIXME("no marshaller for embedded type %02x\n", *desc);
3902     }
3903
3904     TRACE("size %d\n", size);
3905     return size;
3906 }
3907
3908 /***********************************************************************
3909  *           NdrNonEncapsulatedUnionFree [RPCRT4.@]
3910  */
3911 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
3912                                 unsigned char *pMemory,
3913                                 PFORMAT_STRING pFormat)
3914 {
3915     FIXME("stub\n");
3916 }
3917
3918 /***********************************************************************
3919  *           NdrByteCountPointerMarshall [RPCRT4.@]
3920  */
3921 unsigned char *  WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3922                                 unsigned char *pMemory,
3923                                 PFORMAT_STRING pFormat)
3924 {
3925     FIXME("stub\n");
3926     return NULL;
3927 }
3928
3929 /***********************************************************************
3930  *           NdrByteCountPointerUnmarshall [RPCRT4.@]
3931  */
3932 unsigned char *  WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3933                                 unsigned char **ppMemory,
3934                                 PFORMAT_STRING pFormat,
3935                                 unsigned char fMustAlloc)
3936 {
3937     FIXME("stub\n");
3938     return NULL;
3939 }
3940
3941 /***********************************************************************
3942  *           NdrByteCountPointerBufferSize [RPCRT4.@]
3943  */
3944 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3945                                 unsigned char *pMemory,
3946                                 PFORMAT_STRING pFormat)
3947 {
3948     FIXME("stub\n");
3949 }
3950
3951 /***********************************************************************
3952  *           NdrByteCountPointerMemorySize [RPCRT4.@]
3953  */
3954 unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3955                                 PFORMAT_STRING pFormat)
3956 {
3957     FIXME("stub\n");
3958     return 0;
3959 }
3960
3961 /***********************************************************************
3962  *           NdrByteCountPointerFree [RPCRT4.@]
3963  */
3964 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
3965                                 unsigned char *pMemory,
3966                                 PFORMAT_STRING pFormat)
3967 {
3968     FIXME("stub\n");
3969 }
3970
3971 /***********************************************************************
3972  *           NdrXmitOrRepAsMarshall [RPCRT4.@]
3973  */
3974 unsigned char *  WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3975                                 unsigned char *pMemory,
3976                                 PFORMAT_STRING pFormat)
3977 {
3978     FIXME("stub\n");
3979     return NULL;
3980 }
3981
3982 /***********************************************************************
3983  *           NdrXmitOrRepAsUnmarshall [RPCRT4.@]
3984  */
3985 unsigned char *  WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3986                                 unsigned char **ppMemory,
3987                                 PFORMAT_STRING pFormat,
3988                                 unsigned char fMustAlloc)
3989 {
3990     FIXME("stub\n");
3991     return NULL;
3992 }
3993
3994 /***********************************************************************
3995  *           NdrXmitOrRepAsBufferSize [RPCRT4.@]
3996  */
3997 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3998                                 unsigned char *pMemory,
3999                                 PFORMAT_STRING pFormat)
4000 {
4001     FIXME("stub\n");
4002 }
4003
4004 /***********************************************************************
4005  *           NdrXmitOrRepAsMemorySize [RPCRT4.@]
4006  */
4007 unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4008                                 PFORMAT_STRING pFormat)
4009 {
4010     FIXME("stub\n");
4011     return 0;
4012 }
4013
4014 /***********************************************************************
4015  *           NdrXmitOrRepAsFree [RPCRT4.@]
4016  */
4017 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
4018                                 unsigned char *pMemory,
4019                                 PFORMAT_STRING pFormat)
4020 {
4021     FIXME("stub\n");
4022 }
4023
4024 /***********************************************************************
4025  *           NdrBaseTypeMarshall [internal]
4026  */
4027 static unsigned char *WINAPI NdrBaseTypeMarshall(
4028     PMIDL_STUB_MESSAGE pStubMsg,
4029     unsigned char *pMemory,
4030     PFORMAT_STRING pFormat)
4031 {
4032     TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4033
4034     switch(*pFormat)
4035     {
4036     case RPC_FC_BYTE:
4037     case RPC_FC_CHAR:
4038     case RPC_FC_SMALL:
4039     case RPC_FC_USMALL:
4040         *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
4041         pStubMsg->Buffer += sizeof(UCHAR);
4042         TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
4043         break;
4044     case RPC_FC_WCHAR:
4045     case RPC_FC_SHORT:
4046     case RPC_FC_USHORT:
4047         ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4048         *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
4049         pStubMsg->Buffer += sizeof(USHORT);
4050         TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
4051         break;
4052     case RPC_FC_LONG:
4053     case RPC_FC_ULONG:
4054     case RPC_FC_ERROR_STATUS_T:
4055     case RPC_FC_ENUM32:
4056         ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
4057         *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
4058         pStubMsg->Buffer += sizeof(ULONG);
4059         TRACE("value: 0x%08lx\n", *(ULONG *)pMemory);
4060         break;
4061     case RPC_FC_FLOAT:
4062         ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
4063         *(float *)pStubMsg->Buffer = *(float *)pMemory;
4064         pStubMsg->Buffer += sizeof(float);
4065         break;
4066     case RPC_FC_DOUBLE:
4067         ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
4068         *(double *)pStubMsg->Buffer = *(double *)pMemory;
4069         pStubMsg->Buffer += sizeof(double);
4070         break;
4071     case RPC_FC_HYPER:
4072         ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
4073         *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
4074         pStubMsg->Buffer += sizeof(ULONGLONG);
4075         TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
4076         break;
4077     case RPC_FC_ENUM16:
4078         /* only 16-bits on the wire, so do a sanity check */
4079         if (*(UINT *)pMemory > USHRT_MAX)
4080             RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
4081         ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4082         *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
4083         pStubMsg->Buffer += sizeof(USHORT);
4084         TRACE("value: 0x%04x\n", *(UINT *)pMemory);
4085         break;
4086     default:
4087         FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4088     }
4089
4090     STD_OVERFLOW_CHECK(pStubMsg);
4091
4092     /* FIXME: what is the correct return value? */
4093     return NULL;
4094 }
4095
4096 /***********************************************************************
4097  *           NdrBaseTypeUnmarshall [internal]
4098  */
4099 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
4100     PMIDL_STUB_MESSAGE pStubMsg,
4101     unsigned char **ppMemory,
4102     PFORMAT_STRING pFormat,
4103     unsigned char fMustAlloc)
4104 {
4105     TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
4106
4107     if (fMustAlloc || !*ppMemory)
4108     {
4109         unsigned char *Buffer = pStubMsg->Buffer;
4110         unsigned long MemorySize = pStubMsg->MemorySize;
4111         *ppMemory = NdrAllocate(pStubMsg, NdrBaseTypeMemorySize(pStubMsg, pFormat));
4112         pStubMsg->MemorySize = MemorySize;
4113         pStubMsg->Buffer = Buffer;
4114     }
4115
4116     TRACE("*ppMemory: %p\n", *ppMemory);
4117
4118 #define BASE_TYPE_UNMARSHALL(type) \
4119         ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4120         **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4121         pStubMsg->Buffer += sizeof(type);
4122
4123     switch(*pFormat)
4124     {
4125     case RPC_FC_BYTE:
4126     case RPC_FC_CHAR:
4127     case RPC_FC_SMALL:
4128     case RPC_FC_USMALL:
4129         BASE_TYPE_UNMARSHALL(UCHAR);
4130         TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
4131         break;
4132     case RPC_FC_WCHAR:
4133     case RPC_FC_SHORT:
4134     case RPC_FC_USHORT:
4135         BASE_TYPE_UNMARSHALL(USHORT);
4136         TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
4137         break;
4138     case RPC_FC_LONG:
4139     case RPC_FC_ULONG:
4140     case RPC_FC_ERROR_STATUS_T:
4141     case RPC_FC_ENUM32:
4142         BASE_TYPE_UNMARSHALL(ULONG);
4143         TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory);
4144         break;
4145    case RPC_FC_FLOAT:
4146         BASE_TYPE_UNMARSHALL(float);
4147         TRACE("value: %f\n", **(float **)ppMemory);
4148         break;
4149     case RPC_FC_DOUBLE:
4150         BASE_TYPE_UNMARSHALL(double);
4151         TRACE("value: %f\n", **(double **)ppMemory);
4152         break;
4153     case RPC_FC_HYPER:
4154         BASE_TYPE_UNMARSHALL(ULONGLONG);
4155         TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
4156         break;
4157     case RPC_FC_ENUM16:
4158         ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
4159         /* 16-bits on the wire, but int in memory */
4160         **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
4161         pStubMsg->Buffer += sizeof(USHORT);
4162         TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
4163         break;
4164     default:
4165         FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4166     }
4167 #undef BASE_TYPE_UNMARSHALL
4168
4169     /* FIXME: what is the correct return value? */
4170
4171     return NULL;
4172 }
4173
4174 /***********************************************************************
4175  *           NdrBaseTypeBufferSize [internal]
4176  */
4177 static void WINAPI NdrBaseTypeBufferSize(
4178     PMIDL_STUB_MESSAGE pStubMsg,
4179     unsigned char *pMemory,
4180     PFORMAT_STRING pFormat)
4181 {
4182     TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4183
4184     switch(*pFormat)
4185     {
4186     case RPC_FC_BYTE:
4187     case RPC_FC_CHAR:
4188     case RPC_FC_SMALL:
4189     case RPC_FC_USMALL:
4190         pStubMsg->BufferLength += sizeof(UCHAR);
4191         break;
4192     case RPC_FC_WCHAR:
4193     case RPC_FC_SHORT:
4194     case RPC_FC_USHORT:
4195     case RPC_FC_ENUM16:
4196         ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
4197         pStubMsg->BufferLength += sizeof(USHORT);
4198         break;
4199     case RPC_FC_LONG:
4200     case RPC_FC_ULONG:
4201     case RPC_FC_ENUM32:
4202         ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
4203         pStubMsg->BufferLength += sizeof(ULONG);
4204         break;
4205     case RPC_FC_FLOAT:
4206         ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
4207         pStubMsg->BufferLength += sizeof(float);
4208         break;
4209     case RPC_FC_DOUBLE:
4210         ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
4211         pStubMsg->BufferLength += sizeof(double);
4212         break;
4213     case RPC_FC_HYPER:
4214         ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
4215         pStubMsg->BufferLength += sizeof(ULONGLONG);
4216         break;
4217     case RPC_FC_ERROR_STATUS_T:
4218         ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
4219         pStubMsg->BufferLength += sizeof(error_status_t);
4220         break;
4221     default:
4222         FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4223     }
4224 }
4225
4226 /***********************************************************************
4227  *           NdrBaseTypeMemorySize [internal]
4228  */
4229 static unsigned long WINAPI NdrBaseTypeMemorySize(
4230     PMIDL_STUB_MESSAGE pStubMsg,
4231     PFORMAT_STRING pFormat)
4232 {
4233     switch(*pFormat)
4234     {
4235     case RPC_FC_BYTE:
4236     case RPC_FC_CHAR:
4237     case RPC_FC_SMALL:
4238     case RPC_FC_USMALL:
4239         pStubMsg->Buffer += sizeof(UCHAR);
4240         pStubMsg->MemorySize += sizeof(UCHAR);
4241         return sizeof(UCHAR);
4242     case RPC_FC_WCHAR:
4243     case RPC_FC_SHORT:
4244     case RPC_FC_USHORT:
4245         pStubMsg->Buffer += sizeof(USHORT);
4246         pStubMsg->MemorySize += sizeof(USHORT);
4247         return sizeof(USHORT);
4248     case RPC_FC_LONG:
4249     case RPC_FC_ULONG:
4250         pStubMsg->Buffer += sizeof(ULONG);
4251         pStubMsg->MemorySize += sizeof(ULONG);
4252         return sizeof(ULONG);
4253     case RPC_FC_FLOAT:
4254         pStubMsg->Buffer += sizeof(float);
4255         pStubMsg->MemorySize += sizeof(float);
4256         return sizeof(float);
4257     case RPC_FC_DOUBLE:
4258         pStubMsg->Buffer += sizeof(double);
4259         pStubMsg->MemorySize += sizeof(double);
4260         return sizeof(double);
4261     case RPC_FC_HYPER:
4262         pStubMsg->Buffer += sizeof(ULONGLONG);
4263         pStubMsg->MemorySize += sizeof(ULONGLONG);
4264         return sizeof(ULONGLONG);
4265     case RPC_FC_ERROR_STATUS_T:
4266         pStubMsg->Buffer += sizeof(error_status_t);
4267         pStubMsg->MemorySize += sizeof(error_status_t);
4268         return sizeof(error_status_t);
4269     case RPC_FC_ENUM16:
4270     case RPC_FC_ENUM32:
4271         pStubMsg->Buffer += sizeof(INT);
4272         pStubMsg->MemorySize += sizeof(INT);
4273         return sizeof(INT);
4274     default:
4275         FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4276        return 0;
4277     }
4278 }
4279
4280 /***********************************************************************
4281  *           NdrBaseTypeFree [internal]
4282  */
4283 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4284                                 unsigned char *pMemory,
4285                                 PFORMAT_STRING pFormat)
4286 {
4287    TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4288
4289    /* nothing to do */
4290 }
4291
4292 /***********************************************************************
4293  *           NdrClientContextMarshall
4294  */
4295 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4296                                      NDR_CCONTEXT ContextHandle,
4297                                      int fCheck)
4298 {
4299     FIXME("(%p, %p, %d): stub\n", pStubMsg, ContextHandle, fCheck);
4300 }
4301
4302 /***********************************************************************
4303  *           NdrClientContextUnmarshall
4304  */
4305 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4306                                        NDR_CCONTEXT * pContextHandle,
4307                                        RPC_BINDING_HANDLE BindHandle)
4308 {
4309     FIXME("(%p, %p, %p): stub\n", pStubMsg, pContextHandle, BindHandle);
4310 }
4311
4312 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4313                                      NDR_SCONTEXT ContextHandle,
4314                                      NDR_RUNDOWN RundownRoutine )
4315 {
4316     FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4317 }
4318
4319 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4320 {
4321     FIXME("(%p): stub\n", pStubMsg);
4322     return NULL;
4323 }
4324
4325 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4326                                  unsigned char* pMemory,
4327                                  PFORMAT_STRING pFormat)
4328 {
4329     FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
4330 }
4331
4332 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
4333                                                PFORMAT_STRING pFormat)
4334 {
4335     FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4336     return NULL;
4337 }
4338
4339 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4340                                         NDR_SCONTEXT ContextHandle,
4341                                         NDR_RUNDOWN RundownRoutine,
4342                                         PFORMAT_STRING pFormat)
4343 {
4344     FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
4345 }
4346
4347 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4348                                                   PFORMAT_STRING pFormat)
4349 {
4350     FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4351     return NULL;
4352 }
4353
4354 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
4355 {
4356     FIXME("(%p): stub\n", CContext);
4357     return NULL;
4358 }
4359
4360 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
4361 {
4362     FIXME("(%p %p): stub\n", CContext, pBuff);
4363 }
4364
4365 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
4366                                   RPC_BINDING_HANDLE hBinding,
4367                                   void *pBuff,
4368                                   unsigned long DataRepresentation)
4369 {
4370     FIXME("(%p %p %p %08lx): stub\n", CContext, hBinding, pBuff, DataRepresentation);
4371 }
4372
4373 void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext,
4374                                void *pBuff,
4375                                NDR_RUNDOWN userRunDownIn)
4376 {
4377     FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn);
4378 }
4379
4380 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
4381                                   NDR_SCONTEXT CContext,
4382                                   void *pBuff,
4383                                   NDR_RUNDOWN userRunDownIn)
4384 {
4385     FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn);
4386 }
4387
4388 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
4389                                  NDR_SCONTEXT CContext,
4390                                  void *pBuff,
4391                                  NDR_RUNDOWN userRunDownIn,
4392                                  void *CtxGuard,
4393                                  unsigned long Flags)
4394 {
4395     FIXME("(%p %p %p %p %p %lu): stub\n",
4396           hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags);
4397 }
4398
4399 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
4400                                           unsigned long DataRepresentation)
4401 {
4402     FIXME("(%p %08lx): stub\n", pBuff, DataRepresentation);
4403     return NULL;
4404 }
4405
4406 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
4407                                             void *pBuff,
4408                                             unsigned long DataRepresentation)
4409 {
4410     FIXME("(%p %p %08lx): stub\n", hBinding, pBuff, DataRepresentation);
4411     return NULL;
4412 }
4413
4414 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
4415                                            void *pBuff,
4416                                            unsigned long DataRepresentation,
4417                                            void *CtxGuard,
4418                                            unsigned long Flags)
4419 {
4420     FIXME("(%p %p %08lx %p %lu): stub\n",
4421           hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
4422     return NULL;
4423 }