Return error from low level driver when necessary.
[wine.git] / dlls / rpcrt4 / ndr_marshall.c
blobd6b0ca2048a6b8b7fb19a701140999f2eec694dc
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 <stdarg.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <assert.h>
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winerror.h"
33 #include "winreg.h"
35 #include "ndr_misc.h"
36 #include "rpcndr.h"
38 #include "wine/unicode.h"
39 #include "wine/rpcfc.h"
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(ole);
45 #define BUFFER_PARANOIA 20
47 #if defined(__i386__)
48 #define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
49 (*((UINT32 *)(pchar)) = (uint32))
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 */
62 #define LITTLE_ENDIAN_UINT32_READ(pchar) \
63 (MAKELONG( \
64 MAKEWORD(*(pchar), *((pchar)+1)), \
65 MAKEWORD(*((pchar)+2), *((pchar)+3))))
66 #endif
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 */
75 #define BIG_ENDIAN_UINT32_READ(pchar) \
76 (MAKELONG( \
77 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
78 MAKEWORD(*((pchar)+1), *(pchar))))
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
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)
99 #define STD_OVERFLOW_CHECK(_Msg) do { \
100 TRACE("buffer=%d/%ld\n", _Msg->Buffer - _Msg->BufferStart, _Msg->BufferLength); \
101 if (_Msg->Buffer > _Msg->BufferEnd) ERR("buffer overflow %d bytes\n", _Msg->Buffer - _Msg->BufferEnd); \
102 } while (0)
104 #define NDR_TABLE_SIZE 128
105 #define NDR_TABLE_MASK 127
107 NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
108 0, 0, 0, 0, 0, 0, 0, 0,
109 0, 0, 0, 0, 0, 0, 0, 0,
110 /* 0x10 */
112 /* 0x11 */
113 NdrPointerMarshall, NdrPointerMarshall,
114 NdrPointerMarshall, NdrPointerMarshall,
115 /* 0x15 */
116 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
117 0, 0, 0,
118 NdrComplexStructMarshall,
119 /* 0x1b */
120 NdrConformantArrayMarshall, 0, 0, 0, 0, 0,
121 NdrComplexArrayMarshall,
122 /* 0x22 */
123 NdrConformantStringMarshall, 0, 0,
124 NdrConformantStringMarshall, 0, 0, 0, 0,
125 /* 0x2a */
126 0, 0, 0, 0, 0,
127 /* 0x2f */
128 NdrInterfacePointerMarshall,
129 /* 0xb0 */
130 0, 0, 0, 0,
131 NdrUserMarshalMarshall
133 NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
134 0, 0, 0, 0, 0, 0, 0, 0,
135 0, 0, 0, 0, 0, 0, 0, 0,
136 /* 0x10 */
138 /* 0x11 */
139 NdrPointerUnmarshall, NdrPointerUnmarshall,
140 NdrPointerUnmarshall, NdrPointerUnmarshall,
141 /* 0x15 */
142 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
143 0, 0, 0,
144 NdrComplexStructUnmarshall,
145 /* 0x1b */
146 NdrConformantArrayUnmarshall, 0, 0, 0, 0, 0,
147 NdrComplexArrayUnmarshall,
148 /* 0x22 */
149 NdrConformantStringUnmarshall, 0, 0,
150 NdrConformantStringUnmarshall, 0, 0, 0, 0,
151 /* 0x2a */
152 0, 0, 0, 0, 0,
153 /* 0x2f */
154 NdrInterfacePointerUnmarshall,
155 /* 0xb0 */
156 0, 0, 0, 0,
157 NdrUserMarshalUnmarshall
159 NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
160 0, 0, 0, 0, 0, 0, 0, 0,
161 0, 0, 0, 0, 0, 0, 0, 0,
162 /* 0x10 */
164 /* 0x11 */
165 NdrPointerBufferSize, NdrPointerBufferSize,
166 NdrPointerBufferSize, NdrPointerBufferSize,
167 /* 0x15 */
168 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
169 0, 0, 0,
170 NdrComplexStructBufferSize,
171 /* 0x1b */
172 NdrConformantArrayBufferSize, 0, 0, 0, 0, 0,
173 NdrComplexArrayBufferSize,
174 /* 0x22 */
175 NdrConformantStringBufferSize, 0, 0,
176 NdrConformantStringBufferSize, 0, 0, 0, 0,
177 /* 0x2a */
178 0, 0, 0, 0, 0,
179 /* 0x2f */
180 NdrInterfacePointerBufferSize,
181 /* 0xb0 */
182 0, 0, 0, 0,
183 NdrUserMarshalBufferSize
185 NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
186 0, 0, 0, 0, 0, 0, 0, 0,
187 0, 0, 0, 0, 0, 0, 0, 0,
188 /* 0x10 */
190 /* 0x11 */
191 NdrPointerMemorySize, NdrPointerMemorySize,
192 NdrPointerMemorySize, NdrPointerMemorySize,
193 /* 0x15 */
194 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
195 0, 0, 0,
196 NdrComplexStructMemorySize,
197 /* 0x1b */
198 NdrConformantArrayMemorySize, 0, 0, 0, 0, 0,
199 NdrComplexArrayMemorySize,
200 /* 0x22 */
201 NdrConformantStringMemorySize, 0, 0,
202 NdrConformantStringMemorySize, 0, 0, 0, 0,
203 /* 0x2a */
204 0, 0, 0, 0, 0,
205 /* 0x2f */
206 NdrInterfacePointerMemorySize,
207 /* 0xb0 */
208 0, 0, 0, 0,
209 NdrUserMarshalMemorySize
211 NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
212 0, 0, 0, 0, 0, 0, 0, 0,
213 0, 0, 0, 0, 0, 0, 0, 0,
214 /* 0x10 */
216 /* 0x11 */
217 NdrPointerFree, NdrPointerFree,
218 NdrPointerFree, NdrPointerFree,
219 /* 0x15 */
220 NdrSimpleStructFree, NdrSimpleStructFree,
221 0, 0, 0,
222 NdrComplexStructFree,
223 /* 0x1b */
224 NdrConformantArrayFree, 0, 0, 0, 0, 0,
225 NdrComplexArrayFree,
226 /* 0x22 */
227 0, 0, 0, 0, 0, 0, 0, 0,
228 /* 0x2a */
229 0, 0, 0, 0, 0,
230 /* 0x2f */
231 NdrInterfacePointerFree,
232 /* 0xb0 */
233 0, 0, 0, 0,
234 NdrUserMarshalFree
237 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
239 /* hmm, this is probably supposed to do more? */
240 return pStubMsg->pfnAllocate(len);
243 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
245 pStubMsg->pfnFree(Pointer);
248 PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
250 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
251 pStubMsg->Buffer += 4;
252 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
253 return pFormat+4;
256 PFORMAT_STRING ComputeConformance(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
257 PFORMAT_STRING pFormat, ULONG_PTR def)
259 BYTE dtype = pFormat[0] & 0xf;
260 DWORD ofs = (DWORD)pFormat[2] | ((DWORD)pFormat[3] << 8);
261 LPVOID ptr = NULL;
262 DWORD data = 0;
264 if (pFormat[0] == 0xff) {
265 /* null descriptor */
266 pStubMsg->MaxCount = def;
267 goto finish_conf;
270 switch (pFormat[0] & 0xf0) {
271 case RPC_FC_NORMAL_CONFORMANCE:
272 TRACE("normal conformance, ofs=%ld\n", ofs);
273 ptr = pMemory + ofs;
274 break;
275 case RPC_FC_POINTER_CONFORMANCE:
276 TRACE("pointer conformance, ofs=%ld\n", ofs);
277 ptr = pStubMsg->Memory + ofs;
278 break;
279 case RPC_FC_TOP_LEVEL_CONFORMANCE:
280 TRACE("toplevel conformance, ofs=%ld\n", ofs);
281 if (pStubMsg->StackTop) {
282 ptr = pStubMsg->StackTop + ofs;
284 else {
285 /* -Os mode, MaxCount is already set */
286 goto finish_conf;
288 break;
289 case RPC_FC_CONSTANT_CONFORMANCE:
290 data = ofs | ((DWORD)pFormat[1] << 16);
291 TRACE("constant conformance, val=%ld\n", data);
292 pStubMsg->MaxCount = data;
293 goto finish_conf;
294 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
295 FIXME("toplevel multidimensional conformance, ofs=%ld\n", ofs);
296 if (pStubMsg->StackTop) {
297 ptr = pStubMsg->StackTop + ofs;
299 else {
300 /* ? */
301 goto done_conf_grab;
303 break;
304 default:
305 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
308 switch (pFormat[1]) {
309 case RPC_FC_DEREFERENCE:
310 ptr = *(LPVOID*)ptr;
311 break;
312 case RPC_FC_CALLBACK:
313 /* ofs is index into StubDesc->apfnExprEval */
314 FIXME("handle callback\n");
315 goto finish_conf;
316 default:
317 break;
320 switch (dtype) {
321 case RPC_FC_LONG:
322 case RPC_FC_ULONG:
323 data = *(DWORD*)ptr;
324 break;
325 case RPC_FC_SHORT:
326 data = *(SHORT*)ptr;
327 break;
328 case RPC_FC_USHORT:
329 data = *(USHORT*)ptr;
330 break;
331 case RPC_FC_SMALL:
332 data = *(CHAR*)ptr;
333 break;
334 case RPC_FC_USMALL:
335 data = *(UCHAR*)ptr;
336 break;
337 default:
338 FIXME("unknown conformance data type %x\n", dtype);
339 goto done_conf_grab;
341 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
343 done_conf_grab:
344 switch (pFormat[1]) {
345 case 0: /* no op */
346 pStubMsg->MaxCount = data;
347 break;
348 case RPC_FC_DEREFERENCE:
349 /* already handled */
350 break;
351 default:
352 FIXME("unknown conformance op %d\n", pFormat[1]);
353 goto finish_conf;
356 finish_conf:
357 TRACE("resulting conformance is %ld\n", pStubMsg->MaxCount);
358 return pFormat+4;
363 * NdrConformantString:
365 * What MS calls a ConformantString is, in DCE terminology,
366 * a Varying-Conformant String.
368 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
369 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
370 * into unmarshalled string)
371 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
372 * [
373 * data: CHARTYPE[maxlen]
374 * ]
375 * ], where CHARTYPE is the appropriate character type (specified externally)
379 /***********************************************************************
380 * NdrConformantStringMarshall [RPCRT4.@]
382 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
383 unsigned char *pszMessage, PFORMAT_STRING pFormat)
385 unsigned long len, esize;
386 unsigned char *c;
388 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
390 assert(pFormat);
391 if (*pFormat == RPC_FC_C_CSTRING) {
392 TRACE("string=%s\n", debugstr_a(pszMessage));
393 len = strlen(pszMessage)+1;
394 esize = 1;
396 else if (*pFormat == RPC_FC_C_WSTRING) {
397 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
398 len = strlenW((LPWSTR)pszMessage)+1;
399 esize = 2;
401 else {
402 ERR("Unhandled string type: %#x\n", *pFormat);
403 /* FIXME: raise an exception. */
404 return NULL;
407 if (pFormat[1] != RPC_FC_PAD) {
408 FIXME("sized string format=%d\n", pFormat[1]);
411 assert( (pStubMsg->BufferLength >= (len*esize + 13)) && (pStubMsg->Buffer != NULL) );
413 c = pStubMsg->Buffer;
414 memset(c, 0, 12);
415 NDR_LOCAL_UINT32_WRITE(c, len); /* max length: strlen + 1 (for '\0') */
416 c += 8; /* offset: 0 */
417 NDR_LOCAL_UINT32_WRITE(c, len); /* actual length: (same) */
418 c += 4;
419 memcpy(c, pszMessage, len*esize); /* the string itself */
420 c += len*esize;
421 pStubMsg->Buffer = c;
423 STD_OVERFLOW_CHECK(pStubMsg);
425 /* success */
426 return NULL; /* is this always right? */
429 /***********************************************************************
430 * NdrConformantStringBufferSize [RPCRT4.@]
432 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
433 unsigned char* pMemory, PFORMAT_STRING pFormat)
435 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
437 assert(pFormat);
438 if (*pFormat == RPC_FC_C_CSTRING) {
439 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 1 octet for '\0' */
440 TRACE("string=%s\n", debugstr_a(pMemory));
441 pStubMsg->BufferLength += strlen(pMemory) + 13 + BUFFER_PARANOIA;
443 else if (*pFormat == RPC_FC_C_WSTRING) {
444 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 2 octets for L'\0' */
445 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
446 pStubMsg->BufferLength += strlenW((LPWSTR)pMemory)*2 + 14 + BUFFER_PARANOIA;
448 else {
449 ERR("Unhandled string type: %#x\n", *pFormat);
450 /* FIXME: raise an exception */
453 if (pFormat[1] != RPC_FC_PAD) {
454 FIXME("sized string format=%d\n", pFormat[1]);
458 /************************************************************************
459 * NdrConformantStringMemorySize [RPCRT4.@]
461 unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
462 PFORMAT_STRING pFormat )
464 unsigned long rslt = 0;
466 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
468 assert(pStubMsg && pFormat);
470 if (*pFormat == RPC_FC_C_CSTRING) {
471 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
473 else if (*pFormat == RPC_FC_C_WSTRING) {
474 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
476 else {
477 ERR("Unhandled string type: %#x\n", *pFormat);
478 /* FIXME: raise an exception */
481 if (pFormat[1] != RPC_FC_PAD) {
482 FIXME("sized string format=%d\n", pFormat[1]);
485 TRACE(" --> %lu\n", rslt);
486 return rslt;
489 /************************************************************************
490 * NdrConformantStringUnmarshall [RPCRT4.@]
492 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
493 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
495 unsigned long len, esize, ofs;
496 unsigned char *pMem;
498 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
499 pStubMsg, *ppMemory, pFormat, fMustAlloc);
501 assert(pFormat && ppMemory && pStubMsg);
503 pStubMsg->Buffer += 4;
504 ofs = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
505 pStubMsg->Buffer += 4;
506 len = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
507 pStubMsg->Buffer += 4;
509 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
510 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
511 else {
512 ERR("Unhandled string type: %#x\n", *pFormat);
513 /* FIXME: raise an exception */
514 esize = 0;
517 if (pFormat[1] != RPC_FC_PAD) {
518 FIXME("sized string format=%d\n", pFormat[1]);
521 if (fMustAlloc) {
522 *ppMemory = NdrAllocate(pStubMsg, len*esize + BUFFER_PARANOIA);
523 } else {
524 if (pStubMsg->ReuseBuffer && !*ppMemory)
525 /* for servers, we may just point straight into the RPC buffer, I think
526 * (I guess that's what MS does since MIDL code doesn't try to free) */
527 *ppMemory = pStubMsg->Buffer - ofs*esize;
528 /* for clients, memory should be provided by caller */
531 pMem = *ppMemory + ofs*esize;
533 if (pMem != pStubMsg->Buffer)
534 memcpy(pMem, pStubMsg->Buffer, len*esize);
536 pStubMsg->Buffer += len*esize;
538 if (*pFormat == RPC_FC_C_CSTRING) {
539 TRACE("string=%s\n", debugstr_a(pMem));
541 else if (*pFormat == RPC_FC_C_WSTRING) {
542 TRACE("string=%s\n", debugstr_w((LPWSTR)pMem));
545 return NULL; /* FIXME: is this always right? */
548 /***********************************************************************
549 * PointerMarshall
551 void WINAPI PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
552 unsigned char *Buffer,
553 unsigned char *Pointer,
554 PFORMAT_STRING pFormat)
556 unsigned type = pFormat[0], attr = pFormat[1];
557 PFORMAT_STRING desc;
558 NDR_MARSHALL m;
560 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
561 TRACE("type=%d, attr=%d\n", type, attr);
562 pFormat += 2;
563 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
564 else desc = pFormat + *(SHORT*)pFormat;
565 if (attr & RPC_FC_P_DEREF) {
566 Pointer = *(unsigned char**)Pointer;
567 TRACE("deref => %p\n", Pointer);
570 *(LPVOID*)Buffer = 0;
572 switch (type) {
573 case RPC_FC_RP: /* ref pointer (always non-null) */
574 break;
575 default:
576 FIXME("unhandled ptr type=%02x\n", type);
579 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
580 if (m) m(pStubMsg, Pointer, desc);
581 else FIXME("no marshaller for data type=%02x\n", *desc);
583 STD_OVERFLOW_CHECK(pStubMsg);
586 /***********************************************************************
587 * PointerUnmarshall
589 void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
590 unsigned char *Buffer,
591 unsigned char **pPointer,
592 PFORMAT_STRING pFormat,
593 unsigned char fMustAlloc)
595 unsigned type = pFormat[0], attr = pFormat[1];
596 PFORMAT_STRING desc;
597 NDR_UNMARSHALL m;
599 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
600 TRACE("type=%d, attr=%d\n", type, attr);
601 pFormat += 2;
602 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
603 else desc = pFormat + *(SHORT*)pFormat;
604 if (attr & RPC_FC_P_DEREF) {
605 pPointer = *(unsigned char***)pPointer;
606 TRACE("deref => %p\n", pPointer);
609 switch (type) {
610 case RPC_FC_RP: /* ref pointer (always non-null) */
611 break;
612 default:
613 FIXME("unhandled ptr type=%02x\n", type);
616 *pPointer = NULL;
618 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
619 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
620 else FIXME("no unmarshaller for data type=%02x\n", *desc);
621 TRACE("pointer=%p\n", *pPointer);
624 /***********************************************************************
625 * PointerBufferSize
627 void WINAPI PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
628 unsigned char *Pointer,
629 PFORMAT_STRING pFormat)
631 unsigned type = pFormat[0], attr = pFormat[1];
632 PFORMAT_STRING desc;
633 NDR_BUFFERSIZE m;
635 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
636 TRACE("type=%d, attr=%d\n", type, attr);
637 pFormat += 2;
638 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
639 else desc = pFormat + *(SHORT*)pFormat;
640 if (attr & RPC_FC_P_DEREF) {
641 Pointer = *(unsigned char**)Pointer;
642 TRACE("deref => %p\n", Pointer);
645 switch (type) {
646 case RPC_FC_RP: /* ref pointer (always non-null) */
647 break;
648 default:
649 FIXME("unhandled ptr type=%02x\n", type);
652 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
653 if (m) m(pStubMsg, Pointer, desc);
654 else FIXME("no buffersizer for data type=%02x\n", *desc);
657 /***********************************************************************
658 * PointerMemorySize [RPCRT4.@]
660 unsigned long WINAPI PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
661 unsigned char *Buffer,
662 PFORMAT_STRING pFormat)
664 unsigned type = pFormat[0], attr = pFormat[1];
665 PFORMAT_STRING desc;
666 NDR_MEMORYSIZE m;
668 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
669 TRACE("type=%d, attr=%d\n", type, attr);
670 pFormat += 2;
671 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
672 else desc = pFormat + *(SHORT*)pFormat;
673 if (attr & RPC_FC_P_DEREF) {
674 TRACE("deref\n");
677 switch (type) {
678 case RPC_FC_RP: /* ref pointer (always non-null) */
679 break;
680 default:
681 FIXME("unhandled ptr type=%02x\n", type);
684 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
685 if (m) m(pStubMsg, desc);
686 else FIXME("no memorysizer for data type=%02x\n", *desc);
688 return 0;
691 /***********************************************************************
692 * PointerFree [RPCRT4.@]
694 void WINAPI PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
695 unsigned char *Pointer,
696 PFORMAT_STRING pFormat)
698 unsigned type = pFormat[0], attr = pFormat[1];
699 PFORMAT_STRING desc;
700 NDR_FREE m;
702 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
703 TRACE("type=%d, attr=%d\n", type, attr);
704 if (attr & RPC_FC_P_DONTFREE) return;
705 pFormat += 2;
706 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
707 else desc = pFormat + *(SHORT*)pFormat;
708 if (attr & RPC_FC_P_DEREF) {
709 Pointer = *(unsigned char**)Pointer;
710 TRACE("deref => %p\n", Pointer);
713 if (!Pointer) return;
715 m = NdrFreer[*desc & NDR_TABLE_MASK];
716 if (m) m(pStubMsg, Pointer, desc);
718 /* hmm... is this sensible?
719 * perhaps we should check if the memory comes from NdrAllocate,
720 * and deallocate only if so - checking if the pointer is between
721 * BufferStart and BufferEnd is probably no good since the buffer
722 * may be reallocated when the server wants to marshal the reply */
723 switch (*desc) {
724 case RPC_FC_BOGUS_STRUCT:
725 case RPC_FC_BOGUS_ARRAY:
726 case RPC_FC_USER_MARSHAL:
727 break;
728 default:
729 FIXME("unhandled data type=%02x\n", *desc);
730 case RPC_FC_CARRAY:
731 case RPC_FC_C_CSTRING:
732 case RPC_FC_C_WSTRING:
733 if (pStubMsg->ReuseBuffer) goto notfree;
734 break;
735 case RPC_FC_IP:
736 goto notfree;
739 if (attr & RPC_FC_P_ONSTACK) {
740 TRACE("not freeing stack ptr %p\n", Pointer);
741 return;
743 TRACE("freeing %p\n", Pointer);
744 NdrFree(pStubMsg, Pointer);
745 return;
746 notfree:
747 TRACE("not freeing %p\n", Pointer);
750 /***********************************************************************
751 * EmbeddedPointerMarshall
753 unsigned char * WINAPI EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
754 unsigned char *pMemory,
755 PFORMAT_STRING pFormat)
757 unsigned char *Mark = pStubMsg->BufferMark;
758 unsigned long Offset = pStubMsg->Offset;
759 unsigned ofs, rep, count, stride, xofs;
761 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
763 if (*pFormat != RPC_FC_PP) return NULL;
764 pFormat += 2;
766 while (pFormat[0] != RPC_FC_END) {
767 switch (pFormat[0]) {
768 default:
769 FIXME("unknown repeat type %d\n", pFormat[0]);
770 case RPC_FC_NO_REPEAT:
771 rep = 1;
772 stride = 0;
773 ofs = 0;
774 count = 1;
775 xofs = 0;
776 pFormat += 2;
777 break;
778 case RPC_FC_FIXED_REPEAT:
779 rep = *(WORD*)&pFormat[2];
780 stride = *(WORD*)&pFormat[4];
781 ofs = *(WORD*)&pFormat[6];
782 count = *(WORD*)&pFormat[8];
783 xofs = 0;
784 pFormat += 10;
785 break;
786 case RPC_FC_VARIABLE_REPEAT:
787 rep = pStubMsg->MaxCount;
788 stride = *(WORD*)&pFormat[2];
789 ofs = *(WORD*)&pFormat[4];
790 count = *(WORD*)&pFormat[6];
791 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
792 pFormat += 8;
793 break;
795 /* ofs doesn't seem to matter in this context */
796 while (rep) {
797 PFORMAT_STRING info = pFormat;
798 unsigned char *membase = pMemory + xofs;
799 unsigned u;
800 for (u=0; u<count; u++,info+=8) {
801 unsigned char *memptr = membase + *(SHORT*)&info[0];
802 unsigned char *bufptr = Mark + *(SHORT*)&info[2];
803 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
805 rep--;
807 pFormat += 8 * count;
810 STD_OVERFLOW_CHECK(pStubMsg);
812 return NULL;
815 /***********************************************************************
816 * EmbeddedPointerUnmarshall
818 unsigned char * WINAPI EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
819 unsigned char **ppMemory,
820 PFORMAT_STRING pFormat,
821 unsigned char fMustAlloc)
823 unsigned char *Mark = pStubMsg->BufferMark;
824 unsigned long Offset = pStubMsg->Offset;
825 unsigned ofs, rep, count, stride, xofs;
827 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
829 if (*pFormat != RPC_FC_PP) return NULL;
830 pFormat += 2;
832 while (pFormat[0] != RPC_FC_END) {
833 switch (pFormat[0]) {
834 default:
835 FIXME("unknown repeat type %d\n", pFormat[0]);
836 case RPC_FC_NO_REPEAT:
837 rep = 1;
838 stride = 0;
839 ofs = 0;
840 count = 1;
841 xofs = 0;
842 pFormat += 2;
843 break;
844 case RPC_FC_FIXED_REPEAT:
845 rep = *(WORD*)&pFormat[2];
846 stride = *(WORD*)&pFormat[4];
847 ofs = *(WORD*)&pFormat[6];
848 count = *(WORD*)&pFormat[8];
849 xofs = 0;
850 pFormat += 10;
851 break;
852 case RPC_FC_VARIABLE_REPEAT:
853 rep = pStubMsg->MaxCount;
854 stride = *(WORD*)&pFormat[2];
855 ofs = *(WORD*)&pFormat[4];
856 count = *(WORD*)&pFormat[6];
857 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
858 pFormat += 8;
859 break;
861 /* ofs doesn't seem to matter in this context */
862 while (rep) {
863 PFORMAT_STRING info = pFormat;
864 unsigned char *membase = *ppMemory + xofs;
865 unsigned u;
866 for (u=0; u<count; u++,info+=8) {
867 unsigned char *memptr = membase + *(SHORT*)&info[0];
868 unsigned char *bufptr = Mark + *(SHORT*)&info[2];
869 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, fMustAlloc);
871 rep--;
873 pFormat += 8 * count;
876 return NULL;
879 /***********************************************************************
880 * EmbeddedPointerBufferSize
882 void WINAPI EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
883 unsigned char *pMemory,
884 PFORMAT_STRING pFormat)
886 unsigned long Offset = pStubMsg->Offset;
887 unsigned ofs, rep, count, stride, xofs;
889 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
890 if (*pFormat != RPC_FC_PP) return;
891 pFormat += 2;
893 while (pFormat[0] != RPC_FC_END) {
894 switch (pFormat[0]) {
895 default:
896 FIXME("unknown repeat type %d\n", pFormat[0]);
897 case RPC_FC_NO_REPEAT:
898 rep = 1;
899 stride = 0;
900 ofs = 0;
901 count = 1;
902 xofs = 0;
903 pFormat += 2;
904 break;
905 case RPC_FC_FIXED_REPEAT:
906 rep = *(WORD*)&pFormat[2];
907 stride = *(WORD*)&pFormat[4];
908 ofs = *(WORD*)&pFormat[6];
909 count = *(WORD*)&pFormat[8];
910 xofs = 0;
911 pFormat += 10;
912 break;
913 case RPC_FC_VARIABLE_REPEAT:
914 rep = pStubMsg->MaxCount;
915 stride = *(WORD*)&pFormat[2];
916 ofs = *(WORD*)&pFormat[4];
917 count = *(WORD*)&pFormat[6];
918 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
919 pFormat += 8;
920 break;
922 /* ofs doesn't seem to matter in this context */
923 while (rep) {
924 PFORMAT_STRING info = pFormat;
925 unsigned char *membase = pMemory + xofs;
926 unsigned u;
927 for (u=0; u<count; u++,info+=8) {
928 unsigned char *memptr = membase + *(SHORT*)&info[0];
929 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
931 rep--;
933 pFormat += 8 * count;
937 /***********************************************************************
938 * EmbeddedPointerMemorySize
940 unsigned long WINAPI EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
941 PFORMAT_STRING pFormat)
943 unsigned long Offset = pStubMsg->Offset;
944 unsigned char *Mark = pStubMsg->BufferMark;
945 unsigned ofs, rep, count, stride, xofs;
947 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
948 if (*pFormat != RPC_FC_PP) return 0;
949 pFormat += 2;
951 while (pFormat[0] != RPC_FC_END) {
952 switch (pFormat[0]) {
953 default:
954 FIXME("unknown repeat type %d\n", pFormat[0]);
955 case RPC_FC_NO_REPEAT:
956 rep = 1;
957 stride = 0;
958 ofs = 0;
959 count = 1;
960 xofs = 0;
961 pFormat += 2;
962 break;
963 case RPC_FC_FIXED_REPEAT:
964 rep = *(WORD*)&pFormat[2];
965 stride = *(WORD*)&pFormat[4];
966 ofs = *(WORD*)&pFormat[6];
967 count = *(WORD*)&pFormat[8];
968 xofs = 0;
969 pFormat += 10;
970 break;
971 case RPC_FC_VARIABLE_REPEAT:
972 rep = pStubMsg->MaxCount;
973 stride = *(WORD*)&pFormat[2];
974 ofs = *(WORD*)&pFormat[4];
975 count = *(WORD*)&pFormat[6];
976 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
977 pFormat += 8;
978 break;
980 /* ofs doesn't seem to matter in this context */
981 while (rep) {
982 PFORMAT_STRING info = pFormat;
983 unsigned u;
984 for (u=0; u<count; u++,info+=8) {
985 unsigned char *bufptr = Mark + *(SHORT*)&info[2];
986 PointerMemorySize(pStubMsg, bufptr, info+4);
988 rep--;
990 pFormat += 8 * count;
993 return 0;
996 /***********************************************************************
997 * EmbeddedPointerFree
999 void WINAPI EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1000 unsigned char *pMemory,
1001 PFORMAT_STRING pFormat)
1003 unsigned long Offset = pStubMsg->Offset;
1004 unsigned ofs, rep, count, stride, xofs;
1006 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1007 if (*pFormat != RPC_FC_PP) return;
1008 pFormat += 2;
1010 while (pFormat[0] != RPC_FC_END) {
1011 switch (pFormat[0]) {
1012 default:
1013 FIXME("unknown repeat type %d\n", pFormat[0]);
1014 case RPC_FC_NO_REPEAT:
1015 rep = 1;
1016 stride = 0;
1017 ofs = 0;
1018 count = 1;
1019 xofs = 0;
1020 pFormat += 2;
1021 break;
1022 case RPC_FC_FIXED_REPEAT:
1023 rep = *(WORD*)&pFormat[2];
1024 stride = *(WORD*)&pFormat[4];
1025 ofs = *(WORD*)&pFormat[6];
1026 count = *(WORD*)&pFormat[8];
1027 xofs = 0;
1028 pFormat += 10;
1029 break;
1030 case RPC_FC_VARIABLE_REPEAT:
1031 rep = pStubMsg->MaxCount;
1032 stride = *(WORD*)&pFormat[2];
1033 ofs = *(WORD*)&pFormat[4];
1034 count = *(WORD*)&pFormat[6];
1035 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1036 pFormat += 8;
1037 break;
1039 /* ofs doesn't seem to matter in this context */
1040 while (rep) {
1041 PFORMAT_STRING info = pFormat;
1042 unsigned char *membase = pMemory + xofs;
1043 unsigned u;
1044 for (u=0; u<count; u++,info+=8) {
1045 unsigned char *memptr = membase + *(SHORT*)&info[0];
1046 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1048 rep--;
1050 pFormat += 8 * count;
1054 /***********************************************************************
1055 * NdrPointerMarshall [RPCRT4.@]
1057 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1058 unsigned char *pMemory,
1059 PFORMAT_STRING pFormat)
1061 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1063 pStubMsg->BufferMark = pStubMsg->Buffer;
1064 PointerMarshall(pStubMsg, pStubMsg->Buffer, pMemory, pFormat);
1065 pStubMsg->Buffer += 4;
1067 STD_OVERFLOW_CHECK(pStubMsg);
1069 return NULL;
1072 /***********************************************************************
1073 * NdrPointerUnmarshall [RPCRT4.@]
1075 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1076 unsigned char **ppMemory,
1077 PFORMAT_STRING pFormat,
1078 unsigned char fMustAlloc)
1080 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1082 pStubMsg->BufferMark = pStubMsg->Buffer;
1083 PointerUnmarshall(pStubMsg, pStubMsg->Buffer, ppMemory, pFormat, fMustAlloc);
1084 pStubMsg->Buffer += 4;
1086 return NULL;
1089 /***********************************************************************
1090 * NdrPointerBufferSize [RPCRT4.@]
1092 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1093 unsigned char *pMemory,
1094 PFORMAT_STRING pFormat)
1096 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1097 pStubMsg->BufferLength += 4;
1098 PointerBufferSize(pStubMsg, pMemory, pFormat);
1101 /***********************************************************************
1102 * NdrPointerMemorySize [RPCRT4.@]
1104 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1105 PFORMAT_STRING pFormat)
1107 /* unsigned size = *(LPWORD)(pFormat+2); */
1108 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1109 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1110 return 0;
1113 /***********************************************************************
1114 * NdrPointerFree [RPCRT4.@]
1116 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1117 unsigned char *pMemory,
1118 PFORMAT_STRING pFormat)
1120 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1121 PointerFree(pStubMsg, pMemory, pFormat);
1124 /***********************************************************************
1125 * NdrSimpleStructMarshall [RPCRT4.@]
1127 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1128 unsigned char *pMemory,
1129 PFORMAT_STRING pFormat)
1131 unsigned size = *(LPWORD)(pFormat+2);
1132 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1134 memcpy(pStubMsg->Buffer, pMemory, size);
1135 pStubMsg->BufferMark = pStubMsg->Buffer;
1136 pStubMsg->Buffer += size;
1138 if (pFormat[0] != RPC_FC_STRUCT)
1139 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1141 STD_OVERFLOW_CHECK(pStubMsg);
1143 return NULL;
1146 /***********************************************************************
1147 * NdrSimpleStructUnmarshall [RPCRT4.@]
1149 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1150 unsigned char **ppMemory,
1151 PFORMAT_STRING pFormat,
1152 unsigned char fMustAlloc)
1154 unsigned size = *(LPWORD)(pFormat+2);
1155 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1157 if (fMustAlloc) {
1158 *ppMemory = NdrAllocate(pStubMsg, size);
1159 memcpy(*ppMemory, pStubMsg->Buffer, size);
1160 } else {
1161 if (pStubMsg->ReuseBuffer && !*ppMemory)
1162 /* for servers, we may just point straight into the RPC buffer, I think
1163 * (I guess that's what MS does since MIDL code doesn't try to free) */
1164 *ppMemory = pStubMsg->Buffer;
1165 else
1166 /* for clients, memory should be provided by caller */
1167 memcpy(*ppMemory, pStubMsg->Buffer, size);
1170 pStubMsg->BufferMark = pStubMsg->Buffer;
1171 pStubMsg->Buffer += size;
1173 if (pFormat[0] != RPC_FC_STRUCT)
1174 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1176 return NULL;
1180 /***********************************************************************
1181 * NdrSimpleStructUnmarshall [RPCRT4.@]
1183 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1184 unsigned char FormatChar )
1186 FIXME("stub\n");
1190 /***********************************************************************
1191 * NdrSimpleStructUnmarshall [RPCRT4.@]
1193 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1194 unsigned char FormatChar )
1196 FIXME("stub\n");
1200 /***********************************************************************
1201 * NdrSimpleStructBufferSize [RPCRT4.@]
1203 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1204 unsigned char *pMemory,
1205 PFORMAT_STRING pFormat)
1207 unsigned size = *(LPWORD)(pFormat+2);
1208 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1209 pStubMsg->BufferLength += size;
1210 if (pFormat[0] != RPC_FC_STRUCT)
1211 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1214 /***********************************************************************
1215 * NdrSimpleStructMemorySize [RPCRT4.@]
1217 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1218 PFORMAT_STRING pFormat)
1220 /* unsigned size = *(LPWORD)(pFormat+2); */
1221 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1222 if (pFormat[0] != RPC_FC_STRUCT)
1223 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1224 return 0;
1227 /***********************************************************************
1228 * NdrSimpleStructFree [RPCRT4.@]
1230 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1231 unsigned char *pMemory,
1232 PFORMAT_STRING pFormat)
1234 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1235 if (pFormat[0] != RPC_FC_STRUCT)
1236 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1240 unsigned long WINAPI EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1241 PFORMAT_STRING pFormat)
1243 switch (*pFormat) {
1244 case RPC_FC_STRUCT:
1245 case RPC_FC_PSTRUCT:
1246 case RPC_FC_CSTRUCT:
1247 case RPC_FC_BOGUS_STRUCT:
1248 return *(WORD*)&pFormat[2];
1249 case RPC_FC_USER_MARSHAL:
1250 return *(WORD*)&pFormat[4];
1251 default:
1252 FIXME("unhandled embedded type %02x\n", *pFormat);
1254 return 0;
1258 unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1259 unsigned char *pMemory,
1260 PFORMAT_STRING pFormat,
1261 PFORMAT_STRING pPointer)
1263 PFORMAT_STRING desc;
1264 NDR_MARSHALL m;
1265 unsigned long size;
1267 while (*pFormat != RPC_FC_END) {
1268 switch (*pFormat) {
1269 case RPC_FC_SHORT:
1270 case RPC_FC_USHORT:
1271 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1272 memcpy(pStubMsg->Buffer, pMemory, 2);
1273 pStubMsg->Buffer += 2;
1274 pMemory += 2;
1275 break;
1276 case RPC_FC_LONG:
1277 case RPC_FC_ULONG:
1278 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1279 memcpy(pStubMsg->Buffer, pMemory, 4);
1280 pStubMsg->Buffer += 4;
1281 pMemory += 4;
1282 break;
1283 case RPC_FC_POINTER:
1284 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1285 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1286 pPointer += 4;
1287 pMemory += 4;
1288 break;
1289 case RPC_FC_ALIGNM4:
1290 ALIGN_POINTER(pMemory, 3);
1291 break;
1292 case RPC_FC_ALIGNM8:
1293 ALIGN_POINTER(pMemory, 7);
1294 break;
1295 case RPC_FC_EMBEDDED_COMPLEX:
1296 pMemory += pFormat[1];
1297 pFormat += 2;
1298 desc = pFormat + *(SHORT*)pFormat;
1299 size = EmbeddedComplexSize(pStubMsg, desc);
1300 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1301 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1302 if (m) m(pStubMsg, pMemory, desc);
1303 else FIXME("no marshaller for embedded type %02x\n", *desc);
1304 pMemory += size;
1305 pFormat += 2;
1306 continue;
1307 case RPC_FC_PAD:
1308 break;
1309 default:
1310 FIXME("unhandled format %02x\n", *pFormat);
1312 pFormat++;
1315 return pMemory;
1318 unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1319 unsigned char *pMemory,
1320 PFORMAT_STRING pFormat,
1321 PFORMAT_STRING pPointer,
1322 unsigned char fMustAlloc)
1324 PFORMAT_STRING desc;
1325 NDR_UNMARSHALL m;
1326 unsigned long size;
1328 while (*pFormat != RPC_FC_END) {
1329 switch (*pFormat) {
1330 case RPC_FC_SHORT:
1331 case RPC_FC_USHORT:
1332 memcpy(pMemory, pStubMsg->Buffer, 2);
1333 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1334 pStubMsg->Buffer += 2;
1335 pMemory += 2;
1336 break;
1337 case RPC_FC_LONG:
1338 case RPC_FC_ULONG:
1339 memcpy(pMemory, pStubMsg->Buffer, 4);
1340 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1341 pStubMsg->Buffer += 4;
1342 pMemory += 4;
1343 break;
1344 case RPC_FC_POINTER:
1345 *(unsigned char**)pMemory = NULL;
1346 TRACE("pointer => %p\n", pMemory);
1347 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, fMustAlloc);
1348 pPointer += 4;
1349 pMemory += 4;
1350 break;
1351 case RPC_FC_ALIGNM4:
1352 ALIGN_POINTER(pMemory, 3);
1353 break;
1354 case RPC_FC_ALIGNM8:
1355 ALIGN_POINTER(pMemory, 7);
1356 break;
1357 case RPC_FC_EMBEDDED_COMPLEX:
1358 pMemory += pFormat[1];
1359 pFormat += 2;
1360 desc = pFormat + *(SHORT*)pFormat;
1361 size = EmbeddedComplexSize(pStubMsg, desc);
1362 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1363 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1364 memset(pMemory, 0, size); /* just in case */
1365 if (m) m(pStubMsg, &pMemory, desc, fMustAlloc);
1366 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1367 pMemory += size;
1368 pFormat += 2;
1369 continue;
1370 case RPC_FC_PAD:
1371 break;
1372 default:
1373 FIXME("unhandled format %d\n", *pFormat);
1375 pFormat++;
1378 return pMemory;
1381 unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1382 unsigned char *pMemory,
1383 PFORMAT_STRING pFormat,
1384 PFORMAT_STRING pPointer)
1386 PFORMAT_STRING desc;
1387 NDR_BUFFERSIZE m;
1388 unsigned long size;
1390 while (*pFormat != RPC_FC_END) {
1391 switch (*pFormat) {
1392 case RPC_FC_SHORT:
1393 case RPC_FC_USHORT:
1394 pStubMsg->BufferLength += 2;
1395 pMemory += 2;
1396 break;
1397 case RPC_FC_LONG:
1398 case RPC_FC_ULONG:
1399 pStubMsg->BufferLength += 4;
1400 pMemory += 4;
1401 break;
1402 case RPC_FC_POINTER:
1403 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1404 pPointer += 4;
1405 pMemory += 4;
1406 break;
1407 case RPC_FC_ALIGNM4:
1408 ALIGN_POINTER(pMemory, 3);
1409 break;
1410 case RPC_FC_ALIGNM8:
1411 ALIGN_POINTER(pMemory, 7);
1412 break;
1413 case RPC_FC_EMBEDDED_COMPLEX:
1414 pMemory += pFormat[1];
1415 pFormat += 2;
1416 desc = pFormat + *(SHORT*)pFormat;
1417 size = EmbeddedComplexSize(pStubMsg, desc);
1418 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1419 if (m) m(pStubMsg, pMemory, desc);
1420 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1421 pMemory += size;
1422 pFormat += 2;
1423 continue;
1424 case RPC_FC_PAD:
1425 break;
1426 default:
1427 FIXME("unhandled format %d\n", *pFormat);
1429 pFormat++;
1432 return pMemory;
1435 unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1436 unsigned char *pMemory,
1437 PFORMAT_STRING pFormat,
1438 PFORMAT_STRING pPointer)
1440 PFORMAT_STRING desc;
1441 NDR_FREE m;
1442 unsigned long size;
1444 while (*pFormat != RPC_FC_END) {
1445 switch (*pFormat) {
1446 case RPC_FC_SHORT:
1447 case RPC_FC_USHORT:
1448 pMemory += 2;
1449 break;
1450 case RPC_FC_LONG:
1451 case RPC_FC_ULONG:
1452 pMemory += 4;
1453 break;
1454 case RPC_FC_POINTER:
1455 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1456 pPointer += 4;
1457 pMemory += 4;
1458 break;
1459 case RPC_FC_ALIGNM4:
1460 ALIGN_POINTER(pMemory, 3);
1461 break;
1462 case RPC_FC_ALIGNM8:
1463 ALIGN_POINTER(pMemory, 7);
1464 break;
1465 case RPC_FC_EMBEDDED_COMPLEX:
1466 pMemory += pFormat[1];
1467 pFormat += 2;
1468 desc = pFormat + *(SHORT*)pFormat;
1469 size = EmbeddedComplexSize(pStubMsg, desc);
1470 m = NdrFreer[*desc & NDR_TABLE_MASK];
1471 if (m) m(pStubMsg, pMemory, desc);
1472 else FIXME("no freer for embedded type %02x\n", *desc);
1473 pMemory += size;
1474 pFormat += 2;
1475 continue;
1476 case RPC_FC_PAD:
1477 break;
1478 default:
1479 FIXME("unhandled format %d\n", *pFormat);
1481 pFormat++;
1484 return pMemory;
1487 unsigned long WINAPI ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
1488 PFORMAT_STRING pFormat)
1490 PFORMAT_STRING desc;
1491 unsigned long size = 0;
1493 while (*pFormat != RPC_FC_END) {
1494 switch (*pFormat) {
1495 case RPC_FC_SHORT:
1496 case RPC_FC_USHORT:
1497 size += 2;
1498 break;
1499 case RPC_FC_LONG:
1500 case RPC_FC_ULONG:
1501 size += 4;
1502 break;
1503 case RPC_FC_POINTER:
1504 size += 4;
1505 break;
1506 case RPC_FC_ALIGNM4:
1507 ALIGN_LENGTH(size, 3);
1508 break;
1509 case RPC_FC_ALIGNM8:
1510 ALIGN_LENGTH(size, 7);
1511 break;
1512 case RPC_FC_EMBEDDED_COMPLEX:
1513 size += pFormat[1];
1514 pFormat += 2;
1515 desc = pFormat + *(SHORT*)pFormat;
1516 size += EmbeddedComplexSize(pStubMsg, desc);
1517 pFormat += 2;
1518 continue;
1519 case RPC_FC_PAD:
1520 break;
1521 default:
1522 FIXME("unhandled format %d\n", *pFormat);
1524 pFormat++;
1527 return size;
1530 /***********************************************************************
1531 * NdrComplexStructMarshall [RPCRT4.@]
1533 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1534 unsigned char *pMemory,
1535 PFORMAT_STRING pFormat)
1537 PFORMAT_STRING conf_array = NULL;
1538 PFORMAT_STRING pointer_desc = NULL;
1539 unsigned char *OldMemory = pStubMsg->Memory;
1541 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1543 pFormat += 4;
1544 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1545 pFormat += 2;
1546 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1547 pFormat += 2;
1549 pStubMsg->Memory = pMemory;
1551 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
1553 if (conf_array)
1554 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
1556 pStubMsg->Memory = OldMemory;
1558 STD_OVERFLOW_CHECK(pStubMsg);
1560 return NULL;
1563 /***********************************************************************
1564 * NdrComplexStructUnmarshall [RPCRT4.@]
1566 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1567 unsigned char **ppMemory,
1568 PFORMAT_STRING pFormat,
1569 unsigned char fMustAlloc)
1571 unsigned size = *(LPWORD)(pFormat+2);
1572 PFORMAT_STRING conf_array = NULL;
1573 PFORMAT_STRING pointer_desc = NULL;
1574 unsigned char *pMemory;
1576 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1578 if (fMustAlloc || !*ppMemory)
1579 *ppMemory = NdrAllocate(pStubMsg, size);
1581 pFormat += 4;
1582 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1583 pFormat += 2;
1584 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1585 pFormat += 2;
1587 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
1589 if (conf_array)
1590 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
1592 return NULL;
1595 /***********************************************************************
1596 * NdrComplexStructBufferSize [RPCRT4.@]
1598 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1599 unsigned char *pMemory,
1600 PFORMAT_STRING pFormat)
1602 PFORMAT_STRING conf_array = NULL;
1603 PFORMAT_STRING pointer_desc = NULL;
1604 unsigned char *OldMemory = pStubMsg->Memory;
1606 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1608 pFormat += 4;
1609 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1610 pFormat += 2;
1611 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1612 pFormat += 2;
1614 pStubMsg->Memory = pMemory;
1616 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
1618 if (conf_array)
1619 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
1621 pStubMsg->Memory = OldMemory;
1624 /***********************************************************************
1625 * NdrComplexStructMemorySize [RPCRT4.@]
1627 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1628 PFORMAT_STRING pFormat)
1630 /* unsigned size = *(LPWORD)(pFormat+2); */
1631 PFORMAT_STRING conf_array = NULL;
1632 PFORMAT_STRING pointer_desc = NULL;
1634 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1636 pFormat += 4;
1637 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1638 pFormat += 2;
1639 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1640 pFormat += 2;
1642 return 0;
1645 /***********************************************************************
1646 * NdrComplexStructFree [RPCRT4.@]
1648 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1649 unsigned char *pMemory,
1650 PFORMAT_STRING pFormat)
1652 PFORMAT_STRING conf_array = NULL;
1653 PFORMAT_STRING pointer_desc = NULL;
1654 unsigned char *OldMemory = pStubMsg->Memory;
1656 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1658 pFormat += 4;
1659 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1660 pFormat += 2;
1661 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1662 pFormat += 2;
1664 pStubMsg->Memory = pMemory;
1666 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
1668 if (conf_array)
1669 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
1671 pStubMsg->Memory = OldMemory;
1674 /***********************************************************************
1675 * NdrConformantArrayMarshall [RPCRT4.@]
1677 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1678 unsigned char *pMemory,
1679 PFORMAT_STRING pFormat)
1681 DWORD size = 0, esize = *(LPWORD)(pFormat+2);
1682 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1683 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1685 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1686 size = pStubMsg->MaxCount;
1688 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
1689 pStubMsg->Buffer += 4;
1691 memcpy(pStubMsg->Buffer, pMemory, size*esize);
1692 pStubMsg->BufferMark = pStubMsg->Buffer;
1693 pStubMsg->Buffer += size*esize;
1695 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1697 STD_OVERFLOW_CHECK(pStubMsg);
1699 return NULL;
1702 /***********************************************************************
1703 * NdrConformantArrayUnmarshall [RPCRT4.@]
1705 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1706 unsigned char **ppMemory,
1707 PFORMAT_STRING pFormat,
1708 unsigned char fMustAlloc)
1710 DWORD size = 0, esize = *(LPWORD)(pFormat+2);
1711 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1712 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1714 pFormat = ReadConformance(pStubMsg, pFormat+4);
1715 size = pStubMsg->MaxCount;
1717 if (fMustAlloc) {
1718 *ppMemory = NdrAllocate(pStubMsg, size*esize);
1719 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
1720 } else {
1721 if (pStubMsg->ReuseBuffer && !*ppMemory)
1722 /* for servers, we may just point straight into the RPC buffer, I think
1723 * (I guess that's what MS does since MIDL code doesn't try to free) */
1724 *ppMemory = pStubMsg->Buffer;
1725 else
1726 /* for clients, memory should be provided by caller */
1727 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
1730 pStubMsg->BufferMark = pStubMsg->Buffer;
1731 pStubMsg->Buffer += size*esize;
1733 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
1735 return NULL;
1738 /***********************************************************************
1739 * NdrConformantArrayBufferSize [RPCRT4.@]
1741 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1742 unsigned char *pMemory,
1743 PFORMAT_STRING pFormat)
1745 DWORD size = 0, esize = *(LPWORD)(pFormat+2);
1746 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1747 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1749 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1750 size = pStubMsg->MaxCount;
1752 pStubMsg->BufferLength += size*esize;
1754 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1757 /***********************************************************************
1758 * NdrConformantArrayMemorySize [RPCRT4.@]
1760 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1761 PFORMAT_STRING pFormat)
1763 DWORD size = 0;
1764 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1765 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1767 pFormat = ReadConformance(pStubMsg, pFormat+4);
1768 size = pStubMsg->MaxCount;
1770 EmbeddedPointerMemorySize(pStubMsg, pFormat);
1772 return 0;
1775 /***********************************************************************
1776 * NdrConformantArrayFree [RPCRT4.@]
1778 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
1779 unsigned char *pMemory,
1780 PFORMAT_STRING pFormat)
1782 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1783 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1785 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
1789 /***********************************************************************
1790 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
1792 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
1793 unsigned char* pMemory,
1794 PFORMAT_STRING pFormat )
1796 FIXME( "stub\n" );
1797 return NULL;
1801 /***********************************************************************
1802 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
1804 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
1805 unsigned char** ppMemory,
1806 PFORMAT_STRING pFormat,
1807 unsigned char fMustAlloc )
1809 FIXME( "stub\n" );
1810 return NULL;
1814 /***********************************************************************
1815 * NdrConformantVaryingArrayFree [RPCRT4.@]
1817 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
1818 unsigned char* pMemory,
1819 PFORMAT_STRING pFormat )
1821 FIXME( "stub\n" );
1825 /***********************************************************************
1826 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
1828 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
1829 unsigned char* pMemory, PFORMAT_STRING pFormat )
1831 FIXME( "stub\n" );
1835 /***********************************************************************
1836 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
1838 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
1839 PFORMAT_STRING pFormat )
1841 FIXME( "stub\n" );
1842 return 0;
1846 /***********************************************************************
1847 * NdrComplexArrayMarshall [RPCRT4.@]
1849 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1850 unsigned char *pMemory,
1851 PFORMAT_STRING pFormat)
1853 DWORD size = 0, count, def;
1854 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1856 def = *(WORD*)&pFormat[2];
1857 pFormat += 4;
1859 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1860 size = pStubMsg->MaxCount;
1861 TRACE("conformance=%ld\n", size);
1863 if (*(DWORD*)pFormat != 0xffffffff)
1864 FIXME("compute variance\n");
1865 pFormat += 4;
1867 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
1868 pStubMsg->Buffer += 4;
1870 for (count=0; count<size; count++)
1871 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
1873 STD_OVERFLOW_CHECK(pStubMsg);
1875 return NULL;
1878 /***********************************************************************
1879 * NdrComplexArrayUnmarshall [RPCRT4.@]
1881 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1882 unsigned char **ppMemory,
1883 PFORMAT_STRING pFormat,
1884 unsigned char fMustAlloc)
1886 DWORD size = 0, count, esize;
1887 unsigned char *pMemory;
1888 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1890 pFormat += 4;
1892 pFormat = ReadConformance(pStubMsg, pFormat);
1893 size = pStubMsg->MaxCount;
1894 TRACE("conformance=%ld\n", size);
1896 pFormat += 4;
1898 esize = ComplexStructSize(pStubMsg, pFormat);
1900 if (fMustAlloc || !*ppMemory)
1901 *ppMemory = NdrAllocate(pStubMsg, size*esize);
1903 pMemory = *ppMemory;
1904 for (count=0; count<size; count++)
1905 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
1907 return NULL;
1910 /***********************************************************************
1911 * NdrComplexArrayBufferSize [RPCRT4.@]
1913 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1914 unsigned char *pMemory,
1915 PFORMAT_STRING pFormat)
1917 DWORD size = 0, count, def;
1918 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1920 def = *(WORD*)&pFormat[2];
1921 pFormat += 4;
1923 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1924 size = pStubMsg->MaxCount;
1925 TRACE("conformance=%ld\n", size);
1927 if (*(DWORD*)pFormat != 0xffffffff)
1928 FIXME("compute variance\n");
1929 pFormat += 4;
1931 for (count=0; count<size; count++)
1932 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1935 /***********************************************************************
1936 * NdrComplexArrayMemorySize [RPCRT4.@]
1938 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1939 PFORMAT_STRING pFormat)
1941 DWORD size = 0;
1942 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1944 pFormat += 4;
1946 pFormat = ReadConformance(pStubMsg, pFormat);
1947 size = pStubMsg->MaxCount;
1948 TRACE("conformance=%ld\n", size);
1950 pFormat += 4;
1952 return 0;
1955 /***********************************************************************
1956 * NdrComplexArrayFree [RPCRT4.@]
1958 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
1959 unsigned char *pMemory,
1960 PFORMAT_STRING pFormat)
1962 DWORD size = 0, count, def;
1963 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1965 def = *(WORD*)&pFormat[2];
1966 pFormat += 4;
1968 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1969 size = pStubMsg->MaxCount;
1970 TRACE("conformance=%ld\n", size);
1972 if (*(DWORD*)pFormat != 0xffffffff)
1973 FIXME("compute variance\n");
1974 pFormat += 4;
1976 for (count=0; count<size; count++)
1977 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
1980 unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
1982 return MAKELONG(pStubMsg->dwDestContext,
1983 pStubMsg->RpcMsg->DataRepresentation);
1986 /***********************************************************************
1987 * NdrUserMarshalMarshall [RPCRT4.@]
1989 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1990 unsigned char *pMemory,
1991 PFORMAT_STRING pFormat)
1993 /* unsigned flags = pFormat[1]; */
1994 unsigned index = *(WORD*)&pFormat[2];
1995 unsigned long uflag = UserMarshalFlags(pStubMsg);
1996 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1997 TRACE("index=%d\n", index);
1999 pStubMsg->Buffer =
2000 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2001 &uflag, pStubMsg->Buffer, pMemory);
2003 STD_OVERFLOW_CHECK(pStubMsg);
2005 return NULL;
2008 /***********************************************************************
2009 * NdrUserMarshalUnmarshall [RPCRT4.@]
2011 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2012 unsigned char **ppMemory,
2013 PFORMAT_STRING pFormat,
2014 unsigned char fMustAlloc)
2016 /* unsigned flags = pFormat[1];*/
2017 unsigned index = *(WORD*)&pFormat[2];
2018 DWORD memsize = *(WORD*)&pFormat[4];
2019 unsigned long uflag = UserMarshalFlags(pStubMsg);
2020 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2021 TRACE("index=%d\n", index);
2023 if (fMustAlloc || !*ppMemory)
2024 *ppMemory = NdrAllocate(pStubMsg, memsize);
2026 pStubMsg->Buffer =
2027 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2028 &uflag, pStubMsg->Buffer, *ppMemory);
2030 return NULL;
2033 /***********************************************************************
2034 * NdrUserMarshalBufferSize [RPCRT4.@]
2036 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2037 unsigned char *pMemory,
2038 PFORMAT_STRING pFormat)
2040 /* unsigned flags = pFormat[1];*/
2041 unsigned index = *(WORD*)&pFormat[2];
2042 DWORD bufsize = *(WORD*)&pFormat[6];
2043 unsigned long uflag = UserMarshalFlags(pStubMsg);
2044 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2045 TRACE("index=%d\n", index);
2047 if (bufsize) {
2048 TRACE("size=%ld\n", bufsize);
2049 pStubMsg->BufferLength += bufsize;
2050 return;
2053 pStubMsg->BufferLength =
2054 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2055 &uflag, pStubMsg->BufferLength, pMemory);
2058 /***********************************************************************
2059 * NdrUserMarshalMemorySize [RPCRT4.@]
2061 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2062 PFORMAT_STRING pFormat)
2064 unsigned index = *(WORD*)&pFormat[2];
2065 /* DWORD memsize = *(WORD*)&pFormat[4]; */
2066 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
2067 TRACE("index=%d\n", index);
2069 return 0;
2072 /***********************************************************************
2073 * NdrUserMarshalFree [RPCRT4.@]
2075 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2076 unsigned char *pMemory,
2077 PFORMAT_STRING pFormat)
2079 /* unsigned flags = pFormat[1]; */
2080 unsigned index = *(WORD*)&pFormat[2];
2081 unsigned long uflag = UserMarshalFlags(pStubMsg);
2082 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2083 TRACE("index=%d\n", index);
2085 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2086 &uflag, pMemory);
2089 /***********************************************************************
2090 * NdrClearOutParameters [RPCRT4.@]
2092 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2093 PFORMAT_STRING pFormat,
2094 void *ArgAddr)
2096 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2099 /***********************************************************************
2100 * NdrConvert [RPCRT4.@]
2102 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2104 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2105 /* FIXME: since this stub doesn't do any converting, the proper behavior
2106 is to raise an exception */
2109 /***********************************************************************
2110 * NdrConvert2 [RPCRT4.@]
2112 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2114 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2115 pStubMsg, pFormat, NumberParams);
2116 /* FIXME: since this stub doesn't do any converting, the proper behavior
2117 is to raise an exception */