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