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