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