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