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