Add stubs for most of the NDR marshaling functions.
[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 - _Msg->BufferStart, _Msg->BufferLength); \
101     if (_Msg->Buffer > _Msg->BufferEnd) ERR("buffer overflow %d bytes\n", _Msg->Buffer - _Msg->BufferEnd); \
102   } while (0)
103
104 #define NDR_TABLE_SIZE 128
105 #define NDR_TABLE_MASK 127
106
107 NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
108   0, 0, 0, 0, 0, 0, 0, 0,
109   0, 0, 0, 0, 0, 0, 0, 0,
110   /* 0x10 */
111   0,
112   /* 0x11 */
113   NdrPointerMarshall, NdrPointerMarshall,
114   NdrPointerMarshall, NdrPointerMarshall,
115   /* 0x15 */
116   NdrSimpleStructMarshall, NdrSimpleStructMarshall,
117   NdrConformantStructMarshall, NdrConformantStructMarshall,
118   NdrConformantVaryingStructMarshall,
119   NdrComplexStructMarshall,
120   /* 0x1b */
121   NdrConformantArrayMarshall, 
122   NdrConformantVaryingArrayMarshall,
123   NdrFixedArrayMarshall, NdrFixedArrayMarshall,
124   NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
125   NdrComplexArrayMarshall,
126   /* 0x22 */
127   NdrConformantStringMarshall, 0, 0,
128   NdrConformantStringMarshall, 0, 0, 0, 0,
129   /* 0x2a */
130   NdrEncapsulatedUnionMarshall,
131   NdrNonEncapsulatedUnionMarshall,
132   0,
133   NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
134   /* 0x2f */
135   NdrInterfacePointerMarshall,
136   /* 0xb0 */
137   0, 0, 0, 0,
138   NdrUserMarshalMarshall
139 };
140 NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
141   0, 0, 0, 0, 0, 0, 0, 0,
142   0, 0, 0, 0, 0, 0, 0, 0,
143   /* 0x10 */
144   0,
145   /* 0x11 */
146   NdrPointerUnmarshall, NdrPointerUnmarshall,
147   NdrPointerUnmarshall, NdrPointerUnmarshall,
148   /* 0x15 */
149   NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
150   NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
151   NdrConformantVaryingStructUnmarshall,
152   NdrComplexStructUnmarshall,
153   /* 0x1b */
154   NdrConformantArrayUnmarshall, 
155   NdrConformantVaryingArrayUnmarshall,
156   NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
157   NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
158   NdrComplexArrayUnmarshall,
159   /* 0x22 */
160   NdrConformantStringUnmarshall, 0, 0,
161   NdrConformantStringUnmarshall, 0, 0, 0, 0,
162   /* 0x2a */
163   NdrEncapsulatedUnionUnmarshall,
164   NdrNonEncapsulatedUnionUnmarshall,
165   0,
166   NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
167   /* 0x2f */
168   NdrInterfacePointerUnmarshall,
169   /* 0xb0 */
170   0, 0, 0, 0,
171   NdrUserMarshalUnmarshall
172 };
173 NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
174   0, 0, 0, 0, 0, 0, 0, 0,
175   0, 0, 0, 0, 0, 0, 0, 0,
176   /* 0x10 */
177   0,
178   /* 0x11 */
179   NdrPointerBufferSize, NdrPointerBufferSize,
180   NdrPointerBufferSize, NdrPointerBufferSize,
181   /* 0x15 */
182   NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
183   NdrConformantStructBufferSize, NdrConformantStructBufferSize,
184   NdrConformantVaryingStructBufferSize,
185   NdrComplexStructBufferSize,
186   /* 0x1b */
187   NdrConformantArrayBufferSize, 
188   NdrConformantVaryingArrayBufferSize,
189   NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
190   NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
191   NdrComplexArrayBufferSize,
192   /* 0x22 */
193   NdrConformantStringBufferSize, 0, 0,
194   NdrConformantStringBufferSize, 0, 0, 0, 0,
195   /* 0x2a */
196   NdrEncapsulatedUnionBufferSize,
197   NdrNonEncapsulatedUnionBufferSize,
198   0,
199   NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
200   /* 0x2f */
201   NdrInterfacePointerBufferSize,
202   /* 0xb0 */
203   0, 0, 0, 0,
204   NdrUserMarshalBufferSize
205 };
206 NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
207   0, 0, 0, 0, 0, 0, 0, 0,
208   0, 0, 0, 0, 0, 0, 0, 0,
209   /* 0x10 */
210   0,
211   /* 0x11 */
212   NdrPointerMemorySize, NdrPointerMemorySize,
213   NdrPointerMemorySize, NdrPointerMemorySize,
214   /* 0x15 */
215   NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
216   0, 0, 0,
217   NdrComplexStructMemorySize,
218   /* 0x1b */
219   NdrConformantArrayMemorySize, 0, 0, 0, 0, 0,
220   NdrComplexArrayMemorySize,
221   /* 0x22 */
222   NdrConformantStringMemorySize, 0, 0,
223   NdrConformantStringMemorySize, 0, 0, 0, 0,
224   /* 0x2a */
225   0, 0, 0, 0, 0,
226   /* 0x2f */
227   NdrInterfacePointerMemorySize,
228   /* 0xb0 */
229   0, 0, 0, 0,
230   NdrUserMarshalMemorySize
231 };
232 NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
233   0, 0, 0, 0, 0, 0, 0, 0,
234   0, 0, 0, 0, 0, 0, 0, 0,
235   /* 0x10 */
236   0,
237   /* 0x11 */
238   NdrPointerFree, NdrPointerFree,
239   NdrPointerFree, NdrPointerFree,
240   /* 0x15 */
241   NdrSimpleStructFree, NdrSimpleStructFree,
242   NdrConformantStructFree, NdrConformantStructFree,
243   NdrConformantVaryingStructFree,
244   NdrComplexStructFree,
245   /* 0x1b */
246   NdrConformantArrayFree, 
247   NdrConformantVaryingArrayFree,
248   NdrFixedArrayFree, NdrFixedArrayFree,
249   NdrVaryingArrayFree, NdrVaryingArrayFree,
250   NdrComplexArrayFree,
251   /* 0x22 */
252   0, 0, 0,
253   0, 0, 0, 0, 0,
254   /* 0x2a */
255   NdrEncapsulatedUnionFree,
256   NdrNonEncapsulatedUnionFree,
257   0,
258   NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
259   /* 0x2f */
260   NdrInterfacePointerFree,
261   /* 0xb0 */
262   0, 0, 0, 0,
263   NdrUserMarshalFree
264 };
265
266 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
267 {
268   /* hmm, this is probably supposed to do more? */
269   return pStubMsg->pfnAllocate(len);
270 }
271
272 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
273 {
274   pStubMsg->pfnFree(Pointer);
275 }
276
277 PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
278 {
279   pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
280   pStubMsg->Buffer += 4;
281   TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
282   return pFormat+4;
283 }
284
285 PFORMAT_STRING ComputeConformance(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
286                                   PFORMAT_STRING pFormat, ULONG_PTR def)
287 {
288   BYTE dtype = pFormat[0] & 0xf;
289   DWORD ofs = (DWORD)pFormat[2] | ((DWORD)pFormat[3] << 8);
290   LPVOID ptr = NULL;
291   DWORD data = 0;
292
293   if (pFormat[0] == 0xff) {
294     /* null descriptor */
295     pStubMsg->MaxCount = def;
296     goto finish_conf;
297   }
298
299   switch (pFormat[0] & 0xf0) {
300   case RPC_FC_NORMAL_CONFORMANCE:
301     TRACE("normal conformance, ofs=%ld\n", ofs);
302     ptr = pMemory + ofs;
303     break;
304   case RPC_FC_POINTER_CONFORMANCE:
305     TRACE("pointer conformance, ofs=%ld\n", ofs);
306     ptr = pStubMsg->Memory + ofs;
307     break;
308   case RPC_FC_TOP_LEVEL_CONFORMANCE:
309     TRACE("toplevel conformance, ofs=%ld\n", ofs);
310     if (pStubMsg->StackTop) {
311       ptr = pStubMsg->StackTop + ofs;
312     }
313     else {
314       /* -Os mode, MaxCount is already set */
315       goto finish_conf;
316     }
317     break;
318   case RPC_FC_CONSTANT_CONFORMANCE:
319     data = ofs | ((DWORD)pFormat[1] << 16);
320     TRACE("constant conformance, val=%ld\n", data);
321     pStubMsg->MaxCount = data;
322     goto finish_conf;
323   case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
324     FIXME("toplevel multidimensional conformance, ofs=%ld\n", ofs);
325     if (pStubMsg->StackTop) {
326       ptr = pStubMsg->StackTop + ofs;
327     }
328     else {
329       /* ? */
330       goto done_conf_grab;
331     }
332     break;
333   default:
334     FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
335   }
336
337   switch (pFormat[1]) {
338   case RPC_FC_DEREFERENCE:
339     ptr = *(LPVOID*)ptr;
340     break;
341   case RPC_FC_CALLBACK:
342     /* ofs is index into StubDesc->apfnExprEval */
343     FIXME("handle callback\n");
344     goto finish_conf;
345   default:
346     break;
347   }
348
349   switch (dtype) {
350   case RPC_FC_LONG:
351   case RPC_FC_ULONG:
352     data = *(DWORD*)ptr;
353     break;
354   case RPC_FC_SHORT:
355     data = *(SHORT*)ptr;
356     break;
357   case RPC_FC_USHORT:
358     data = *(USHORT*)ptr;
359     break;
360   case RPC_FC_SMALL:
361     data = *(CHAR*)ptr;
362     break;
363   case RPC_FC_USMALL:
364     data = *(UCHAR*)ptr;
365     break;
366   default:
367     FIXME("unknown conformance data type %x\n", dtype);
368     goto done_conf_grab;
369   }
370   TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
371
372 done_conf_grab:
373   switch (pFormat[1]) {
374   case 0: /* no op */
375     pStubMsg->MaxCount = data;
376     break;
377   case RPC_FC_DEREFERENCE:
378     /* already handled */
379     break;
380   default:
381     FIXME("unknown conformance op %d\n", pFormat[1]);
382     goto finish_conf;
383   }
384
385 finish_conf:
386   TRACE("resulting conformance is %ld\n", pStubMsg->MaxCount);
387   return pFormat+4;
388 }
389
390
391 /*
392  * NdrConformantString:
393  * 
394  * What MS calls a ConformantString is, in DCE terminology,
395  * a Varying-Conformant String.
396  * [
397  *   maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
398  *   offset: DWORD (actual string data begins at (offset) CHARTYPE's
399  *           into unmarshalled string) 
400  *   length: DWORD (# of CHARTYPE characters, inclusive of '\0')
401  *   [ 
402  *     data: CHARTYPE[maxlen]
403  *   ] 
404  * ], where CHARTYPE is the appropriate character type (specified externally)
405  *
406  */
407
408 /***********************************************************************
409  *            NdrConformantStringMarshall [RPCRT4.@]
410  */
411 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
412   unsigned char *pszMessage, PFORMAT_STRING pFormat)
413
414   unsigned long len, esize;
415   unsigned char *c;
416
417   TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
418   
419   assert(pFormat);
420   if (*pFormat == RPC_FC_C_CSTRING) {
421     TRACE("string=%s\n", debugstr_a(pszMessage));
422     len = strlen(pszMessage)+1;
423     esize = 1;
424   }
425   else if (*pFormat == RPC_FC_C_WSTRING) {
426     TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
427     len = strlenW((LPWSTR)pszMessage)+1;
428     esize = 2;
429   }
430   else {
431     ERR("Unhandled string type: %#x\n", *pFormat); 
432     /* FIXME: raise an exception. */
433     return NULL;
434   }
435
436   if (pFormat[1] != RPC_FC_PAD) {
437     FIXME("sized string format=%d\n", pFormat[1]);
438   }
439
440   assert( (pStubMsg->BufferLength >= (len*esize + 13)) && (pStubMsg->Buffer != NULL) );
441
442   c = pStubMsg->Buffer;
443   memset(c, 0, 12);
444   NDR_LOCAL_UINT32_WRITE(c, len); /* max length: strlen + 1 (for '\0') */
445   c += 8;                         /* offset: 0 */
446   NDR_LOCAL_UINT32_WRITE(c, len); /* actual length: (same) */
447   c += 4;
448   memcpy(c, pszMessage, len*esize); /* the string itself */
449   c += len*esize;
450   pStubMsg->Buffer = c;
451
452   STD_OVERFLOW_CHECK(pStubMsg);
453
454   /* success */
455   return NULL; /* is this always right? */
456 }
457
458 /***********************************************************************
459  *           NdrConformantStringBufferSize [RPCRT4.@]
460  */
461 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
462   unsigned char* pMemory, PFORMAT_STRING pFormat)
463 {
464   TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
465
466   assert(pFormat);
467   if (*pFormat == RPC_FC_C_CSTRING) {
468     /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 1 octet for '\0' */
469     TRACE("string=%s\n", debugstr_a(pMemory));
470     pStubMsg->BufferLength += strlen(pMemory) + 13 + BUFFER_PARANOIA;
471   }
472   else if (*pFormat == RPC_FC_C_WSTRING) {
473     /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 2 octets for L'\0' */
474     TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
475     pStubMsg->BufferLength += strlenW((LPWSTR)pMemory)*2 + 14 + BUFFER_PARANOIA;
476   }
477   else {
478     ERR("Unhandled string type: %#x\n", *pFormat); 
479     /* FIXME: raise an exception */
480   }
481
482   if (pFormat[1] != RPC_FC_PAD) {
483     FIXME("sized string format=%d\n", pFormat[1]);
484   }
485 }
486
487 /************************************************************************
488  *            NdrConformantStringMemorySize [RPCRT4.@]
489  */
490 unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
491   PFORMAT_STRING pFormat )
492 {
493   unsigned long rslt = 0;
494
495   TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
496    
497   assert(pStubMsg && pFormat);
498
499   if (*pFormat == RPC_FC_C_CSTRING) {
500     rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
501   }
502   else if (*pFormat == RPC_FC_C_WSTRING) {
503     rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
504   }
505   else {
506     ERR("Unhandled string type: %#x\n", *pFormat);
507     /* FIXME: raise an exception */
508   }
509
510   if (pFormat[1] != RPC_FC_PAD) {
511     FIXME("sized string format=%d\n", pFormat[1]);
512   }
513
514   TRACE("  --> %lu\n", rslt);
515   return rslt;
516 }
517
518 /************************************************************************
519  *           NdrConformantStringUnmarshall [RPCRT4.@]
520  */
521 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
522   unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
523 {
524   unsigned long len, esize, ofs;
525   unsigned char *pMem;
526
527   TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
528     pStubMsg, *ppMemory, pFormat, fMustAlloc);
529
530   assert(pFormat && ppMemory && pStubMsg);
531
532   pStubMsg->Buffer += 4;
533   ofs = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
534   pStubMsg->Buffer += 4;
535   len = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
536   pStubMsg->Buffer += 4;
537
538   if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
539   else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
540   else {
541     ERR("Unhandled string type: %#x\n", *pFormat);
542     /* FIXME: raise an exception */
543     esize = 0;
544   }
545
546   if (pFormat[1] != RPC_FC_PAD) {
547     FIXME("sized string format=%d\n", pFormat[1]);
548   }
549
550   if (fMustAlloc) {
551     *ppMemory = NdrAllocate(pStubMsg, len*esize + BUFFER_PARANOIA);
552   } else {
553     if (pStubMsg->ReuseBuffer && !*ppMemory)
554       /* for servers, we may just point straight into the RPC buffer, I think
555        * (I guess that's what MS does since MIDL code doesn't try to free) */
556       *ppMemory = pStubMsg->Buffer - ofs*esize;
557     /* for clients, memory should be provided by caller */
558   }
559
560   pMem = *ppMemory + ofs*esize;
561
562   if (pMem != pStubMsg->Buffer)
563     memcpy(pMem, pStubMsg->Buffer, len*esize);
564
565   pStubMsg->Buffer += len*esize;
566
567   if (*pFormat == RPC_FC_C_CSTRING) {
568     TRACE("string=%s\n", debugstr_a(pMem));
569   }
570   else if (*pFormat == RPC_FC_C_WSTRING) {
571     TRACE("string=%s\n", debugstr_w((LPWSTR)pMem));
572   }
573
574   return NULL; /* FIXME: is this always right? */
575 }
576
577 static inline void dump_pointer_attr(unsigned char attr)
578 {
579     if (attr & RPC_FC_P_ALLOCALLNODES)
580         TRACE(" RPC_FC_P_ALLOCALLNODES");
581     if (attr & RPC_FC_P_DONTFREE)
582         TRACE(" RPC_FC_P_DONTFREE");
583     if (attr & RPC_FC_P_ONSTACK)
584         TRACE(" RPC_FC_P_ONSTACK");
585     if (attr & RPC_FC_P_SIMPLEPOINTER)
586         TRACE(" RPC_FC_P_SIMPLEPOINTER");
587     if (attr & RPC_FC_P_DEREF)
588         TRACE(" RPC_FC_P_DEREF");
589     TRACE("\n");
590 }
591
592 /***********************************************************************
593  *           PointerMarshall
594  */
595 void WINAPI PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
596                             unsigned char *Buffer,
597                             unsigned char *Pointer,
598                             PFORMAT_STRING pFormat)
599 {
600   unsigned type = pFormat[0], attr = pFormat[1];
601   PFORMAT_STRING desc;
602   NDR_MARSHALL m;
603
604   TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
605   TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
606   pFormat += 2;
607   if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
608   else desc = pFormat + *(const SHORT*)pFormat;
609   if (attr & RPC_FC_P_DEREF) {
610     Pointer = *(unsigned char**)Pointer;
611     TRACE("deref => %p\n", Pointer);
612   }
613
614   switch (type) {
615   case RPC_FC_RP: /* ref pointer (always non-null) */
616 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
617     if (!Pointer)
618       RpcRaiseException(RPC_X_NULL_REF_POINTER);
619 #endif
620     break;
621   case RPC_FC_UP: /* unique pointer */
622   case RPC_FC_OP: /* object pointer - same as unique here */
623     TRACE("writing %p to buffer\n", Pointer);
624     NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, (unsigned long)Pointer);
625     pStubMsg->Buffer += 4;
626     break;
627   case RPC_FC_FP:
628   default:
629     FIXME("unhandled ptr type=%02x\n", type);
630     RpcRaiseException(RPC_X_BAD_STUB_DATA);
631   }
632
633   TRACE("calling marshaller for type 0x%x\n", (int)*desc);
634
635   if (Pointer) {
636     m = NdrMarshaller[*desc & NDR_TABLE_MASK];
637     if (m) m(pStubMsg, Pointer, desc);
638     else FIXME("no marshaller for data type=%02x\n", *desc);
639   }
640
641   STD_OVERFLOW_CHECK(pStubMsg);
642 }
643
644 /***********************************************************************
645  *           PointerUnmarshall
646  */
647 void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
648                               unsigned char *Buffer,
649                               unsigned char **pPointer,
650                               PFORMAT_STRING pFormat,
651                               unsigned char fMustAlloc)
652 {
653   unsigned type = pFormat[0], attr = pFormat[1];
654   PFORMAT_STRING desc;
655   NDR_UNMARSHALL m;
656   DWORD pointer_id = 0;
657
658   TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
659   TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
660   pFormat += 2;
661   if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
662   else desc = pFormat + *(const SHORT*)pFormat;
663   if (attr & RPC_FC_P_DEREF) {
664     pPointer = *(unsigned char***)pPointer;
665     TRACE("deref => %p\n", pPointer);
666   }
667
668   switch (type) {
669   case RPC_FC_RP: /* ref pointer (always non-null) */
670     pointer_id = ~0UL;
671     break;
672   case RPC_FC_UP: /* unique pointer */
673     pointer_id = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
674     pStubMsg->Buffer += 4;
675     break;
676   case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
677   case RPC_FC_FP:
678   default:
679     FIXME("unhandled ptr type=%02x\n", type);
680     RpcRaiseException(RPC_X_BAD_STUB_DATA);
681   }
682
683   *pPointer = NULL;
684
685   if (pointer_id) {
686     m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
687     if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
688     else FIXME("no unmarshaller for data type=%02x\n", *desc);
689   }
690
691   TRACE("pointer=%p\n", *pPointer);
692 }
693
694 /***********************************************************************
695  *           PointerBufferSize
696  */
697 void WINAPI PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
698                               unsigned char *Pointer,
699                               PFORMAT_STRING pFormat)
700 {
701   unsigned type = pFormat[0], attr = pFormat[1];
702   PFORMAT_STRING desc;
703   NDR_BUFFERSIZE m;
704
705   TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
706   TRACE("type=%d, attr=%d\n", type, attr);
707   pFormat += 2;
708   if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
709   else desc = pFormat + *(const SHORT*)pFormat;
710   if (attr & RPC_FC_P_DEREF) {
711     Pointer = *(unsigned char**)Pointer;
712     TRACE("deref => %p\n", Pointer);
713   }
714
715   switch (type) {
716   case RPC_FC_RP: /* ref pointer (always non-null) */
717     break;
718   case RPC_FC_OP:
719   case RPC_FC_UP:
720     pStubMsg->BufferLength += 4;
721     /* NULL pointer has no further representation */
722     if (!Pointer)
723         return;
724     break;
725   case RPC_FC_FP:
726   default:
727     FIXME("unhandled ptr type=%02x\n", type);
728     RpcRaiseException(RPC_X_BAD_STUB_DATA);
729   }
730
731   m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
732   if (m) m(pStubMsg, Pointer, desc);
733   else FIXME("no buffersizer for data type=%02x\n", *desc);
734 }
735
736 /***********************************************************************
737  *           PointerMemorySize [RPCRT4.@]
738  */
739 unsigned long WINAPI PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
740                                        unsigned char *Buffer,
741                                        PFORMAT_STRING pFormat)
742 {
743   unsigned type = pFormat[0], attr = pFormat[1];
744   PFORMAT_STRING desc;
745   NDR_MEMORYSIZE m;
746
747   FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
748   TRACE("type=%d, attr=", type); dump_pointer_attr(attr);
749   pFormat += 2;
750   if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
751   else desc = pFormat + *(const SHORT*)pFormat;
752   if (attr & RPC_FC_P_DEREF) {
753     TRACE("deref\n");
754   }
755
756   switch (type) {
757   case RPC_FC_RP: /* ref pointer (always non-null) */
758     break;
759   default:
760     FIXME("unhandled ptr type=%02x\n", type);
761     RpcRaiseException(RPC_X_BAD_STUB_DATA);
762   }
763
764   m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
765   if (m) m(pStubMsg, desc);
766   else FIXME("no memorysizer for data type=%02x\n", *desc);
767
768   return 0;
769 }
770
771 /***********************************************************************
772  *           PointerFree [RPCRT4.@]
773  */
774 void WINAPI PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
775                         unsigned char *Pointer,
776                         PFORMAT_STRING pFormat)
777 {
778   unsigned type = pFormat[0], attr = pFormat[1];
779   PFORMAT_STRING desc;
780   NDR_FREE m;
781
782   TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
783   TRACE("type=%d, attr=", type); dump_pointer_attr(attr);
784   if (attr & RPC_FC_P_DONTFREE) return;
785   pFormat += 2;
786   if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
787   else desc = pFormat + *(const SHORT*)pFormat;
788   if (attr & RPC_FC_P_DEREF) {
789     Pointer = *(unsigned char**)Pointer;
790     TRACE("deref => %p\n", Pointer);
791   }
792
793   if (!Pointer) return;
794
795   m = NdrFreer[*desc & NDR_TABLE_MASK];
796   if (m) m(pStubMsg, Pointer, desc);
797
798   /* hmm... is this sensible?
799    * perhaps we should check if the memory comes from NdrAllocate,
800    * and deallocate only if so - checking if the pointer is between
801    * BufferStart and BufferEnd is probably no good since the buffer
802    * may be reallocated when the server wants to marshal the reply */
803   switch (*desc) {
804   case RPC_FC_BOGUS_STRUCT:
805   case RPC_FC_BOGUS_ARRAY:
806   case RPC_FC_USER_MARSHAL:
807     break;
808   default:
809     FIXME("unhandled data type=%02x\n", *desc);
810   case RPC_FC_CARRAY:
811   case RPC_FC_C_CSTRING:
812   case RPC_FC_C_WSTRING:
813     if (pStubMsg->ReuseBuffer) goto notfree;
814     break;
815   case RPC_FC_IP:
816     goto notfree;
817   }
818
819   if (attr & RPC_FC_P_ONSTACK) {
820     TRACE("not freeing stack ptr %p\n", Pointer);
821     return;
822   }
823   TRACE("freeing %p\n", Pointer);
824   NdrFree(pStubMsg, Pointer);
825   return;
826 notfree:
827   TRACE("not freeing %p\n", Pointer);
828 }
829
830 /***********************************************************************
831  *           EmbeddedPointerMarshall
832  */
833 unsigned char * WINAPI EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
834                                                unsigned char *pMemory,
835                                                PFORMAT_STRING pFormat)
836 {
837   unsigned char *Mark = pStubMsg->BufferMark;
838   unsigned long Offset = pStubMsg->Offset;
839   unsigned ofs, rep, count, stride, xofs;
840
841   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
842
843   if (*pFormat != RPC_FC_PP) return NULL;
844   pFormat += 2;
845
846   while (pFormat[0] != RPC_FC_END) {
847     switch (pFormat[0]) {
848     default:
849       FIXME("unknown repeat type %d\n", pFormat[0]);
850     case RPC_FC_NO_REPEAT:
851       rep = 1;
852       stride = 0;
853       ofs = 0;
854       count = 1;
855       xofs = 0;
856       pFormat += 2;
857       break;
858     case RPC_FC_FIXED_REPEAT:
859       rep = *(const WORD*)&pFormat[2];
860       stride = *(const WORD*)&pFormat[4];
861       ofs = *(const WORD*)&pFormat[6];
862       count = *(const WORD*)&pFormat[8];
863       xofs = 0;
864       pFormat += 10;
865       break;
866     case RPC_FC_VARIABLE_REPEAT:
867       rep = pStubMsg->MaxCount;
868       stride = *(const WORD*)&pFormat[2];
869       ofs = *(const WORD*)&pFormat[4];
870       count = *(const WORD*)&pFormat[6];
871       xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
872       pFormat += 8;
873       break;
874     }
875     /* ofs doesn't seem to matter in this context */
876     while (rep) {
877       PFORMAT_STRING info = pFormat;
878       unsigned char *membase = pMemory + xofs;
879       unsigned u;
880       for (u=0; u<count; u++,info+=8) {
881         unsigned char *memptr = membase + *(const SHORT*)&info[0];
882         unsigned char *bufptr = Mark + *(const SHORT*)&info[2];
883         PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
884       }
885       rep--;
886     }
887     pFormat += 8 * count;
888   }
889
890   STD_OVERFLOW_CHECK(pStubMsg);
891
892   return NULL;
893 }
894
895 /***********************************************************************
896  *           EmbeddedPointerUnmarshall
897  */
898 unsigned char * WINAPI EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
899                                                  unsigned char **ppMemory,
900                                                  PFORMAT_STRING pFormat,
901                                                  unsigned char fMustAlloc)
902 {
903   unsigned char *Mark = pStubMsg->BufferMark;
904   unsigned long Offset = pStubMsg->Offset;
905   unsigned ofs, rep, count, stride, xofs;
906
907   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
908
909   if (*pFormat != RPC_FC_PP) return NULL;
910   pFormat += 2;
911
912   while (pFormat[0] != RPC_FC_END) {
913     switch (pFormat[0]) {
914     default:
915       FIXME("unknown repeat type %d\n", pFormat[0]);
916     case RPC_FC_NO_REPEAT:
917       rep = 1;
918       stride = 0;
919       ofs = 0;
920       count = 1;
921       xofs = 0;
922       pFormat += 2;
923       break;
924     case RPC_FC_FIXED_REPEAT:
925       rep = *(const WORD*)&pFormat[2];
926       stride = *(const WORD*)&pFormat[4];
927       ofs = *(const WORD*)&pFormat[6];
928       count = *(const WORD*)&pFormat[8];
929       xofs = 0;
930       pFormat += 10;
931       break;
932     case RPC_FC_VARIABLE_REPEAT:
933       rep = pStubMsg->MaxCount;
934       stride = *(const WORD*)&pFormat[2];
935       ofs = *(const WORD*)&pFormat[4];
936       count = *(const WORD*)&pFormat[6];
937       xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
938       pFormat += 8;
939       break;
940     }
941     /* ofs doesn't seem to matter in this context */
942     while (rep) {
943       PFORMAT_STRING info = pFormat;
944       unsigned char *membase = *ppMemory + xofs;
945       unsigned u;
946       for (u=0; u<count; u++,info+=8) {
947         unsigned char *memptr = membase + *(const SHORT*)&info[0];
948         unsigned char *bufptr = Mark + *(const SHORT*)&info[2];
949         PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, fMustAlloc);
950       }
951       rep--;
952     }
953     pFormat += 8 * count;
954   }
955
956   return NULL;
957 }
958
959 /***********************************************************************
960  *           EmbeddedPointerBufferSize
961  */
962 void WINAPI EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
963                                       unsigned char *pMemory,
964                                       PFORMAT_STRING pFormat)
965 {
966   unsigned long Offset = pStubMsg->Offset;
967   unsigned ofs, rep, count, stride, xofs;
968
969   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
970   if (*pFormat != RPC_FC_PP) return;
971   pFormat += 2;
972
973   while (pFormat[0] != RPC_FC_END) {
974     switch (pFormat[0]) {
975     default:
976       FIXME("unknown repeat type %d\n", pFormat[0]);
977     case RPC_FC_NO_REPEAT:
978       rep = 1;
979       stride = 0;
980       ofs = 0;
981       count = 1;
982       xofs = 0;
983       pFormat += 2;
984       break;
985     case RPC_FC_FIXED_REPEAT:
986       rep = *(const WORD*)&pFormat[2];
987       stride = *(const WORD*)&pFormat[4];
988       ofs = *(const WORD*)&pFormat[6];
989       count = *(const WORD*)&pFormat[8];
990       xofs = 0;
991       pFormat += 10;
992       break;
993     case RPC_FC_VARIABLE_REPEAT:
994       rep = pStubMsg->MaxCount;
995       stride = *(const WORD*)&pFormat[2];
996       ofs = *(const WORD*)&pFormat[4];
997       count = *(const WORD*)&pFormat[6];
998       xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
999       pFormat += 8;
1000       break;
1001     }
1002     /* ofs doesn't seem to matter in this context */
1003     while (rep) {
1004       PFORMAT_STRING info = pFormat;
1005       unsigned char *membase = pMemory + xofs;
1006       unsigned u;
1007       for (u=0; u<count; u++,info+=8) {
1008         unsigned char *memptr = membase + *(const SHORT*)&info[0];
1009         PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1010       }
1011       rep--;
1012     }
1013     pFormat += 8 * count;
1014   }
1015 }
1016
1017 /***********************************************************************
1018  *           EmbeddedPointerMemorySize
1019  */
1020 unsigned long WINAPI EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1021                                                PFORMAT_STRING pFormat)
1022 {
1023   unsigned long Offset = pStubMsg->Offset;
1024   unsigned char *Mark = pStubMsg->BufferMark;
1025   unsigned ofs, rep, count, stride, xofs;
1026
1027   FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1028   if (*pFormat != RPC_FC_PP) return 0;
1029   pFormat += 2;
1030
1031   while (pFormat[0] != RPC_FC_END) {
1032     switch (pFormat[0]) {
1033     default:
1034       FIXME("unknown repeat type %d\n", pFormat[0]);
1035     case RPC_FC_NO_REPEAT:
1036       rep = 1;
1037       stride = 0;
1038       ofs = 0;
1039       count = 1;
1040       xofs = 0;
1041       pFormat += 2;
1042       break;
1043     case RPC_FC_FIXED_REPEAT:
1044       rep = *(const WORD*)&pFormat[2];
1045       stride = *(const WORD*)&pFormat[4];
1046       ofs = *(const WORD*)&pFormat[6];
1047       count = *(const WORD*)&pFormat[8];
1048       xofs = 0;
1049       pFormat += 10;
1050       break;
1051     case RPC_FC_VARIABLE_REPEAT:
1052       rep = pStubMsg->MaxCount;
1053       stride = *(const WORD*)&pFormat[2];
1054       ofs = *(const WORD*)&pFormat[4];
1055       count = *(const WORD*)&pFormat[6];
1056       xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1057       pFormat += 8;
1058       break;
1059     }
1060     /* ofs doesn't seem to matter in this context */
1061     while (rep) {
1062       PFORMAT_STRING info = pFormat;
1063       unsigned u;
1064       for (u=0; u<count; u++,info+=8) {
1065         unsigned char *bufptr = Mark + *(const SHORT*)&info[2];
1066         PointerMemorySize(pStubMsg, bufptr, info+4);
1067       }
1068       rep--;
1069     }
1070     pFormat += 8 * count;
1071   }
1072
1073   return 0;
1074 }
1075
1076 /***********************************************************************
1077  *           EmbeddedPointerFree
1078  */
1079 void WINAPI EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1080                                 unsigned char *pMemory,
1081                                 PFORMAT_STRING pFormat)
1082 {
1083   unsigned long Offset = pStubMsg->Offset;
1084   unsigned ofs, rep, count, stride, xofs;
1085
1086   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1087   if (*pFormat != RPC_FC_PP) return;
1088   pFormat += 2;
1089
1090   while (pFormat[0] != RPC_FC_END) {
1091     switch (pFormat[0]) {
1092     default:
1093       FIXME("unknown repeat type %d\n", pFormat[0]);
1094     case RPC_FC_NO_REPEAT:
1095       rep = 1;
1096       stride = 0;
1097       ofs = 0;
1098       count = 1;
1099       xofs = 0;
1100       pFormat += 2;
1101       break;
1102     case RPC_FC_FIXED_REPEAT:
1103       rep = *(const WORD*)&pFormat[2];
1104       stride = *(const WORD*)&pFormat[4];
1105       ofs = *(const WORD*)&pFormat[6];
1106       count = *(const WORD*)&pFormat[8];
1107       xofs = 0;
1108       pFormat += 10;
1109       break;
1110     case RPC_FC_VARIABLE_REPEAT:
1111       rep = pStubMsg->MaxCount;
1112       stride = *(const WORD*)&pFormat[2];
1113       ofs = *(const WORD*)&pFormat[4];
1114       count = *(const WORD*)&pFormat[6];
1115       xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1116       pFormat += 8;
1117       break;
1118     }
1119     /* ofs doesn't seem to matter in this context */
1120     while (rep) {
1121       PFORMAT_STRING info = pFormat;
1122       unsigned char *membase = pMemory + xofs;
1123       unsigned u;
1124       for (u=0; u<count; u++,info+=8) {
1125         unsigned char *memptr = membase + *(const SHORT*)&info[0];
1126         PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1127       }
1128       rep--;
1129     }
1130     pFormat += 8 * count;
1131   }
1132 }
1133
1134 /***********************************************************************
1135  *           NdrPointerMarshall [RPCRT4.@]
1136  */
1137 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1138                                           unsigned char *pMemory,
1139                                           PFORMAT_STRING pFormat)
1140 {
1141   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1142
1143   pStubMsg->BufferMark = pStubMsg->Buffer;
1144   PointerMarshall(pStubMsg, pStubMsg->Buffer, pMemory, pFormat);
1145
1146   STD_OVERFLOW_CHECK(pStubMsg);
1147
1148   return NULL;
1149 }
1150
1151 /***********************************************************************
1152  *           NdrPointerUnmarshall [RPCRT4.@]
1153  */
1154 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1155                                             unsigned char **ppMemory,
1156                                             PFORMAT_STRING pFormat,
1157                                             unsigned char fMustAlloc)
1158 {
1159   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1160
1161   pStubMsg->BufferMark = pStubMsg->Buffer;
1162   PointerUnmarshall(pStubMsg, pStubMsg->Buffer, ppMemory, pFormat, fMustAlloc);
1163
1164   return NULL;
1165 }
1166
1167 /***********************************************************************
1168  *           NdrPointerBufferSize [RPCRT4.@]
1169  */
1170 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1171                                       unsigned char *pMemory,
1172                                       PFORMAT_STRING pFormat)
1173 {
1174   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1175   PointerBufferSize(pStubMsg, pMemory, pFormat);
1176 }
1177
1178 /***********************************************************************
1179  *           NdrPointerMemorySize [RPCRT4.@]
1180  */
1181 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1182                                           PFORMAT_STRING pFormat)
1183 {
1184   /* unsigned size = *(LPWORD)(pFormat+2); */
1185   FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1186   PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1187   return 0;
1188 }
1189
1190 /***********************************************************************
1191  *           NdrPointerFree [RPCRT4.@]
1192  */
1193 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1194                            unsigned char *pMemory,
1195                            PFORMAT_STRING pFormat)
1196 {
1197   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1198   PointerFree(pStubMsg, pMemory, pFormat);
1199 }
1200
1201 /***********************************************************************
1202  *           NdrSimpleStructMarshall [RPCRT4.@]
1203  */
1204 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1205                                                unsigned char *pMemory,
1206                                                PFORMAT_STRING pFormat)
1207 {
1208   unsigned size = *(const WORD*)(pFormat+2);
1209   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1210
1211   memcpy(pStubMsg->Buffer, pMemory, size);
1212   pStubMsg->BufferMark = pStubMsg->Buffer;
1213   pStubMsg->Buffer += size;
1214
1215   if (pFormat[0] != RPC_FC_STRUCT)
1216     EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1217
1218   STD_OVERFLOW_CHECK(pStubMsg);
1219
1220   return NULL;
1221 }
1222
1223 /***********************************************************************
1224  *           NdrSimpleStructUnmarshall [RPCRT4.@]
1225  */
1226 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1227                                                  unsigned char **ppMemory,
1228                                                  PFORMAT_STRING pFormat,
1229                                                  unsigned char fMustAlloc)
1230 {
1231   unsigned size = *(const WORD*)(pFormat+2);
1232   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1233
1234   if (fMustAlloc) {
1235     *ppMemory = NdrAllocate(pStubMsg, size);
1236     memcpy(*ppMemory, pStubMsg->Buffer, size);
1237   } else {
1238     if (pStubMsg->ReuseBuffer && !*ppMemory)
1239       /* for servers, we may just point straight into the RPC buffer, I think
1240        * (I guess that's what MS does since MIDL code doesn't try to free) */
1241       *ppMemory = pStubMsg->Buffer;
1242     else
1243       /* for clients, memory should be provided by caller */
1244       memcpy(*ppMemory, pStubMsg->Buffer, size);
1245   }
1246
1247   pStubMsg->BufferMark = pStubMsg->Buffer;
1248   pStubMsg->Buffer += size;
1249
1250   if (pFormat[0] != RPC_FC_STRUCT)
1251     EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1252
1253   return NULL;
1254 }
1255
1256
1257 /***********************************************************************
1258  *           NdrSimpleStructUnmarshall [RPCRT4.@]
1259  */
1260 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1261                                    unsigned char FormatChar )
1262 {
1263     FIXME("stub\n");
1264 }
1265
1266
1267 /***********************************************************************
1268  *           NdrSimpleStructUnmarshall [RPCRT4.@]
1269  */
1270 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1271                                      unsigned char FormatChar )
1272 {
1273     FIXME("stub\n");
1274 }
1275
1276
1277 /***********************************************************************
1278  *           NdrSimpleStructBufferSize [RPCRT4.@]
1279  */
1280 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1281                                       unsigned char *pMemory,
1282                                       PFORMAT_STRING pFormat)
1283 {
1284   unsigned size = *(const WORD*)(pFormat+2);
1285   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1286   pStubMsg->BufferLength += size;
1287   if (pFormat[0] != RPC_FC_STRUCT)
1288     EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1289 }
1290
1291 /***********************************************************************
1292  *           NdrSimpleStructMemorySize [RPCRT4.@]
1293  */
1294 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1295                                                PFORMAT_STRING pFormat)
1296 {
1297   /* unsigned size = *(LPWORD)(pFormat+2); */
1298   FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1299   if (pFormat[0] != RPC_FC_STRUCT)
1300     EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1301   return 0;
1302 }
1303
1304 /***********************************************************************
1305  *           NdrSimpleStructFree [RPCRT4.@]
1306  */
1307 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1308                                 unsigned char *pMemory,
1309                                 PFORMAT_STRING pFormat)
1310 {
1311   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1312   if (pFormat[0] != RPC_FC_STRUCT)
1313     EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1314 }
1315
1316
1317 unsigned long WINAPI EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1318                                          PFORMAT_STRING pFormat)
1319 {
1320   switch (*pFormat) {
1321   case RPC_FC_STRUCT:
1322   case RPC_FC_PSTRUCT:
1323   case RPC_FC_CSTRUCT:
1324   case RPC_FC_BOGUS_STRUCT:
1325     return *(const WORD*)&pFormat[2];
1326   case RPC_FC_USER_MARSHAL:
1327     return *(const WORD*)&pFormat[4];
1328   default:
1329     FIXME("unhandled embedded type %02x\n", *pFormat);
1330   }
1331   return 0;
1332 }
1333
1334
1335 unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1336                                        unsigned char *pMemory,
1337                                        PFORMAT_STRING pFormat,
1338                                        PFORMAT_STRING pPointer)
1339 {
1340   PFORMAT_STRING desc;
1341   NDR_MARSHALL m;
1342   unsigned long size;
1343
1344   while (*pFormat != RPC_FC_END) {
1345     switch (*pFormat) {
1346     case RPC_FC_SHORT:
1347     case RPC_FC_USHORT:
1348       TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1349       memcpy(pStubMsg->Buffer, pMemory, 2);
1350       pStubMsg->Buffer += 2;
1351       pMemory += 2;
1352       break;
1353     case RPC_FC_LONG:
1354     case RPC_FC_ULONG:
1355       TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1356       memcpy(pStubMsg->Buffer, pMemory, 4);
1357       pStubMsg->Buffer += 4;
1358       pMemory += 4;
1359       break;
1360     case RPC_FC_POINTER:
1361       TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1362       NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1363       pPointer += 4;
1364       pMemory += 4;
1365       break;
1366     case RPC_FC_ALIGNM4:
1367       ALIGN_POINTER(pMemory, 3);
1368       break;
1369     case RPC_FC_ALIGNM8:
1370       ALIGN_POINTER(pMemory, 7);
1371       break;
1372     case RPC_FC_EMBEDDED_COMPLEX:
1373       pMemory += pFormat[1];
1374       pFormat += 2;
1375       desc = pFormat + *(const SHORT*)pFormat;
1376       size = EmbeddedComplexSize(pStubMsg, desc);
1377       TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1378       m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1379       if (m) m(pStubMsg, pMemory, desc);
1380       else FIXME("no marshaller for embedded type %02x\n", *desc);
1381       pMemory += size;
1382       pFormat += 2;
1383       continue;
1384     case RPC_FC_PAD:
1385       break;
1386     default:
1387       FIXME("unhandled format %02x\n", *pFormat);
1388     }
1389     pFormat++;
1390   }
1391
1392   return pMemory;
1393 }
1394
1395 unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1396                                          unsigned char *pMemory,
1397                                          PFORMAT_STRING pFormat,
1398                                          PFORMAT_STRING pPointer,
1399                                          unsigned char fMustAlloc)
1400 {
1401   PFORMAT_STRING desc;
1402   NDR_UNMARSHALL m;
1403   unsigned long size;
1404
1405   while (*pFormat != RPC_FC_END) {
1406     switch (*pFormat) {
1407     case RPC_FC_SHORT:
1408     case RPC_FC_USHORT:
1409       memcpy(pMemory, pStubMsg->Buffer, 2);
1410       TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1411       pStubMsg->Buffer += 2;
1412       pMemory += 2;
1413       break;
1414     case RPC_FC_LONG:
1415     case RPC_FC_ULONG:
1416       memcpy(pMemory, pStubMsg->Buffer, 4);
1417       TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1418       pStubMsg->Buffer += 4;
1419       pMemory += 4;
1420       break;
1421     case RPC_FC_POINTER:
1422       *(unsigned char**)pMemory = NULL;
1423       TRACE("pointer => %p\n", pMemory);
1424       NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, fMustAlloc);
1425       pPointer += 4;
1426       pMemory += 4;
1427       break;
1428     case RPC_FC_ALIGNM4:
1429       ALIGN_POINTER(pMemory, 3);
1430       break;
1431     case RPC_FC_ALIGNM8:
1432       ALIGN_POINTER(pMemory, 7);
1433       break;
1434     case RPC_FC_EMBEDDED_COMPLEX:
1435       pMemory += pFormat[1];
1436       pFormat += 2;
1437       desc = pFormat + *(const SHORT*)pFormat;
1438       size = EmbeddedComplexSize(pStubMsg, desc);
1439       TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1440       m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1441       memset(pMemory, 0, size); /* just in case */
1442       if (m) m(pStubMsg, &pMemory, desc, fMustAlloc);
1443       else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1444       pMemory += size;
1445       pFormat += 2;
1446       continue;
1447     case RPC_FC_PAD:
1448       break;
1449     default:
1450       FIXME("unhandled format %d\n", *pFormat);
1451     }
1452     pFormat++;
1453   }
1454
1455   return pMemory;
1456 }
1457
1458 unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1459                                          unsigned char *pMemory,
1460                                          PFORMAT_STRING pFormat,
1461                                          PFORMAT_STRING pPointer)
1462 {
1463   PFORMAT_STRING desc;
1464   NDR_BUFFERSIZE m;
1465   unsigned long size;
1466
1467   while (*pFormat != RPC_FC_END) {
1468     switch (*pFormat) {
1469     case RPC_FC_SHORT:
1470     case RPC_FC_USHORT:
1471       pStubMsg->BufferLength += 2;
1472       pMemory += 2;
1473       break;
1474     case RPC_FC_LONG:
1475     case RPC_FC_ULONG:
1476       pStubMsg->BufferLength += 4;
1477       pMemory += 4;
1478       break;
1479     case RPC_FC_POINTER:
1480       NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1481       pPointer += 4;
1482       pMemory += 4;
1483       break;
1484     case RPC_FC_ALIGNM4:
1485       ALIGN_POINTER(pMemory, 3);
1486       break;
1487     case RPC_FC_ALIGNM8:
1488       ALIGN_POINTER(pMemory, 7);
1489       break;
1490     case RPC_FC_EMBEDDED_COMPLEX:
1491       pMemory += pFormat[1];
1492       pFormat += 2;
1493       desc = pFormat + *(const SHORT*)pFormat;
1494       size = EmbeddedComplexSize(pStubMsg, desc);
1495       m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1496       if (m) m(pStubMsg, pMemory, desc);
1497       else FIXME("no buffersizer for embedded type %02x\n", *desc);
1498       pMemory += size;
1499       pFormat += 2;
1500       continue;
1501     case RPC_FC_PAD:
1502       break;
1503     default:
1504       FIXME("unhandled format %d\n", *pFormat);
1505     }
1506     pFormat++;
1507   }
1508
1509   return pMemory;
1510 }
1511
1512 unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1513                                    unsigned char *pMemory,
1514                                    PFORMAT_STRING pFormat,
1515                                    PFORMAT_STRING pPointer)
1516 {
1517   PFORMAT_STRING desc;
1518   NDR_FREE m;
1519   unsigned long size;
1520
1521   while (*pFormat != RPC_FC_END) {
1522     switch (*pFormat) {
1523     case RPC_FC_SHORT:
1524     case RPC_FC_USHORT:
1525       pMemory += 2;
1526       break;
1527     case RPC_FC_LONG:
1528     case RPC_FC_ULONG:
1529       pMemory += 4;
1530       break;
1531     case RPC_FC_POINTER:
1532       NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1533       pPointer += 4;
1534       pMemory += 4;
1535       break;
1536     case RPC_FC_ALIGNM4:
1537       ALIGN_POINTER(pMemory, 3);
1538       break;
1539     case RPC_FC_ALIGNM8:
1540       ALIGN_POINTER(pMemory, 7);
1541       break;
1542     case RPC_FC_EMBEDDED_COMPLEX:
1543       pMemory += pFormat[1];
1544       pFormat += 2;
1545       desc = pFormat + *(const SHORT*)pFormat;
1546       size = EmbeddedComplexSize(pStubMsg, desc);
1547       m = NdrFreer[*desc & NDR_TABLE_MASK];
1548       if (m) m(pStubMsg, pMemory, desc);
1549       else FIXME("no freer for embedded type %02x\n", *desc);
1550       pMemory += size;
1551       pFormat += 2;
1552       continue;
1553     case RPC_FC_PAD:
1554       break;
1555     default:
1556       FIXME("unhandled format %d\n", *pFormat);
1557     }
1558     pFormat++;
1559   }
1560
1561   return pMemory;
1562 }
1563
1564 unsigned long WINAPI ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
1565                                        PFORMAT_STRING pFormat)
1566 {
1567   PFORMAT_STRING desc;
1568   unsigned long size = 0;
1569
1570   while (*pFormat != RPC_FC_END) {
1571     switch (*pFormat) {
1572     case RPC_FC_SHORT:
1573     case RPC_FC_USHORT:
1574       size += 2;
1575       break;
1576     case RPC_FC_LONG:
1577     case RPC_FC_ULONG:
1578       size += 4;
1579       break;
1580     case RPC_FC_POINTER:
1581       size += 4;
1582       break;
1583     case RPC_FC_ALIGNM4:
1584       ALIGN_LENGTH(size, 3);
1585       break;
1586     case RPC_FC_ALIGNM8:
1587       ALIGN_LENGTH(size, 7);
1588       break;
1589     case RPC_FC_EMBEDDED_COMPLEX:
1590       size += pFormat[1];
1591       pFormat += 2;
1592       desc = pFormat + *(const SHORT*)pFormat;
1593       size += EmbeddedComplexSize(pStubMsg, desc);
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 size;
1605 }
1606
1607 /***********************************************************************
1608  *           NdrComplexStructMarshall [RPCRT4.@]
1609  */
1610 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1611                                                 unsigned char *pMemory,
1612                                                 PFORMAT_STRING pFormat)
1613 {
1614   PFORMAT_STRING conf_array = NULL;
1615   PFORMAT_STRING pointer_desc = NULL;
1616   unsigned char *OldMemory = pStubMsg->Memory;
1617
1618   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1619
1620   pFormat += 4;
1621   if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1622   pFormat += 2;
1623   if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1624   pFormat += 2;
1625
1626   pStubMsg->Memory = pMemory;
1627
1628   ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
1629
1630   if (conf_array)
1631     NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
1632
1633   pStubMsg->Memory = OldMemory;
1634
1635   STD_OVERFLOW_CHECK(pStubMsg);
1636
1637   return NULL;
1638 }
1639
1640 /***********************************************************************
1641  *           NdrComplexStructUnmarshall [RPCRT4.@]
1642  */
1643 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1644                                                   unsigned char **ppMemory,
1645                                                   PFORMAT_STRING pFormat,
1646                                                   unsigned char fMustAlloc)
1647 {
1648   unsigned size = *(const WORD*)(pFormat+2);
1649   PFORMAT_STRING conf_array = NULL;
1650   PFORMAT_STRING pointer_desc = NULL;
1651   unsigned char *pMemory;
1652
1653   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1654
1655   if (fMustAlloc || !*ppMemory)
1656     *ppMemory = NdrAllocate(pStubMsg, size);
1657
1658   pFormat += 4;
1659   if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1660   pFormat += 2;
1661   if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1662   pFormat += 2;
1663
1664   pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
1665
1666   if (conf_array)
1667     NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
1668
1669   return NULL;
1670 }
1671
1672 /***********************************************************************
1673  *           NdrComplexStructBufferSize [RPCRT4.@]
1674  */
1675 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1676                                        unsigned char *pMemory,
1677                                        PFORMAT_STRING pFormat)
1678 {
1679   PFORMAT_STRING conf_array = NULL;
1680   PFORMAT_STRING pointer_desc = NULL;
1681   unsigned char *OldMemory = pStubMsg->Memory;
1682
1683   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1684
1685   pFormat += 4;
1686   if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1687   pFormat += 2;
1688   if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1689   pFormat += 2;
1690
1691   pStubMsg->Memory = pMemory;
1692
1693   pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
1694
1695   if (conf_array)
1696     NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
1697
1698   pStubMsg->Memory = OldMemory;
1699 }
1700
1701 /***********************************************************************
1702  *           NdrComplexStructMemorySize [RPCRT4.@]
1703  */
1704 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1705                                                 PFORMAT_STRING pFormat)
1706 {
1707   /* unsigned size = *(LPWORD)(pFormat+2); */
1708   PFORMAT_STRING conf_array = NULL;
1709   PFORMAT_STRING pointer_desc = NULL;
1710
1711   FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1712
1713   pFormat += 4;
1714   if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1715   pFormat += 2;
1716   if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1717   pFormat += 2;
1718
1719   return 0;
1720 }
1721
1722 /***********************************************************************
1723  *           NdrComplexStructFree [RPCRT4.@]
1724  */
1725 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1726                                  unsigned char *pMemory,
1727                                  PFORMAT_STRING pFormat)
1728 {
1729   PFORMAT_STRING conf_array = NULL;
1730   PFORMAT_STRING pointer_desc = NULL;
1731   unsigned char *OldMemory = pStubMsg->Memory;
1732
1733   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1734
1735   pFormat += 4;
1736   if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1737   pFormat += 2;
1738   if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1739   pFormat += 2;
1740
1741   pStubMsg->Memory = pMemory;
1742
1743   pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
1744
1745   if (conf_array)
1746     NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
1747
1748   pStubMsg->Memory = OldMemory;
1749 }
1750
1751 /***********************************************************************
1752  *           NdrConformantArrayMarshall [RPCRT4.@]
1753  */
1754 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1755                                                   unsigned char *pMemory,
1756                                                   PFORMAT_STRING pFormat)
1757 {
1758   DWORD size = 0, esize = *(const WORD*)(pFormat+2);
1759   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1760   if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1761
1762   pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1763   size = pStubMsg->MaxCount;
1764
1765   NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
1766   pStubMsg->Buffer += 4;
1767
1768   memcpy(pStubMsg->Buffer, pMemory, size*esize);
1769   pStubMsg->BufferMark = pStubMsg->Buffer;
1770   pStubMsg->Buffer += size*esize;
1771
1772   EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1773
1774   STD_OVERFLOW_CHECK(pStubMsg);
1775
1776   return NULL;
1777 }
1778
1779 /***********************************************************************
1780  *           NdrConformantArrayUnmarshall [RPCRT4.@]
1781  */
1782 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1783                                                     unsigned char **ppMemory,
1784                                                     PFORMAT_STRING pFormat,
1785                                                     unsigned char fMustAlloc)
1786 {
1787   DWORD size = 0, esize = *(const WORD*)(pFormat+2);
1788   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1789   if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1790
1791   pFormat = ReadConformance(pStubMsg, pFormat+4);
1792   size = pStubMsg->MaxCount;
1793
1794   if (fMustAlloc) {
1795     *ppMemory = NdrAllocate(pStubMsg, size*esize);
1796     memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
1797   } else {
1798     if (pStubMsg->ReuseBuffer && !*ppMemory)
1799       /* for servers, we may just point straight into the RPC buffer, I think
1800        * (I guess that's what MS does since MIDL code doesn't try to free) */
1801       *ppMemory = pStubMsg->Buffer;
1802     else
1803       /* for clients, memory should be provided by caller */
1804       memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
1805   }
1806
1807   pStubMsg->BufferMark = pStubMsg->Buffer;
1808   pStubMsg->Buffer += size*esize;
1809
1810   EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
1811
1812   return NULL;
1813 }
1814
1815 /***********************************************************************
1816  *           NdrConformantArrayBufferSize [RPCRT4.@]
1817  */
1818 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1819                                          unsigned char *pMemory,
1820                                          PFORMAT_STRING pFormat)
1821 {
1822   DWORD size = 0, esize = *(const WORD*)(pFormat+2);
1823   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1824   if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1825
1826   pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1827   size = pStubMsg->MaxCount;
1828
1829   pStubMsg->BufferLength += size*esize;
1830
1831   EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1832 }
1833
1834 /***********************************************************************
1835  *           NdrConformantArrayMemorySize [RPCRT4.@]
1836  */
1837 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1838                                                   PFORMAT_STRING pFormat)
1839 {
1840   DWORD size = 0;
1841   FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1842   if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1843
1844   pFormat = ReadConformance(pStubMsg, pFormat+4);
1845   size = pStubMsg->MaxCount;
1846
1847   EmbeddedPointerMemorySize(pStubMsg, pFormat);
1848
1849   return 0;
1850 }
1851
1852 /***********************************************************************
1853  *           NdrConformantArrayFree [RPCRT4.@]
1854  */
1855 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
1856                                    unsigned char *pMemory,
1857                                    PFORMAT_STRING pFormat)
1858 {
1859   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1860   if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1861
1862   EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
1863 }
1864
1865
1866 /***********************************************************************
1867  *           NdrConformantVaryingArrayMarshall  [RPCRT4.@]
1868  */
1869 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
1870                                                          unsigned char* pMemory,
1871                                                          PFORMAT_STRING pFormat )
1872 {
1873     FIXME( "stub\n" );
1874     return NULL;
1875 }
1876
1877
1878 /***********************************************************************
1879  *           NdrConformantVaryingArrayUnmarshall  [RPCRT4.@]
1880  */
1881 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
1882                                                            unsigned char** ppMemory,
1883                                                            PFORMAT_STRING pFormat,
1884                                                            unsigned char fMustAlloc )
1885 {
1886     FIXME( "stub\n" );
1887     return NULL;
1888 }
1889
1890
1891 /***********************************************************************
1892  *           NdrConformantVaryingArrayFree  [RPCRT4.@]
1893  */
1894 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
1895                                            unsigned char* pMemory,
1896                                            PFORMAT_STRING pFormat )
1897 {
1898     FIXME( "stub\n" );
1899 }
1900
1901
1902 /***********************************************************************
1903  *           NdrConformantVaryingArrayBufferSize  [RPCRT4.@]
1904  */
1905 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
1906                                                  unsigned char* pMemory, PFORMAT_STRING pFormat )
1907 {
1908     FIXME( "stub\n" );
1909 }
1910
1911
1912 /***********************************************************************
1913  *           NdrConformantVaryingArrayMemorySize  [RPCRT4.@]
1914  */
1915 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
1916                                                           PFORMAT_STRING pFormat )
1917 {
1918     FIXME( "stub\n" );
1919     return 0;
1920 }
1921
1922
1923 /***********************************************************************
1924  *           NdrComplexArrayMarshall [RPCRT4.@]
1925  */
1926 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1927                                                unsigned char *pMemory,
1928                                                PFORMAT_STRING pFormat)
1929 {
1930   DWORD size = 0, count, def;
1931   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1932
1933   def = *(const WORD*)&pFormat[2];
1934   pFormat += 4;
1935
1936   pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1937   size = pStubMsg->MaxCount;
1938   TRACE("conformance=%ld\n", size);
1939
1940   if (*(const DWORD*)pFormat != 0xffffffff)
1941     FIXME("compute variance\n");
1942   pFormat += 4;
1943
1944   NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
1945   pStubMsg->Buffer += 4;
1946
1947   for (count=0; count<size; count++)
1948     pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
1949
1950   STD_OVERFLOW_CHECK(pStubMsg);
1951
1952   return NULL;
1953 }
1954
1955 /***********************************************************************
1956  *           NdrComplexArrayUnmarshall [RPCRT4.@]
1957  */
1958 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1959                                                  unsigned char **ppMemory,
1960                                                  PFORMAT_STRING pFormat,
1961                                                  unsigned char fMustAlloc)
1962 {
1963   DWORD size = 0, count, esize;
1964   unsigned char *pMemory;
1965   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1966
1967   pFormat += 4;
1968
1969   pFormat = ReadConformance(pStubMsg, pFormat);
1970   size = pStubMsg->MaxCount;
1971   TRACE("conformance=%ld\n", size);
1972
1973   pFormat += 4;
1974
1975   esize = ComplexStructSize(pStubMsg, pFormat);
1976
1977   if (fMustAlloc || !*ppMemory)
1978     *ppMemory = NdrAllocate(pStubMsg, size*esize);
1979
1980   pMemory = *ppMemory;
1981   for (count=0; count<size; count++)
1982     pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
1983
1984   return NULL;
1985 }
1986
1987 /***********************************************************************
1988  *           NdrComplexArrayBufferSize [RPCRT4.@]
1989  */
1990 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1991                                       unsigned char *pMemory,
1992                                       PFORMAT_STRING pFormat)
1993 {
1994   DWORD size = 0, count, def;
1995   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1996
1997   def = *(const WORD*)&pFormat[2];
1998   pFormat += 4;
1999
2000   pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2001   size = pStubMsg->MaxCount;
2002   TRACE("conformance=%ld\n", size);
2003
2004   if (*(const DWORD*)pFormat != 0xffffffff)
2005     FIXME("compute variance\n");
2006   pFormat += 4;
2007
2008   for (count=0; count<size; count++)
2009     pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2010 }
2011
2012 /***********************************************************************
2013  *           NdrComplexArrayMemorySize [RPCRT4.@]
2014  */
2015 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2016                                                PFORMAT_STRING pFormat)
2017 {
2018   DWORD size = 0;
2019   FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
2020
2021   pFormat += 4;
2022
2023   pFormat = ReadConformance(pStubMsg, pFormat);
2024   size = pStubMsg->MaxCount;
2025   TRACE("conformance=%ld\n", size);
2026
2027   pFormat += 4;
2028
2029   return 0;
2030 }
2031
2032 /***********************************************************************
2033  *           NdrComplexArrayFree [RPCRT4.@]
2034  */
2035 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2036                                 unsigned char *pMemory,
2037                                 PFORMAT_STRING pFormat)
2038 {
2039   DWORD size = 0, count, def;
2040   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2041
2042   def = *(const WORD*)&pFormat[2];
2043   pFormat += 4;
2044
2045   pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2046   size = pStubMsg->MaxCount;
2047   TRACE("conformance=%ld\n", size);
2048
2049   if (*(const DWORD*)pFormat != 0xffffffff)
2050     FIXME("compute variance\n");
2051   pFormat += 4;
2052
2053   for (count=0; count<size; count++)
2054     pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2055 }
2056
2057 unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2058 {
2059   return MAKELONG(pStubMsg->dwDestContext,
2060                   pStubMsg->RpcMsg->DataRepresentation);
2061 }
2062
2063 /***********************************************************************
2064  *           NdrUserMarshalMarshall [RPCRT4.@]
2065  */
2066 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2067                                               unsigned char *pMemory,
2068                                               PFORMAT_STRING pFormat)
2069 {
2070 /*  unsigned flags = pFormat[1]; */
2071   unsigned index = *(const WORD*)&pFormat[2];
2072   unsigned long uflag = UserMarshalFlags(pStubMsg);
2073   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2074   TRACE("index=%d\n", index);
2075
2076   pStubMsg->Buffer =
2077     pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2078       &uflag, pStubMsg->Buffer, pMemory);
2079
2080   STD_OVERFLOW_CHECK(pStubMsg);
2081
2082   return NULL;
2083 }
2084
2085 /***********************************************************************
2086  *           NdrUserMarshalUnmarshall [RPCRT4.@]
2087  */
2088 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2089                                                  unsigned char **ppMemory,
2090                                                  PFORMAT_STRING pFormat,
2091                                                  unsigned char fMustAlloc)
2092 {
2093 /*  unsigned flags = pFormat[1];*/
2094   unsigned index = *(const WORD*)&pFormat[2];
2095   DWORD memsize = *(const WORD*)&pFormat[4];
2096   unsigned long uflag = UserMarshalFlags(pStubMsg);
2097   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2098   TRACE("index=%d\n", index);
2099
2100   if (fMustAlloc || !*ppMemory)
2101     *ppMemory = NdrAllocate(pStubMsg, memsize);
2102
2103   pStubMsg->Buffer =
2104     pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2105       &uflag, pStubMsg->Buffer, *ppMemory);
2106
2107   return NULL;
2108 }
2109
2110 /***********************************************************************
2111  *           NdrUserMarshalBufferSize [RPCRT4.@]
2112  */
2113 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2114                                       unsigned char *pMemory,
2115                                       PFORMAT_STRING pFormat)
2116 {
2117 /*  unsigned flags = pFormat[1];*/
2118   unsigned index = *(const WORD*)&pFormat[2];
2119   DWORD bufsize = *(const WORD*)&pFormat[6];
2120   unsigned long uflag = UserMarshalFlags(pStubMsg);
2121   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2122   TRACE("index=%d\n", index);
2123
2124   if (bufsize) {
2125     TRACE("size=%ld\n", bufsize);
2126     pStubMsg->BufferLength += bufsize;
2127     return;
2128   }
2129
2130   pStubMsg->BufferLength =
2131     pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2132       &uflag, pStubMsg->BufferLength, pMemory);
2133 }
2134
2135 /***********************************************************************
2136  *           NdrUserMarshalMemorySize [RPCRT4.@]
2137  */
2138 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2139                                               PFORMAT_STRING pFormat)
2140 {
2141   unsigned index = *(const WORD*)&pFormat[2];
2142 /*  DWORD memsize = *(const WORD*)&pFormat[4]; */
2143   FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
2144   TRACE("index=%d\n", index);
2145
2146   return 0;
2147 }
2148
2149 /***********************************************************************
2150  *           NdrUserMarshalFree [RPCRT4.@]
2151  */
2152 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2153                                 unsigned char *pMemory,
2154                                 PFORMAT_STRING pFormat)
2155 {
2156 /*  unsigned flags = pFormat[1]; */
2157   unsigned index = *(const WORD*)&pFormat[2];
2158   unsigned long uflag = UserMarshalFlags(pStubMsg);
2159   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2160   TRACE("index=%d\n", index);
2161
2162   pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2163     &uflag, pMemory);
2164 }
2165
2166 /***********************************************************************
2167  *           NdrClearOutParameters [RPCRT4.@]
2168  */
2169 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2170                                   PFORMAT_STRING pFormat,
2171                                   void *ArgAddr)
2172 {
2173   FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2174 }
2175
2176 /***********************************************************************
2177  *           NdrConvert [RPCRT4.@]
2178  */
2179 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2180 {
2181   FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2182   /* FIXME: since this stub doesn't do any converting, the proper behavior
2183      is to raise an exception */
2184 }
2185
2186 /***********************************************************************
2187  *           NdrConvert2 [RPCRT4.@]
2188  */
2189 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2190 {
2191   FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2192     pStubMsg, pFormat, NumberParams);
2193   /* FIXME: since this stub doesn't do any converting, the proper behavior
2194      is to raise an exception */
2195 }
2196
2197 /***********************************************************************
2198  *           NdrConformantStructMarshall [RPCRT4.@]
2199  */
2200 unsigned char *  WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2201                                 unsigned char *pMemory,
2202                                 PFORMAT_STRING pFormat)
2203 {
2204     FIXME("stub\n");
2205     return NULL;
2206 }
2207
2208 /***********************************************************************
2209  *           NdrConformantStructUnmarshall [RPCRT4.@]
2210  */
2211 unsigned char *  WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2212                                 unsigned char **ppMemory,
2213                                 PFORMAT_STRING pFormat,
2214                                 unsigned char fMustAlloc)
2215 {
2216     FIXME("stub\n");
2217     return NULL;
2218 }
2219
2220 /***********************************************************************
2221  *           NdrConformantStructBufferSize [RPCRT4.@]
2222  */
2223 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2224                                 unsigned char *pMemory,
2225                                 PFORMAT_STRING pFormat)
2226 {
2227     FIXME("stub\n");
2228 }
2229
2230 /***********************************************************************
2231  *           NdrConformantStructMemorySize [RPCRT4.@]
2232  */
2233 unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2234                                 PFORMAT_STRING pFormat)
2235 {
2236     FIXME("stub\n");
2237     return 0;
2238 }
2239
2240 /***********************************************************************
2241  *           NdrConformantStructFree [RPCRT4.@]
2242  */
2243 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2244                                 unsigned char *pMemory,
2245                                 PFORMAT_STRING pFormat)
2246 {
2247     FIXME("stub\n");
2248 }
2249
2250 /***********************************************************************
2251  *           NdrConformantVaryingStructMarshall [RPCRT4.@]
2252  */
2253 unsigned char *  WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2254                                 unsigned char *pMemory,
2255                                 PFORMAT_STRING pFormat)
2256 {
2257     FIXME("stub\n");
2258     return NULL;
2259 }
2260
2261 /***********************************************************************
2262  *           NdrConformantVaryingStructUnmarshall [RPCRT4.@]
2263  */
2264 unsigned char *  WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2265                                 unsigned char **ppMemory,
2266                                 PFORMAT_STRING pFormat,
2267                                 unsigned char fMustAlloc)
2268 {
2269     FIXME("stub\n");
2270     return NULL;
2271 }
2272
2273 /***********************************************************************
2274  *           NdrConformantVaryingStructBufferSize [RPCRT4.@]
2275  */
2276 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2277                                 unsigned char *pMemory,
2278                                 PFORMAT_STRING pFormat)
2279 {
2280     FIXME("stub\n");
2281 }
2282
2283 /***********************************************************************
2284  *           NdrConformantVaryingStructMemorySize [RPCRT4.@]
2285  */
2286 unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2287                                 PFORMAT_STRING pFormat)
2288 {
2289     FIXME("stub\n");
2290     return 0;
2291 }
2292
2293 /***********************************************************************
2294  *           NdrConformantVaryingStructFree [RPCRT4.@]
2295  */
2296 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2297                                 unsigned char *pMemory,
2298                                 PFORMAT_STRING pFormat)
2299 {
2300     FIXME("stub\n");
2301 }
2302
2303 /***********************************************************************
2304  *           NdrFixedArrayMarshall [RPCRT4.@]
2305  */
2306 unsigned char *  WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2307                                 unsigned char *pMemory,
2308                                 PFORMAT_STRING pFormat)
2309 {
2310     FIXME("stub\n");
2311     return NULL;
2312 }
2313
2314 /***********************************************************************
2315  *           NdrFixedArrayUnmarshall [RPCRT4.@]
2316  */
2317 unsigned char *  WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2318                                 unsigned char **ppMemory,
2319                                 PFORMAT_STRING pFormat,
2320                                 unsigned char fMustAlloc)
2321 {
2322     FIXME("stub\n");
2323     return NULL;
2324 }
2325
2326 /***********************************************************************
2327  *           NdrFixedArrayBufferSize [RPCRT4.@]
2328  */
2329 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2330                                 unsigned char *pMemory,
2331                                 PFORMAT_STRING pFormat)
2332 {
2333     FIXME("stub\n");
2334 }
2335
2336 /***********************************************************************
2337  *           NdrFixedArrayMemorySize [RPCRT4.@]
2338  */
2339 unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2340                                 PFORMAT_STRING pFormat)
2341 {
2342     FIXME("stub\n");
2343     return 0;
2344 }
2345
2346 /***********************************************************************
2347  *           NdrFixedArrayFree [RPCRT4.@]
2348  */
2349 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2350                                 unsigned char *pMemory,
2351                                 PFORMAT_STRING pFormat)
2352 {
2353     FIXME("stub\n");
2354 }
2355
2356 /***********************************************************************
2357  *           NdrVaryingArrayMarshall [RPCRT4.@]
2358  */
2359 unsigned char *  WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2360                                 unsigned char *pMemory,
2361                                 PFORMAT_STRING pFormat)
2362 {
2363     FIXME("stub\n");
2364     return NULL;
2365 }
2366
2367 /***********************************************************************
2368  *           NdrVaryingArrayUnmarshall [RPCRT4.@]
2369  */
2370 unsigned char *  WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2371                                 unsigned char **ppMemory,
2372                                 PFORMAT_STRING pFormat,
2373                                 unsigned char fMustAlloc)
2374 {
2375     FIXME("stub\n");
2376     return NULL;
2377 }
2378
2379 /***********************************************************************
2380  *           NdrVaryingArrayBufferSize [RPCRT4.@]
2381  */
2382 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2383                                 unsigned char *pMemory,
2384                                 PFORMAT_STRING pFormat)
2385 {
2386     FIXME("stub\n");
2387 }
2388
2389 /***********************************************************************
2390  *           NdrVaryingArrayMemorySize [RPCRT4.@]
2391  */
2392 unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2393                                 PFORMAT_STRING pFormat)
2394 {
2395     FIXME("stub\n");
2396     return 0;
2397 }
2398
2399 /***********************************************************************
2400  *           NdrVaryingArrayFree [RPCRT4.@]
2401  */
2402 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2403                                 unsigned char *pMemory,
2404                                 PFORMAT_STRING pFormat)
2405 {
2406     FIXME("stub\n");
2407 }
2408
2409 /***********************************************************************
2410  *           NdrEncapsulatedUnionMarshall [RPCRT4.@]
2411  */
2412 unsigned char *  WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2413                                 unsigned char *pMemory,
2414                                 PFORMAT_STRING pFormat)
2415 {
2416     FIXME("stub\n");
2417     return NULL;
2418 }
2419
2420 /***********************************************************************
2421  *           NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
2422  */
2423 unsigned char *  WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2424                                 unsigned char **ppMemory,
2425                                 PFORMAT_STRING pFormat,
2426                                 unsigned char fMustAlloc)
2427 {
2428     FIXME("stub\n");
2429     return NULL;
2430 }
2431
2432 /***********************************************************************
2433  *           NdrEncapsulatedUnionBufferSize [RPCRT4.@]
2434  */
2435 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2436                                 unsigned char *pMemory,
2437                                 PFORMAT_STRING pFormat)
2438 {
2439     FIXME("stub\n");
2440 }
2441
2442 /***********************************************************************
2443  *           NdrEncapsulatedUnionMemorySize [RPCRT4.@]
2444  */
2445 unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2446                                 PFORMAT_STRING pFormat)
2447 {
2448     FIXME("stub\n");
2449     return 0;
2450 }
2451
2452 /***********************************************************************
2453  *           NdrEncapsulatedUnionFree [RPCRT4.@]
2454  */
2455 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
2456                                 unsigned char *pMemory,
2457                                 PFORMAT_STRING pFormat)
2458 {
2459     FIXME("stub\n");
2460 }
2461
2462 /***********************************************************************
2463  *           NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
2464  */
2465 unsigned char *  WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2466                                 unsigned char *pMemory,
2467                                 PFORMAT_STRING pFormat)
2468 {
2469     FIXME("stub\n");
2470     return NULL;
2471 }
2472
2473 /***********************************************************************
2474  *           NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
2475  */
2476 unsigned char *  WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2477                                 unsigned char **ppMemory,
2478                                 PFORMAT_STRING pFormat,
2479                                 unsigned char fMustAlloc)
2480 {
2481     FIXME("stub\n");
2482     return NULL;
2483 }
2484
2485 /***********************************************************************
2486  *           NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
2487  */
2488 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2489                                 unsigned char *pMemory,
2490                                 PFORMAT_STRING pFormat)
2491 {
2492     FIXME("stub\n");
2493 }
2494
2495 /***********************************************************************
2496  *           NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
2497  */
2498 unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2499                                 PFORMAT_STRING pFormat)
2500 {
2501     FIXME("stub\n");
2502     return 0;
2503 }
2504
2505 /***********************************************************************
2506  *           NdrNonEncapsulatedUnionFree [RPCRT4.@]
2507  */
2508 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
2509                                 unsigned char *pMemory,
2510                                 PFORMAT_STRING pFormat)
2511 {
2512     FIXME("stub\n");
2513 }
2514
2515 /***********************************************************************
2516  *           NdrByteCountPointerMarshall [RPCRT4.@]
2517  */
2518 unsigned char *  WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2519                                 unsigned char *pMemory,
2520                                 PFORMAT_STRING pFormat)
2521 {
2522     FIXME("stub\n");
2523     return NULL;
2524 }
2525
2526 /***********************************************************************
2527  *           NdrByteCountPointerUnmarshall [RPCRT4.@]
2528  */
2529 unsigned char *  WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2530                                 unsigned char **ppMemory,
2531                                 PFORMAT_STRING pFormat,
2532                                 unsigned char fMustAlloc)
2533 {
2534     FIXME("stub\n");
2535     return NULL;
2536 }
2537
2538 /***********************************************************************
2539  *           NdrByteCountPointerBufferSize [RPCRT4.@]
2540  */
2541 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2542                                 unsigned char *pMemory,
2543                                 PFORMAT_STRING pFormat)
2544 {
2545     FIXME("stub\n");
2546 }
2547
2548 /***********************************************************************
2549  *           NdrByteCountPointerMemorySize [RPCRT4.@]
2550  */
2551 unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2552                                 PFORMAT_STRING pFormat)
2553 {
2554     FIXME("stub\n");
2555     return 0;
2556 }
2557
2558 /***********************************************************************
2559  *           NdrByteCountPointerFree [RPCRT4.@]
2560  */
2561 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
2562                                 unsigned char *pMemory,
2563                                 PFORMAT_STRING pFormat)
2564 {
2565     FIXME("stub\n");
2566 }
2567
2568 /***********************************************************************
2569  *           NdrXmitOrRepAsMarshall [RPCRT4.@]
2570  */
2571 unsigned char *  WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2572                                 unsigned char *pMemory,
2573                                 PFORMAT_STRING pFormat)
2574 {
2575     FIXME("stub\n");
2576     return NULL;
2577 }
2578
2579 /***********************************************************************
2580  *           NdrXmitOrRepAsUnmarshall [RPCRT4.@]
2581  */
2582 unsigned char *  WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2583                                 unsigned char **ppMemory,
2584                                 PFORMAT_STRING pFormat,
2585                                 unsigned char fMustAlloc)
2586 {
2587     FIXME("stub\n");
2588     return NULL;
2589 }
2590
2591 /***********************************************************************
2592  *           NdrXmitOrRepAsBufferSize [RPCRT4.@]
2593  */
2594 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2595                                 unsigned char *pMemory,
2596                                 PFORMAT_STRING pFormat)
2597 {
2598     FIXME("stub\n");
2599 }
2600
2601 /***********************************************************************
2602  *           NdrXmitOrRepAsMemorySize [RPCRT4.@]
2603  */
2604 unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2605                                 PFORMAT_STRING pFormat)
2606 {
2607     FIXME("stub\n");
2608     return 0;
2609 }
2610
2611 /***********************************************************************
2612  *           NdrXmitOrRepAsFree [RPCRT4.@]
2613  */
2614 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
2615                                 unsigned char *pMemory,
2616                                 PFORMAT_STRING pFormat)
2617 {
2618     FIXME("stub\n");
2619 }
2620
2621 /***********************************************************************
2622  *           NdrClientContextMarshall
2623  */
2624 unsigned char * WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2625                                                 NDR_CCONTEXT ContextHandle,
2626                                                 int fCheck)
2627 {
2628     FIXME("(%p, %p, %d): stub\n", pStubMsg, ContextHandle, fCheck);
2629     return NULL;
2630 }
2631
2632 /***********************************************************************
2633  *           NdrClientContextUnmarshall
2634  */
2635 unsigned char * WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2636                                                   NDR_CCONTEXT * pContextHandle,
2637                                                   RPC_BINDING_HANDLE BindHandle)
2638 {
2639     FIXME("(%p, %p, %p): stub\n", pStubMsg, pContextHandle, BindHandle);
2640     return NULL;
2641 }