Implemented localeconv() with libc function.
[wine.git] / dlls / rpcrt4 / ndr_marshall.c
blobc95e0f9a40b1db1a45c593a9212339acb56a8736
1 /*
2 * NDR data marshalling
4 * Copyright 2002 Greg Turner
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.
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.
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
20 * TODO:
21 * - figure out whether we *really* got this right
22 * - check for errors and throw exceptions
25 #include <stdio.h>
26 #include <string.h>
27 #include <assert.h>
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winerror.h"
32 #include "winreg.h"
34 #include "ndr_misc.h"
35 #include "rpcndr.h"
37 #include "wine/unicode.h"
38 #include "wine/rpcfc.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(ole);
44 #define BUFFER_PARANOIA 20
46 #if defined(__i386__)
47 #define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
48 (*((UINT32 *)(pchar)) = (uint32))
50 #define LITTLE_ENDIAN_UINT32_READ(pchar) \
51 (*((UINT32 *)(pchar)))
52 #else
53 /* these would work for i386 too, but less efficient */
54 #define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
55 (*(pchar) = LOBYTE(LOWORD(uint32)), \
56 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
57 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
58 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
59 (uint32)) /* allow as r-value */
61 #define LITTLE_ENDIAN_UINT32_READ(pchar) \
62 (MAKELONG( \
63 MAKEWORD(*(pchar), *((pchar)+1)), \
64 MAKEWORD(*((pchar)+2), *((pchar)+3))))
65 #endif
67 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
68 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
69 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
70 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
71 *(pchar) = HIBYTE(HIWORD(uint32)), \
72 (uint32)) /* allow as r-value */
74 #define BIG_ENDIAN_UINT32_READ(pchar) \
75 (MAKELONG( \
76 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
77 MAKEWORD(*((pchar)+1), *(pchar))))
79 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
80 #define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
81 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
82 #define NDR_LOCAL_UINT32_READ(pchar) \
83 BIG_ENDIAN_UINT32_READ(pchar)
84 #else
85 #define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
86 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
87 #define NDR_LOCAL_UINT32_READ(pchar) \
88 LITTLE_ENDIAN_UINT32_READ(pchar)
89 #endif
91 /* _Align must be the desired alignment minus 1,
92 * e.g. ALIGN_LENGTH(len, 3) to align on a dword boundary. */
93 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
94 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
95 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
96 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
98 #define STD_OVERFLOW_CHECK(_Msg) do { \
99 TRACE("buffer=%d/%ld\n", _Msg->Buffer - _Msg->BufferStart, _Msg->BufferLength); \
100 if (_Msg->Buffer > _Msg->BufferEnd) ERR("buffer overflow %d bytes\n", _Msg->Buffer - _Msg->BufferEnd); \
101 } while (0)
103 #define NDR_TABLE_SIZE 128
104 #define NDR_TABLE_MASK 127
106 NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
107 0, 0, 0, 0, 0, 0, 0, 0,
108 0, 0, 0, 0, 0, 0, 0, 0,
109 /* 0x10 */
111 /* 0x11 */
112 NdrPointerMarshall, NdrPointerMarshall,
113 NdrPointerMarshall, NdrPointerMarshall,
114 /* 0x15 */
115 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
116 0, 0, 0,
117 NdrComplexStructMarshall,
118 /* 0x1b */
119 NdrConformantArrayMarshall, 0, 0, 0, 0, 0,
120 NdrComplexArrayMarshall,
121 /* 0x22 */
122 NdrConformantStringMarshall, 0, 0,
123 NdrConformantStringMarshall, 0, 0, 0, 0,
124 /* 0x2a */
125 0, 0, 0, 0, 0,
126 /* 0x2f */
127 NdrInterfacePointerMarshall,
128 /* 0xb0 */
129 0, 0, 0, 0,
130 NdrUserMarshalMarshall
132 NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
133 0, 0, 0, 0, 0, 0, 0, 0,
134 0, 0, 0, 0, 0, 0, 0, 0,
135 /* 0x10 */
137 /* 0x11 */
138 NdrPointerUnmarshall, NdrPointerUnmarshall,
139 NdrPointerUnmarshall, NdrPointerUnmarshall,
140 /* 0x15 */
141 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
142 0, 0, 0,
143 NdrComplexStructUnmarshall,
144 /* 0x1b */
145 NdrConformantArrayUnmarshall, 0, 0, 0, 0, 0,
146 NdrComplexArrayUnmarshall,
147 /* 0x22 */
148 NdrConformantStringUnmarshall, 0, 0,
149 NdrConformantStringUnmarshall, 0, 0, 0, 0,
150 /* 0x2a */
151 0, 0, 0, 0, 0,
152 /* 0x2f */
153 NdrInterfacePointerUnmarshall,
154 /* 0xb0 */
155 0, 0, 0, 0,
156 NdrUserMarshalUnmarshall
158 NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
159 0, 0, 0, 0, 0, 0, 0, 0,
160 0, 0, 0, 0, 0, 0, 0, 0,
161 /* 0x10 */
163 /* 0x11 */
164 NdrPointerBufferSize, NdrPointerBufferSize,
165 NdrPointerBufferSize, NdrPointerBufferSize,
166 /* 0x15 */
167 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
168 0, 0, 0,
169 NdrComplexStructBufferSize,
170 /* 0x1b */
171 NdrConformantArrayBufferSize, 0, 0, 0, 0, 0,
172 NdrComplexArrayBufferSize,
173 /* 0x22 */
174 NdrConformantStringBufferSize, 0, 0,
175 NdrConformantStringBufferSize, 0, 0, 0, 0,
176 /* 0x2a */
177 0, 0, 0, 0, 0,
178 /* 0x2f */
179 NdrInterfacePointerBufferSize,
180 /* 0xb0 */
181 0, 0, 0, 0,
182 NdrUserMarshalBufferSize
184 NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
185 0, 0, 0, 0, 0, 0, 0, 0,
186 0, 0, 0, 0, 0, 0, 0, 0,
187 /* 0x10 */
189 /* 0x11 */
190 NdrPointerMemorySize, NdrPointerMemorySize,
191 NdrPointerMemorySize, NdrPointerMemorySize,
192 /* 0x15 */
193 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
194 0, 0, 0,
195 NdrComplexStructMemorySize,
196 /* 0x1b */
197 NdrConformantArrayMemorySize, 0, 0, 0, 0, 0,
198 NdrComplexArrayMemorySize,
199 /* 0x22 */
200 NdrConformantStringMemorySize, 0, 0,
201 NdrConformantStringMemorySize, 0, 0, 0, 0,
202 /* 0x2a */
203 0, 0, 0, 0, 0,
204 /* 0x2f */
205 NdrInterfacePointerMemorySize,
206 /* 0xb0 */
207 0, 0, 0, 0,
208 NdrUserMarshalMemorySize
210 NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
211 0, 0, 0, 0, 0, 0, 0, 0,
212 0, 0, 0, 0, 0, 0, 0, 0,
213 /* 0x10 */
215 /* 0x11 */
216 NdrPointerFree, NdrPointerFree,
217 NdrPointerFree, NdrPointerFree,
218 /* 0x15 */
219 NdrSimpleStructFree, NdrSimpleStructFree,
220 0, 0, 0,
221 NdrComplexStructFree,
222 /* 0x1b */
223 NdrConformantArrayFree, 0, 0, 0, 0, 0,
224 NdrComplexArrayFree,
225 /* 0x22 */
226 0, 0, 0, 0, 0, 0, 0, 0,
227 /* 0x2a */
228 0, 0, 0, 0, 0,
229 /* 0x2f */
230 NdrInterfacePointerFree,
231 /* 0xb0 */
232 0, 0, 0, 0,
233 NdrUserMarshalFree
236 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
238 /* hmm, this is probably supposed to do more? */
239 return pStubMsg->pfnAllocate(len);
242 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
244 pStubMsg->pfnFree(Pointer);
247 PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
249 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
250 pStubMsg->Buffer += 4;
251 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
252 return pFormat+4;
255 PFORMAT_STRING ComputeConformance(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
256 PFORMAT_STRING pFormat, ULONG_PTR def)
258 BYTE dtype = pFormat[0] & 0xf;
259 DWORD ofs = (DWORD)pFormat[2] | ((DWORD)pFormat[3] << 8);
260 LPVOID ptr = NULL;
261 DWORD data = 0;
263 if (pFormat[0] == 0xff) {
264 /* null descriptor */
265 pStubMsg->MaxCount = def;
266 goto finish_conf;
269 switch (pFormat[0] & 0xf0) {
270 case RPC_FC_NORMAL_CONFORMANCE:
271 TRACE("normal conformance, ofs=%ld\n", ofs);
272 ptr = pMemory + ofs;
273 break;
274 case RPC_FC_POINTER_CONFORMANCE:
275 TRACE("pointer conformance, ofs=%ld\n", ofs);
276 ptr = pStubMsg->Memory + ofs;
277 break;
278 case RPC_FC_TOP_LEVEL_CONFORMANCE:
279 TRACE("toplevel conformance, ofs=%ld\n", ofs);
280 if (pStubMsg->StackTop) {
281 ptr = pStubMsg->StackTop + ofs;
283 else {
284 /* -Os mode, MaxCount is already set */
285 goto finish_conf;
287 break;
288 case RPC_FC_CONSTANT_CONFORMANCE:
289 data = ofs | ((DWORD)pFormat[1] << 16);
290 TRACE("constant conformance, val=%ld\n", data);
291 pStubMsg->MaxCount = data;
292 goto finish_conf;
293 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
294 FIXME("toplevel multidimensional conformance, ofs=%ld\n", ofs);
295 if (pStubMsg->StackTop) {
296 ptr = pStubMsg->StackTop + ofs;
298 else {
299 /* ? */
300 goto done_conf_grab;
302 break;
303 default:
304 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
307 switch (pFormat[1]) {
308 case RPC_FC_DEREFERENCE:
309 ptr = *(LPVOID*)ptr;
310 break;
311 case RPC_FC_CALLBACK:
312 /* ofs is index into StubDesc->apfnExprEval */
313 FIXME("handle callback\n");
314 goto finish_conf;
315 default:
316 break;
319 switch (dtype) {
320 case RPC_FC_LONG:
321 case RPC_FC_ULONG:
322 data = *(DWORD*)ptr;
323 break;
324 case RPC_FC_SHORT:
325 data = *(SHORT*)ptr;
326 break;
327 case RPC_FC_USHORT:
328 data = *(USHORT*)ptr;
329 break;
330 case RPC_FC_SMALL:
331 data = *(CHAR*)ptr;
332 break;
333 case RPC_FC_USMALL:
334 data = *(UCHAR*)ptr;
335 break;
336 default:
337 FIXME("unknown conformance data type %x\n", dtype);
338 goto done_conf_grab;
340 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
342 done_conf_grab:
343 switch (pFormat[1]) {
344 case 0: /* no op */
345 pStubMsg->MaxCount = data;
346 break;
347 case RPC_FC_DEREFERENCE:
348 /* already handled */
349 break;
350 default:
351 FIXME("unknown conformance op %d\n", pFormat[1]);
352 goto finish_conf;
355 finish_conf:
356 TRACE("resulting conformance is %ld\n", pStubMsg->MaxCount);
357 return pFormat+4;
362 * NdrConformantString:
364 * What MS calls a ConformantString is, in DCE terminology,
365 * a Varying-Conformant String.
367 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
368 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
369 * into unmarshalled string)
370 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
371 * [
372 * data: CHARTYPE[maxlen]
373 * ]
374 * ], where CHARTYPE is the appropriate character type (specified externally)
378 /***********************************************************************
379 * NdrConformantStringMarshall [RPCRT4.@]
381 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
382 unsigned char *pszMessage, PFORMAT_STRING pFormat)
384 unsigned long len, esize;
385 unsigned char *c;
387 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
389 assert(pFormat);
390 if (*pFormat == RPC_FC_C_CSTRING) {
391 TRACE("string=%s\n", debugstr_a(pszMessage));
392 len = strlen(pszMessage)+1;
393 esize = 1;
395 else if (*pFormat == RPC_FC_C_WSTRING) {
396 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
397 len = strlenW((LPWSTR)pszMessage)+1;
398 esize = 2;
400 else {
401 ERR("Unhandled string type: %#x\n", *pFormat);
402 /* FIXME: raise an exception. */
403 return NULL;
406 if (pFormat[1] != RPC_FC_PAD) {
407 FIXME("sized string format=%d\n", pFormat[1]);
410 assert( (pStubMsg->BufferLength >= (len*esize + 13)) && (pStubMsg->Buffer != NULL) );
412 c = pStubMsg->Buffer;
413 memset(c, 0, 12);
414 NDR_LOCAL_UINT32_WRITE(c, len); /* max length: strlen + 1 (for '\0') */
415 c += 8; /* offset: 0 */
416 NDR_LOCAL_UINT32_WRITE(c, len); /* actual length: (same) */
417 c += 4;
418 memcpy(c, pszMessage, len*esize); /* the string itself */
419 c += len*esize;
420 pStubMsg->Buffer = c;
422 STD_OVERFLOW_CHECK(pStubMsg);
424 /* success */
425 return NULL; /* is this always right? */
428 /***********************************************************************
429 * NdrConformantStringBufferSize [RPCRT4.@]
431 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
432 unsigned char* pMemory, PFORMAT_STRING pFormat)
434 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
436 assert(pFormat);
437 if (*pFormat == RPC_FC_C_CSTRING) {
438 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 1 octet for '\0' */
439 TRACE("string=%s\n", debugstr_a(pMemory));
440 pStubMsg->BufferLength += strlen(pMemory) + 13 + BUFFER_PARANOIA;
442 else if (*pFormat == RPC_FC_C_WSTRING) {
443 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 2 octets for L'\0' */
444 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
445 pStubMsg->BufferLength += strlenW((LPWSTR)pMemory)*2 + 14 + BUFFER_PARANOIA;
447 else {
448 ERR("Unhandled string type: %#x\n", *pFormat);
449 /* FIXME: raise an exception */
452 if (pFormat[1] != RPC_FC_PAD) {
453 FIXME("sized string format=%d\n", pFormat[1]);
457 /************************************************************************
458 * NdrConformantStringMemorySize [RPCRT4.@]
460 unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
461 PFORMAT_STRING pFormat )
463 unsigned long rslt = 0;
465 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
467 assert(pStubMsg && pFormat);
469 if (*pFormat == RPC_FC_C_CSTRING) {
470 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
472 else if (*pFormat == RPC_FC_C_WSTRING) {
473 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
475 else {
476 ERR("Unhandled string type: %#x\n", *pFormat);
477 /* FIXME: raise an exception */
480 if (pFormat[1] != RPC_FC_PAD) {
481 FIXME("sized string format=%d\n", pFormat[1]);
484 TRACE(" --> %lu\n", rslt);
485 return rslt;
488 /************************************************************************
489 * NdrConformantStringUnmarshall [RPCRT4.@]
491 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
492 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
494 unsigned long len, esize, ofs;
495 unsigned char *pMem;
497 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
498 pStubMsg, *ppMemory, pFormat, fMustAlloc);
500 assert(pFormat && ppMemory && pStubMsg);
502 pStubMsg->Buffer += 4;
503 ofs = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
504 pStubMsg->Buffer += 4;
505 len = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
506 pStubMsg->Buffer += 4;
508 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
509 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
510 else {
511 ERR("Unhandled string type: %#x\n", *pFormat);
512 /* FIXME: raise an exception */
513 esize = 0;
516 if (pFormat[1] != RPC_FC_PAD) {
517 FIXME("sized string format=%d\n", pFormat[1]);
520 if (fMustAlloc) {
521 *ppMemory = NdrAllocate(pStubMsg, len*esize + BUFFER_PARANOIA);
522 } else {
523 if (pStubMsg->ReuseBuffer && !*ppMemory)
524 /* for servers, we may just point straight into the RPC buffer, I think
525 * (I guess that's what MS does since MIDL code doesn't try to free) */
526 *ppMemory = pStubMsg->Buffer - ofs*esize;
527 /* for clients, memory should be provided by caller */
530 pMem = *ppMemory + ofs*esize;
532 if (pMem != pStubMsg->Buffer)
533 memcpy(pMem, pStubMsg->Buffer, len*esize);
535 pStubMsg->Buffer += len*esize;
537 if (*pFormat == RPC_FC_C_CSTRING) {
538 TRACE("string=%s\n", debugstr_a(pMem));
540 else if (*pFormat == RPC_FC_C_WSTRING) {
541 TRACE("string=%s\n", debugstr_w((LPWSTR)pMem));
544 return NULL; /* FIXME: is this always right? */
547 /***********************************************************************
548 * PointerMarshall
550 void WINAPI PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
551 unsigned char *Buffer,
552 unsigned char *Pointer,
553 PFORMAT_STRING pFormat)
555 unsigned type = pFormat[0], attr = pFormat[1];
556 PFORMAT_STRING desc;
557 NDR_MARSHALL m;
559 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
560 TRACE("type=%d, attr=%d\n", type, attr);
561 pFormat += 2;
562 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
563 else desc = pFormat + *(SHORT*)pFormat;
564 if (attr & RPC_FC_P_DEREF) {
565 Pointer = *(unsigned char**)Pointer;
566 TRACE("deref => %p\n", Pointer);
569 *(LPVOID*)Buffer = 0;
571 switch (type) {
572 case RPC_FC_RP: /* ref pointer (always non-null) */
573 break;
574 default:
575 FIXME("unhandled ptr type=%02x\n", type);
578 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
579 if (m) m(pStubMsg, Pointer, desc);
580 else FIXME("no marshaller for data type=%02x\n", *desc);
582 STD_OVERFLOW_CHECK(pStubMsg);
585 /***********************************************************************
586 * PointerUnmarshall
588 void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
589 unsigned char *Buffer,
590 unsigned char **pPointer,
591 PFORMAT_STRING pFormat,
592 unsigned char fMustAlloc)
594 unsigned type = pFormat[0], attr = pFormat[1];
595 PFORMAT_STRING desc;
596 NDR_UNMARSHALL m;
598 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
599 TRACE("type=%d, attr=%d\n", type, attr);
600 pFormat += 2;
601 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
602 else desc = pFormat + *(SHORT*)pFormat;
603 if (attr & RPC_FC_P_DEREF) {
604 pPointer = *(unsigned char***)pPointer;
605 TRACE("deref => %p\n", pPointer);
608 switch (type) {
609 case RPC_FC_RP: /* ref pointer (always non-null) */
610 break;
611 default:
612 FIXME("unhandled ptr type=%02x\n", type);
615 *pPointer = NULL;
617 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
618 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
619 else FIXME("no unmarshaller for data type=%02x\n", *desc);
620 TRACE("pointer=%p\n", *pPointer);
623 /***********************************************************************
624 * PointerBufferSize
626 void WINAPI PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
627 unsigned char *Pointer,
628 PFORMAT_STRING pFormat)
630 unsigned type = pFormat[0], attr = pFormat[1];
631 PFORMAT_STRING desc;
632 NDR_BUFFERSIZE m;
634 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
635 TRACE("type=%d, attr=%d\n", type, attr);
636 pFormat += 2;
637 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
638 else desc = pFormat + *(SHORT*)pFormat;
639 if (attr & RPC_FC_P_DEREF) {
640 Pointer = *(unsigned char**)Pointer;
641 TRACE("deref => %p\n", Pointer);
644 switch (type) {
645 case RPC_FC_RP: /* ref pointer (always non-null) */
646 break;
647 default:
648 FIXME("unhandled ptr type=%02x\n", type);
651 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
652 if (m) m(pStubMsg, Pointer, desc);
653 else FIXME("no buffersizer for data type=%02x\n", *desc);
656 /***********************************************************************
657 * PointerMemorySize [RPCRT4.@]
659 unsigned long WINAPI PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
660 unsigned char *Buffer,
661 PFORMAT_STRING pFormat)
663 unsigned type = pFormat[0], attr = pFormat[1];
664 PFORMAT_STRING desc;
665 NDR_MEMORYSIZE m;
667 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
668 TRACE("type=%d, attr=%d\n", type, attr);
669 pFormat += 2;
670 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
671 else desc = pFormat + *(SHORT*)pFormat;
672 if (attr & RPC_FC_P_DEREF) {
673 TRACE("deref\n");
676 switch (type) {
677 case RPC_FC_RP: /* ref pointer (always non-null) */
678 break;
679 default:
680 FIXME("unhandled ptr type=%02x\n", type);
683 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
684 if (m) m(pStubMsg, desc);
685 else FIXME("no memorysizer for data type=%02x\n", *desc);
687 return 0;
690 /***********************************************************************
691 * PointerFree [RPCRT4.@]
693 void WINAPI PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
694 unsigned char *Pointer,
695 PFORMAT_STRING pFormat)
697 unsigned type = pFormat[0], attr = pFormat[1];
698 PFORMAT_STRING desc;
699 NDR_FREE m;
701 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
702 TRACE("type=%d, attr=%d\n", type, attr);
703 if (attr & RPC_FC_P_DONTFREE) return;
704 pFormat += 2;
705 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
706 else desc = pFormat + *(SHORT*)pFormat;
707 if (attr & RPC_FC_P_DEREF) {
708 Pointer = *(unsigned char**)Pointer;
709 TRACE("deref => %p\n", Pointer);
712 if (!Pointer) return;
714 m = NdrFreer[*desc & NDR_TABLE_MASK];
715 if (m) m(pStubMsg, Pointer, desc);
717 /* hmm... is this sensible?
718 * perhaps we should check if the memory comes from NdrAllocate,
719 * and deallocate only if so - checking if the pointer is between
720 * BufferStart and BufferEnd is probably no good since the buffer
721 * may be reallocated when the server wants to marshal the reply */
722 switch (*desc) {
723 case RPC_FC_BOGUS_STRUCT:
724 case RPC_FC_BOGUS_ARRAY:
725 case RPC_FC_USER_MARSHAL:
726 break;
727 default:
728 FIXME("unhandled data type=%02x\n", *desc);
729 case RPC_FC_CARRAY:
730 case RPC_FC_C_CSTRING:
731 case RPC_FC_C_WSTRING:
732 if (pStubMsg->ReuseBuffer) goto notfree;
733 break;
734 case RPC_FC_IP:
735 goto notfree;
738 if (attr & RPC_FC_P_ONSTACK) {
739 TRACE("not freeing stack ptr %p\n", Pointer);
740 return;
742 TRACE("freeing %p\n", Pointer);
743 NdrFree(pStubMsg, Pointer);
744 return;
745 notfree:
746 TRACE("not freeing %p\n", Pointer);
749 /***********************************************************************
750 * EmbeddedPointerMarshall
752 unsigned char * WINAPI EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
753 unsigned char *pMemory,
754 PFORMAT_STRING pFormat)
756 unsigned char *Mark = pStubMsg->BufferMark;
757 unsigned long Offset = pStubMsg->Offset;
758 unsigned ofs, rep, count, stride, xofs;
760 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
762 if (*pFormat != RPC_FC_PP) return NULL;
763 pFormat += 2;
765 while (pFormat[0] != RPC_FC_END) {
766 switch (pFormat[0]) {
767 default:
768 FIXME("unknown repeat type %d\n", pFormat[0]);
769 case RPC_FC_NO_REPEAT:
770 rep = 1;
771 stride = 0;
772 ofs = 0;
773 count = 1;
774 xofs = 0;
775 pFormat += 2;
776 break;
777 case RPC_FC_FIXED_REPEAT:
778 rep = *(WORD*)&pFormat[2];
779 stride = *(WORD*)&pFormat[4];
780 ofs = *(WORD*)&pFormat[6];
781 count = *(WORD*)&pFormat[8];
782 xofs = 0;
783 pFormat += 10;
784 break;
785 case RPC_FC_VARIABLE_REPEAT:
786 rep = pStubMsg->MaxCount;
787 stride = *(WORD*)&pFormat[2];
788 ofs = *(WORD*)&pFormat[4];
789 count = *(WORD*)&pFormat[6];
790 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
791 pFormat += 8;
792 break;
794 /* ofs doesn't seem to matter in this context */
795 while (rep) {
796 PFORMAT_STRING info = pFormat;
797 unsigned char *membase = pMemory + xofs;
798 unsigned u;
799 for (u=0; u<count; u++,info+=8) {
800 unsigned char *memptr = membase + *(SHORT*)&info[0];
801 unsigned char *bufptr = Mark + *(SHORT*)&info[2];
802 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
804 rep--;
806 pFormat += 8 * count;
809 STD_OVERFLOW_CHECK(pStubMsg);
811 return NULL;
814 /***********************************************************************
815 * EmbeddedPointerUnmarshall
817 unsigned char * WINAPI EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
818 unsigned char **ppMemory,
819 PFORMAT_STRING pFormat,
820 unsigned char fMustAlloc)
822 unsigned char *Mark = pStubMsg->BufferMark;
823 unsigned long Offset = pStubMsg->Offset;
824 unsigned ofs, rep, count, stride, xofs;
826 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
828 if (*pFormat != RPC_FC_PP) return NULL;
829 pFormat += 2;
831 while (pFormat[0] != RPC_FC_END) {
832 switch (pFormat[0]) {
833 default:
834 FIXME("unknown repeat type %d\n", pFormat[0]);
835 case RPC_FC_NO_REPEAT:
836 rep = 1;
837 stride = 0;
838 ofs = 0;
839 count = 1;
840 xofs = 0;
841 pFormat += 2;
842 break;
843 case RPC_FC_FIXED_REPEAT:
844 rep = *(WORD*)&pFormat[2];
845 stride = *(WORD*)&pFormat[4];
846 ofs = *(WORD*)&pFormat[6];
847 count = *(WORD*)&pFormat[8];
848 xofs = 0;
849 pFormat += 10;
850 break;
851 case RPC_FC_VARIABLE_REPEAT:
852 rep = pStubMsg->MaxCount;
853 stride = *(WORD*)&pFormat[2];
854 ofs = *(WORD*)&pFormat[4];
855 count = *(WORD*)&pFormat[6];
856 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
857 pFormat += 8;
858 break;
860 /* ofs doesn't seem to matter in this context */
861 while (rep) {
862 PFORMAT_STRING info = pFormat;
863 unsigned char *membase = *ppMemory + xofs;
864 unsigned u;
865 for (u=0; u<count; u++,info+=8) {
866 unsigned char *memptr = membase + *(SHORT*)&info[0];
867 unsigned char *bufptr = Mark + *(SHORT*)&info[2];
868 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, fMustAlloc);
870 rep--;
872 pFormat += 8 * count;
875 return NULL;
878 /***********************************************************************
879 * EmbeddedPointerBufferSize
881 void WINAPI EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
882 unsigned char *pMemory,
883 PFORMAT_STRING pFormat)
885 unsigned long Offset = pStubMsg->Offset;
886 unsigned ofs, rep, count, stride, xofs;
888 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
889 if (*pFormat != RPC_FC_PP) return;
890 pFormat += 2;
892 while (pFormat[0] != RPC_FC_END) {
893 switch (pFormat[0]) {
894 default:
895 FIXME("unknown repeat type %d\n", pFormat[0]);
896 case RPC_FC_NO_REPEAT:
897 rep = 1;
898 stride = 0;
899 ofs = 0;
900 count = 1;
901 xofs = 0;
902 pFormat += 2;
903 break;
904 case RPC_FC_FIXED_REPEAT:
905 rep = *(WORD*)&pFormat[2];
906 stride = *(WORD*)&pFormat[4];
907 ofs = *(WORD*)&pFormat[6];
908 count = *(WORD*)&pFormat[8];
909 xofs = 0;
910 pFormat += 10;
911 break;
912 case RPC_FC_VARIABLE_REPEAT:
913 rep = pStubMsg->MaxCount;
914 stride = *(WORD*)&pFormat[2];
915 ofs = *(WORD*)&pFormat[4];
916 count = *(WORD*)&pFormat[6];
917 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
918 pFormat += 8;
919 break;
921 /* ofs doesn't seem to matter in this context */
922 while (rep) {
923 PFORMAT_STRING info = pFormat;
924 unsigned char *membase = pMemory + xofs;
925 unsigned u;
926 for (u=0; u<count; u++,info+=8) {
927 unsigned char *memptr = membase + *(SHORT*)&info[0];
928 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
930 rep--;
932 pFormat += 8 * count;
936 /***********************************************************************
937 * EmbeddedPointerMemorySize
939 unsigned long WINAPI EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
940 PFORMAT_STRING pFormat)
942 unsigned long Offset = pStubMsg->Offset;
943 unsigned char *Mark = pStubMsg->BufferMark;
944 unsigned ofs, rep, count, stride, xofs;
946 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
947 if (*pFormat != RPC_FC_PP) return 0;
948 pFormat += 2;
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 = *(WORD*)&pFormat[2];
964 stride = *(WORD*)&pFormat[4];
965 ofs = *(WORD*)&pFormat[6];
966 count = *(WORD*)&pFormat[8];
967 xofs = 0;
968 pFormat += 10;
969 break;
970 case RPC_FC_VARIABLE_REPEAT:
971 rep = pStubMsg->MaxCount;
972 stride = *(WORD*)&pFormat[2];
973 ofs = *(WORD*)&pFormat[4];
974 count = *(WORD*)&pFormat[6];
975 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
976 pFormat += 8;
977 break;
979 /* ofs doesn't seem to matter in this context */
980 while (rep) {
981 PFORMAT_STRING info = pFormat;
982 unsigned u;
983 for (u=0; u<count; u++,info+=8) {
984 unsigned char *bufptr = Mark + *(SHORT*)&info[2];
985 PointerMemorySize(pStubMsg, bufptr, info+4);
987 rep--;
989 pFormat += 8 * count;
992 return 0;
995 /***********************************************************************
996 * EmbeddedPointerFree
998 void WINAPI EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
999 unsigned char *pMemory,
1000 PFORMAT_STRING pFormat)
1002 unsigned long Offset = pStubMsg->Offset;
1003 unsigned ofs, rep, count, stride, xofs;
1005 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1006 if (*pFormat != RPC_FC_PP) return;
1007 pFormat += 2;
1009 while (pFormat[0] != RPC_FC_END) {
1010 switch (pFormat[0]) {
1011 default:
1012 FIXME("unknown repeat type %d\n", pFormat[0]);
1013 case RPC_FC_NO_REPEAT:
1014 rep = 1;
1015 stride = 0;
1016 ofs = 0;
1017 count = 1;
1018 xofs = 0;
1019 pFormat += 2;
1020 break;
1021 case RPC_FC_FIXED_REPEAT:
1022 rep = *(WORD*)&pFormat[2];
1023 stride = *(WORD*)&pFormat[4];
1024 ofs = *(WORD*)&pFormat[6];
1025 count = *(WORD*)&pFormat[8];
1026 xofs = 0;
1027 pFormat += 10;
1028 break;
1029 case RPC_FC_VARIABLE_REPEAT:
1030 rep = pStubMsg->MaxCount;
1031 stride = *(WORD*)&pFormat[2];
1032 ofs = *(WORD*)&pFormat[4];
1033 count = *(WORD*)&pFormat[6];
1034 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1035 pFormat += 8;
1036 break;
1038 /* ofs doesn't seem to matter in this context */
1039 while (rep) {
1040 PFORMAT_STRING info = pFormat;
1041 unsigned char *membase = pMemory + xofs;
1042 unsigned u;
1043 for (u=0; u<count; u++,info+=8) {
1044 unsigned char *memptr = membase + *(SHORT*)&info[0];
1045 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1047 rep--;
1049 pFormat += 8 * count;
1053 /***********************************************************************
1054 * NdrPointerMarshall [RPCRT4.@]
1056 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1057 unsigned char *pMemory,
1058 PFORMAT_STRING pFormat)
1060 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1062 pStubMsg->BufferMark = pStubMsg->Buffer;
1063 PointerMarshall(pStubMsg, pStubMsg->Buffer, pMemory, pFormat);
1064 pStubMsg->Buffer += 4;
1066 STD_OVERFLOW_CHECK(pStubMsg);
1068 return NULL;
1071 /***********************************************************************
1072 * NdrPointerUnmarshall [RPCRT4.@]
1074 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1075 unsigned char **ppMemory,
1076 PFORMAT_STRING pFormat,
1077 unsigned char fMustAlloc)
1079 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1081 pStubMsg->BufferMark = pStubMsg->Buffer;
1082 PointerUnmarshall(pStubMsg, pStubMsg->Buffer, ppMemory, pFormat, fMustAlloc);
1083 pStubMsg->Buffer += 4;
1085 return NULL;
1088 /***********************************************************************
1089 * NdrPointerBufferSize [RPCRT4.@]
1091 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1092 unsigned char *pMemory,
1093 PFORMAT_STRING pFormat)
1095 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1096 pStubMsg->BufferLength += 4;
1097 PointerBufferSize(pStubMsg, pMemory, pFormat);
1100 /***********************************************************************
1101 * NdrPointerMemorySize [RPCRT4.@]
1103 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1104 PFORMAT_STRING pFormat)
1106 /* unsigned size = *(LPWORD)(pFormat+2); */
1107 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1108 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1109 return 0;
1112 /***********************************************************************
1113 * NdrPointerFree [RPCRT4.@]
1115 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1116 unsigned char *pMemory,
1117 PFORMAT_STRING pFormat)
1119 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1120 PointerFree(pStubMsg, pMemory, pFormat);
1123 /***********************************************************************
1124 * NdrSimpleStructMarshall [RPCRT4.@]
1126 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1127 unsigned char *pMemory,
1128 PFORMAT_STRING pFormat)
1130 unsigned size = *(LPWORD)(pFormat+2);
1131 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1133 memcpy(pStubMsg->Buffer, pMemory, size);
1134 pStubMsg->BufferMark = pStubMsg->Buffer;
1135 pStubMsg->Buffer += size;
1137 if (pFormat[0] != RPC_FC_STRUCT)
1138 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1140 STD_OVERFLOW_CHECK(pStubMsg);
1142 return NULL;
1145 /***********************************************************************
1146 * NdrSimpleStructUnmarshall [RPCRT4.@]
1148 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1149 unsigned char **ppMemory,
1150 PFORMAT_STRING pFormat,
1151 unsigned char fMustAlloc)
1153 unsigned size = *(LPWORD)(pFormat+2);
1154 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1156 if (fMustAlloc) {
1157 *ppMemory = NdrAllocate(pStubMsg, size);
1158 memcpy(*ppMemory, pStubMsg->Buffer, size);
1159 } else {
1160 if (pStubMsg->ReuseBuffer && !*ppMemory)
1161 /* for servers, we may just point straight into the RPC buffer, I think
1162 * (I guess that's what MS does since MIDL code doesn't try to free) */
1163 *ppMemory = pStubMsg->Buffer;
1164 else
1165 /* for clients, memory should be provided by caller */
1166 memcpy(*ppMemory, pStubMsg->Buffer, size);
1169 pStubMsg->BufferMark = pStubMsg->Buffer;
1170 pStubMsg->Buffer += size;
1172 if (pFormat[0] != RPC_FC_STRUCT)
1173 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1175 return NULL;
1179 /***********************************************************************
1180 * NdrSimpleStructUnmarshall [RPCRT4.@]
1182 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1183 unsigned char FormatChar )
1185 FIXME("stub\n");
1189 /***********************************************************************
1190 * NdrSimpleStructUnmarshall [RPCRT4.@]
1192 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1193 unsigned char FormatChar )
1195 FIXME("stub\n");
1199 /***********************************************************************
1200 * NdrSimpleStructBufferSize [RPCRT4.@]
1202 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1203 unsigned char *pMemory,
1204 PFORMAT_STRING pFormat)
1206 unsigned size = *(LPWORD)(pFormat+2);
1207 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1208 pStubMsg->BufferLength += size;
1209 if (pFormat[0] != RPC_FC_STRUCT)
1210 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1213 /***********************************************************************
1214 * NdrSimpleStructMemorySize [RPCRT4.@]
1216 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1217 PFORMAT_STRING pFormat)
1219 /* unsigned size = *(LPWORD)(pFormat+2); */
1220 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1221 if (pFormat[0] != RPC_FC_STRUCT)
1222 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1223 return 0;
1226 /***********************************************************************
1227 * NdrSimpleStructFree [RPCRT4.@]
1229 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1230 unsigned char *pMemory,
1231 PFORMAT_STRING pFormat)
1233 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1234 if (pFormat[0] != RPC_FC_STRUCT)
1235 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1239 unsigned long WINAPI EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1240 PFORMAT_STRING pFormat)
1242 switch (*pFormat) {
1243 case RPC_FC_STRUCT:
1244 case RPC_FC_PSTRUCT:
1245 case RPC_FC_CSTRUCT:
1246 case RPC_FC_BOGUS_STRUCT:
1247 return *(WORD*)&pFormat[2];
1248 case RPC_FC_USER_MARSHAL:
1249 return *(WORD*)&pFormat[4];
1250 default:
1251 FIXME("unhandled embedded type %02x\n", *pFormat);
1253 return 0;
1257 unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1258 unsigned char *pMemory,
1259 PFORMAT_STRING pFormat,
1260 PFORMAT_STRING pPointer)
1262 PFORMAT_STRING desc;
1263 NDR_MARSHALL m;
1264 unsigned long size;
1266 while (*pFormat != RPC_FC_END) {
1267 switch (*pFormat) {
1268 case RPC_FC_SHORT:
1269 case RPC_FC_USHORT:
1270 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1271 memcpy(pStubMsg->Buffer, pMemory, 2);
1272 pStubMsg->Buffer += 2;
1273 pMemory += 2;
1274 break;
1275 case RPC_FC_LONG:
1276 case RPC_FC_ULONG:
1277 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1278 memcpy(pStubMsg->Buffer, pMemory, 4);
1279 pStubMsg->Buffer += 4;
1280 pMemory += 4;
1281 break;
1282 case RPC_FC_POINTER:
1283 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1284 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1285 pPointer += 4;
1286 pMemory += 4;
1287 break;
1288 case RPC_FC_ALIGNM4:
1289 ALIGN_POINTER(pMemory, 3);
1290 break;
1291 case RPC_FC_ALIGNM8:
1292 ALIGN_POINTER(pMemory, 7);
1293 break;
1294 case RPC_FC_EMBEDDED_COMPLEX:
1295 pMemory += pFormat[1];
1296 pFormat += 2;
1297 desc = pFormat + *(SHORT*)pFormat;
1298 size = EmbeddedComplexSize(pStubMsg, desc);
1299 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1300 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1301 if (m) m(pStubMsg, pMemory, desc);
1302 else FIXME("no marshaller for embedded type %02x\n", *desc);
1303 pMemory += size;
1304 pFormat += 2;
1305 continue;
1306 case RPC_FC_PAD:
1307 break;
1308 default:
1309 FIXME("unhandled format %02x\n", *pFormat);
1311 pFormat++;
1314 return pMemory;
1317 unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1318 unsigned char *pMemory,
1319 PFORMAT_STRING pFormat,
1320 PFORMAT_STRING pPointer,
1321 unsigned char fMustAlloc)
1323 PFORMAT_STRING desc;
1324 NDR_UNMARSHALL m;
1325 unsigned long size;
1327 while (*pFormat != RPC_FC_END) {
1328 switch (*pFormat) {
1329 case RPC_FC_SHORT:
1330 case RPC_FC_USHORT:
1331 memcpy(pMemory, pStubMsg->Buffer, 2);
1332 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1333 pStubMsg->Buffer += 2;
1334 pMemory += 2;
1335 break;
1336 case RPC_FC_LONG:
1337 case RPC_FC_ULONG:
1338 memcpy(pMemory, pStubMsg->Buffer, 4);
1339 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1340 pStubMsg->Buffer += 4;
1341 pMemory += 4;
1342 break;
1343 case RPC_FC_POINTER:
1344 *(unsigned char**)pMemory = NULL;
1345 TRACE("pointer => %p\n", pMemory);
1346 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, fMustAlloc);
1347 pPointer += 4;
1348 pMemory += 4;
1349 break;
1350 case RPC_FC_ALIGNM4:
1351 ALIGN_POINTER(pMemory, 3);
1352 break;
1353 case RPC_FC_ALIGNM8:
1354 ALIGN_POINTER(pMemory, 7);
1355 break;
1356 case RPC_FC_EMBEDDED_COMPLEX:
1357 pMemory += pFormat[1];
1358 pFormat += 2;
1359 desc = pFormat + *(SHORT*)pFormat;
1360 size = EmbeddedComplexSize(pStubMsg, desc);
1361 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1362 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1363 memset(pMemory, 0, size); /* just in case */
1364 if (m) m(pStubMsg, &pMemory, desc, fMustAlloc);
1365 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1366 pMemory += size;
1367 pFormat += 2;
1368 continue;
1369 case RPC_FC_PAD:
1370 break;
1371 default:
1372 FIXME("unhandled format %d\n", *pFormat);
1374 pFormat++;
1377 return pMemory;
1380 unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1381 unsigned char *pMemory,
1382 PFORMAT_STRING pFormat,
1383 PFORMAT_STRING pPointer)
1385 PFORMAT_STRING desc;
1386 NDR_BUFFERSIZE m;
1387 unsigned long size;
1389 while (*pFormat != RPC_FC_END) {
1390 switch (*pFormat) {
1391 case RPC_FC_SHORT:
1392 case RPC_FC_USHORT:
1393 pStubMsg->BufferLength += 2;
1394 pMemory += 2;
1395 break;
1396 case RPC_FC_LONG:
1397 case RPC_FC_ULONG:
1398 pStubMsg->BufferLength += 4;
1399 pMemory += 4;
1400 break;
1401 case RPC_FC_POINTER:
1402 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1403 pPointer += 4;
1404 pMemory += 4;
1405 break;
1406 case RPC_FC_ALIGNM4:
1407 ALIGN_POINTER(pMemory, 3);
1408 break;
1409 case RPC_FC_ALIGNM8:
1410 ALIGN_POINTER(pMemory, 7);
1411 break;
1412 case RPC_FC_EMBEDDED_COMPLEX:
1413 pMemory += pFormat[1];
1414 pFormat += 2;
1415 desc = pFormat + *(SHORT*)pFormat;
1416 size = EmbeddedComplexSize(pStubMsg, desc);
1417 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1418 if (m) m(pStubMsg, pMemory, desc);
1419 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1420 pMemory += size;
1421 pFormat += 2;
1422 continue;
1423 case RPC_FC_PAD:
1424 break;
1425 default:
1426 FIXME("unhandled format %d\n", *pFormat);
1428 pFormat++;
1431 return pMemory;
1434 unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1435 unsigned char *pMemory,
1436 PFORMAT_STRING pFormat,
1437 PFORMAT_STRING pPointer)
1439 PFORMAT_STRING desc;
1440 NDR_FREE m;
1441 unsigned long size;
1443 while (*pFormat != RPC_FC_END) {
1444 switch (*pFormat) {
1445 case RPC_FC_SHORT:
1446 case RPC_FC_USHORT:
1447 pMemory += 2;
1448 break;
1449 case RPC_FC_LONG:
1450 case RPC_FC_ULONG:
1451 pMemory += 4;
1452 break;
1453 case RPC_FC_POINTER:
1454 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1455 pPointer += 4;
1456 pMemory += 4;
1457 break;
1458 case RPC_FC_ALIGNM4:
1459 ALIGN_POINTER(pMemory, 3);
1460 break;
1461 case RPC_FC_ALIGNM8:
1462 ALIGN_POINTER(pMemory, 7);
1463 break;
1464 case RPC_FC_EMBEDDED_COMPLEX:
1465 pMemory += pFormat[1];
1466 pFormat += 2;
1467 desc = pFormat + *(SHORT*)pFormat;
1468 size = EmbeddedComplexSize(pStubMsg, desc);
1469 m = NdrFreer[*desc & NDR_TABLE_MASK];
1470 if (m) m(pStubMsg, pMemory, desc);
1471 else FIXME("no freer for embedded type %02x\n", *desc);
1472 pMemory += size;
1473 pFormat += 2;
1474 continue;
1475 case RPC_FC_PAD:
1476 break;
1477 default:
1478 FIXME("unhandled format %d\n", *pFormat);
1480 pFormat++;
1483 return pMemory;
1486 unsigned long WINAPI ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
1487 PFORMAT_STRING pFormat)
1489 PFORMAT_STRING desc;
1490 unsigned long size = 0;
1492 while (*pFormat != RPC_FC_END) {
1493 switch (*pFormat) {
1494 case RPC_FC_SHORT:
1495 case RPC_FC_USHORT:
1496 size += 2;
1497 break;
1498 case RPC_FC_LONG:
1499 case RPC_FC_ULONG:
1500 size += 4;
1501 break;
1502 case RPC_FC_POINTER:
1503 size += 4;
1504 break;
1505 case RPC_FC_ALIGNM4:
1506 ALIGN_LENGTH(size, 3);
1507 break;
1508 case RPC_FC_ALIGNM8:
1509 ALIGN_LENGTH(size, 7);
1510 break;
1511 case RPC_FC_EMBEDDED_COMPLEX:
1512 size += pFormat[1];
1513 pFormat += 2;
1514 desc = pFormat + *(SHORT*)pFormat;
1515 size += EmbeddedComplexSize(pStubMsg, desc);
1516 pFormat += 2;
1517 continue;
1518 case RPC_FC_PAD:
1519 break;
1520 default:
1521 FIXME("unhandled format %d\n", *pFormat);
1523 pFormat++;
1526 return size;
1529 /***********************************************************************
1530 * NdrComplexStructMarshall [RPCRT4.@]
1532 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1533 unsigned char *pMemory,
1534 PFORMAT_STRING pFormat)
1536 PFORMAT_STRING conf_array = NULL;
1537 PFORMAT_STRING pointer_desc = NULL;
1538 unsigned char *OldMemory = pStubMsg->Memory;
1540 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1542 pFormat += 4;
1543 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1544 pFormat += 2;
1545 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1546 pFormat += 2;
1548 pStubMsg->Memory = pMemory;
1550 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
1552 if (conf_array)
1553 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
1555 pStubMsg->Memory = OldMemory;
1557 STD_OVERFLOW_CHECK(pStubMsg);
1559 return NULL;
1562 /***********************************************************************
1563 * NdrComplexStructUnmarshall [RPCRT4.@]
1565 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1566 unsigned char **ppMemory,
1567 PFORMAT_STRING pFormat,
1568 unsigned char fMustAlloc)
1570 unsigned size = *(LPWORD)(pFormat+2);
1571 PFORMAT_STRING conf_array = NULL;
1572 PFORMAT_STRING pointer_desc = NULL;
1573 unsigned char *pMemory;
1575 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1577 if (fMustAlloc || !*ppMemory)
1578 *ppMemory = NdrAllocate(pStubMsg, size);
1580 pFormat += 4;
1581 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1582 pFormat += 2;
1583 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1584 pFormat += 2;
1586 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
1588 if (conf_array)
1589 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
1591 return NULL;
1594 /***********************************************************************
1595 * NdrComplexStructBufferSize [RPCRT4.@]
1597 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1598 unsigned char *pMemory,
1599 PFORMAT_STRING pFormat)
1601 PFORMAT_STRING conf_array = NULL;
1602 PFORMAT_STRING pointer_desc = NULL;
1603 unsigned char *OldMemory = pStubMsg->Memory;
1605 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1607 pFormat += 4;
1608 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1609 pFormat += 2;
1610 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1611 pFormat += 2;
1613 pStubMsg->Memory = pMemory;
1615 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
1617 if (conf_array)
1618 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
1620 pStubMsg->Memory = OldMemory;
1623 /***********************************************************************
1624 * NdrComplexStructMemorySize [RPCRT4.@]
1626 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1627 PFORMAT_STRING pFormat)
1629 /* unsigned size = *(LPWORD)(pFormat+2); */
1630 PFORMAT_STRING conf_array = NULL;
1631 PFORMAT_STRING pointer_desc = NULL;
1633 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1635 pFormat += 4;
1636 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1637 pFormat += 2;
1638 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1639 pFormat += 2;
1641 return 0;
1644 /***********************************************************************
1645 * NdrComplexStructFree [RPCRT4.@]
1647 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1648 unsigned char *pMemory,
1649 PFORMAT_STRING pFormat)
1651 PFORMAT_STRING conf_array = NULL;
1652 PFORMAT_STRING pointer_desc = NULL;
1653 unsigned char *OldMemory = pStubMsg->Memory;
1655 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1657 pFormat += 4;
1658 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1659 pFormat += 2;
1660 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1661 pFormat += 2;
1663 pStubMsg->Memory = pMemory;
1665 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
1667 if (conf_array)
1668 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
1670 pStubMsg->Memory = OldMemory;
1673 /***********************************************************************
1674 * NdrConformantArrayMarshall [RPCRT4.@]
1676 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1677 unsigned char *pMemory,
1678 PFORMAT_STRING pFormat)
1680 DWORD size = 0, esize = *(LPWORD)(pFormat+2);
1681 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1682 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1684 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1685 size = pStubMsg->MaxCount;
1687 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
1688 pStubMsg->Buffer += 4;
1690 memcpy(pStubMsg->Buffer, pMemory, size*esize);
1691 pStubMsg->BufferMark = pStubMsg->Buffer;
1692 pStubMsg->Buffer += size*esize;
1694 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1696 STD_OVERFLOW_CHECK(pStubMsg);
1698 return NULL;
1701 /***********************************************************************
1702 * NdrConformantArrayUnmarshall [RPCRT4.@]
1704 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1705 unsigned char **ppMemory,
1706 PFORMAT_STRING pFormat,
1707 unsigned char fMustAlloc)
1709 DWORD size = 0, esize = *(LPWORD)(pFormat+2);
1710 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1711 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1713 pFormat = ReadConformance(pStubMsg, pFormat+4);
1714 size = pStubMsg->MaxCount;
1716 if (fMustAlloc) {
1717 *ppMemory = NdrAllocate(pStubMsg, size*esize);
1718 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
1719 } else {
1720 if (pStubMsg->ReuseBuffer && !*ppMemory)
1721 /* for servers, we may just point straight into the RPC buffer, I think
1722 * (I guess that's what MS does since MIDL code doesn't try to free) */
1723 *ppMemory = pStubMsg->Buffer;
1724 else
1725 /* for clients, memory should be provided by caller */
1726 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
1729 pStubMsg->BufferMark = pStubMsg->Buffer;
1730 pStubMsg->Buffer += size*esize;
1732 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
1734 return NULL;
1737 /***********************************************************************
1738 * NdrConformantArrayBufferSize [RPCRT4.@]
1740 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1741 unsigned char *pMemory,
1742 PFORMAT_STRING pFormat)
1744 DWORD size = 0, esize = *(LPWORD)(pFormat+2);
1745 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1746 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1748 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1749 size = pStubMsg->MaxCount;
1751 pStubMsg->BufferLength += size*esize;
1753 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1756 /***********************************************************************
1757 * NdrConformantArrayMemorySize [RPCRT4.@]
1759 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1760 PFORMAT_STRING pFormat)
1762 DWORD size = 0;
1763 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1764 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1766 pFormat = ReadConformance(pStubMsg, pFormat+4);
1767 size = pStubMsg->MaxCount;
1769 EmbeddedPointerMemorySize(pStubMsg, pFormat);
1771 return 0;
1774 /***********************************************************************
1775 * NdrConformantArrayFree [RPCRT4.@]
1777 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
1778 unsigned char *pMemory,
1779 PFORMAT_STRING pFormat)
1781 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1782 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1784 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
1788 /***********************************************************************
1789 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
1791 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
1792 unsigned char* pMemory,
1793 PFORMAT_STRING pFormat )
1795 FIXME( "stub\n" );
1796 return NULL;
1800 /***********************************************************************
1801 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
1803 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
1804 unsigned char** ppMemory,
1805 PFORMAT_STRING pFormat,
1806 unsigned char fMustAlloc )
1808 FIXME( "stub\n" );
1809 return NULL;
1813 /***********************************************************************
1814 * NdrConformantVaryingArrayFree [RPCRT4.@]
1816 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
1817 unsigned char* pMemory,
1818 PFORMAT_STRING pFormat )
1820 FIXME( "stub\n" );
1824 /***********************************************************************
1825 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
1827 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
1828 unsigned char* pMemory, PFORMAT_STRING pFormat )
1830 FIXME( "stub\n" );
1834 /***********************************************************************
1835 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
1837 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
1838 PFORMAT_STRING pFormat )
1840 FIXME( "stub\n" );
1841 return 0;
1845 /***********************************************************************
1846 * NdrComplexArrayMarshall [RPCRT4.@]
1848 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1849 unsigned char *pMemory,
1850 PFORMAT_STRING pFormat)
1852 DWORD size = 0, count, def;
1853 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1855 def = *(WORD*)&pFormat[2];
1856 pFormat += 4;
1858 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1859 size = pStubMsg->MaxCount;
1860 TRACE("conformance=%ld\n", size);
1862 if (*(DWORD*)pFormat != 0xffffffff)
1863 FIXME("compute variance\n");
1864 pFormat += 4;
1866 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
1867 pStubMsg->Buffer += 4;
1869 for (count=0; count<size; count++)
1870 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
1872 STD_OVERFLOW_CHECK(pStubMsg);
1874 return NULL;
1877 /***********************************************************************
1878 * NdrComplexArrayUnmarshall [RPCRT4.@]
1880 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1881 unsigned char **ppMemory,
1882 PFORMAT_STRING pFormat,
1883 unsigned char fMustAlloc)
1885 DWORD size = 0, count, esize;
1886 unsigned char *pMemory;
1887 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1889 pFormat += 4;
1891 pFormat = ReadConformance(pStubMsg, pFormat);
1892 size = pStubMsg->MaxCount;
1893 TRACE("conformance=%ld\n", size);
1895 pFormat += 4;
1897 esize = ComplexStructSize(pStubMsg, pFormat);
1899 if (fMustAlloc || !*ppMemory)
1900 *ppMemory = NdrAllocate(pStubMsg, size*esize);
1902 pMemory = *ppMemory;
1903 for (count=0; count<size; count++)
1904 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
1906 return NULL;
1909 /***********************************************************************
1910 * NdrComplexArrayBufferSize [RPCRT4.@]
1912 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1913 unsigned char *pMemory,
1914 PFORMAT_STRING pFormat)
1916 DWORD size = 0, count, def;
1917 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1919 def = *(WORD*)&pFormat[2];
1920 pFormat += 4;
1922 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1923 size = pStubMsg->MaxCount;
1924 TRACE("conformance=%ld\n", size);
1926 if (*(DWORD*)pFormat != 0xffffffff)
1927 FIXME("compute variance\n");
1928 pFormat += 4;
1930 for (count=0; count<size; count++)
1931 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1934 /***********************************************************************
1935 * NdrComplexArrayMemorySize [RPCRT4.@]
1937 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1938 PFORMAT_STRING pFormat)
1940 DWORD size = 0;
1941 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1943 pFormat += 4;
1945 pFormat = ReadConformance(pStubMsg, pFormat);
1946 size = pStubMsg->MaxCount;
1947 TRACE("conformance=%ld\n", size);
1949 pFormat += 4;
1951 return 0;
1954 /***********************************************************************
1955 * NdrComplexArrayFree [RPCRT4.@]
1957 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
1958 unsigned char *pMemory,
1959 PFORMAT_STRING pFormat)
1961 DWORD size = 0, count, def;
1962 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1964 def = *(WORD*)&pFormat[2];
1965 pFormat += 4;
1967 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1968 size = pStubMsg->MaxCount;
1969 TRACE("conformance=%ld\n", size);
1971 if (*(DWORD*)pFormat != 0xffffffff)
1972 FIXME("compute variance\n");
1973 pFormat += 4;
1975 for (count=0; count<size; count++)
1976 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
1979 unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
1981 return MAKELONG(pStubMsg->dwDestContext,
1982 pStubMsg->RpcMsg->DataRepresentation);
1985 /***********************************************************************
1986 * NdrUserMarshalMarshall [RPCRT4.@]
1988 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1989 unsigned char *pMemory,
1990 PFORMAT_STRING pFormat)
1992 /* unsigned flags = pFormat[1]; */
1993 unsigned index = *(WORD*)&pFormat[2];
1994 unsigned long uflag = UserMarshalFlags(pStubMsg);
1995 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1996 TRACE("index=%d\n", index);
1998 pStubMsg->Buffer =
1999 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2000 &uflag, pStubMsg->Buffer, pMemory);
2002 STD_OVERFLOW_CHECK(pStubMsg);
2004 return NULL;
2007 /***********************************************************************
2008 * NdrUserMarshalUnmarshall [RPCRT4.@]
2010 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2011 unsigned char **ppMemory,
2012 PFORMAT_STRING pFormat,
2013 unsigned char fMustAlloc)
2015 /* unsigned flags = pFormat[1];*/
2016 unsigned index = *(WORD*)&pFormat[2];
2017 DWORD memsize = *(WORD*)&pFormat[4];
2018 unsigned long uflag = UserMarshalFlags(pStubMsg);
2019 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2020 TRACE("index=%d\n", index);
2022 if (fMustAlloc || !*ppMemory)
2023 *ppMemory = NdrAllocate(pStubMsg, memsize);
2025 pStubMsg->Buffer =
2026 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2027 &uflag, pStubMsg->Buffer, *ppMemory);
2029 return NULL;
2032 /***********************************************************************
2033 * NdrUserMarshalBufferSize [RPCRT4.@]
2035 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2036 unsigned char *pMemory,
2037 PFORMAT_STRING pFormat)
2039 /* unsigned flags = pFormat[1];*/
2040 unsigned index = *(WORD*)&pFormat[2];
2041 DWORD bufsize = *(WORD*)&pFormat[6];
2042 unsigned long uflag = UserMarshalFlags(pStubMsg);
2043 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2044 TRACE("index=%d\n", index);
2046 if (bufsize) {
2047 TRACE("size=%ld\n", bufsize);
2048 pStubMsg->BufferLength += bufsize;
2049 return;
2052 pStubMsg->BufferLength =
2053 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2054 &uflag, pStubMsg->BufferLength, pMemory);
2057 /***********************************************************************
2058 * NdrUserMarshalMemorySize [RPCRT4.@]
2060 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2061 PFORMAT_STRING pFormat)
2063 unsigned index = *(WORD*)&pFormat[2];
2064 /* DWORD memsize = *(WORD*)&pFormat[4]; */
2065 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
2066 TRACE("index=%d\n", index);
2068 return 0;
2071 /***********************************************************************
2072 * NdrUserMarshalFree [RPCRT4.@]
2074 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2075 unsigned char *pMemory,
2076 PFORMAT_STRING pFormat)
2078 /* unsigned flags = pFormat[1]; */
2079 unsigned index = *(WORD*)&pFormat[2];
2080 unsigned long uflag = UserMarshalFlags(pStubMsg);
2081 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2082 TRACE("index=%d\n", index);
2084 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2085 &uflag, pMemory);
2088 /***********************************************************************
2089 * NdrClearOutParameters [RPCRT4.@]
2091 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2092 PFORMAT_STRING pFormat,
2093 void *ArgAddr)
2095 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2098 /***********************************************************************
2099 * NdrConvert [RPCRT4.@]
2101 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2103 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2104 /* FIXME: since this stub doesn't do any converting, the proper behavior
2105 is to raise an exception */
2108 /***********************************************************************
2109 * NdrConvert2 [RPCRT4.@]
2111 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2113 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2114 pStubMsg, pFormat, NumberParams);
2115 /* FIXME: since this stub doesn't do any converting, the proper behavior
2116 is to raise an exception */