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