Add support for impersonating a token.
[wine/multimedia.git] / dlls / rpcrt4 / ndr_marshall.c
blob32242652bbe1b798d54ce4f74aefcce8f8add5a2
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 static inline void dump_pointer_attr(unsigned char attr)
550 if (attr & RPC_FC_P_ALLOCALLNODES)
551 TRACE(" RPC_FC_P_ALLOCALLNODES");
552 if (attr & RPC_FC_P_DONTFREE)
553 TRACE(" RPC_FC_P_DONTFREE");
554 if (attr & RPC_FC_P_ONSTACK)
555 TRACE(" RPC_FC_P_ONSTACK");
556 if (attr & RPC_FC_P_SIMPLEPOINTER)
557 TRACE(" RPC_FC_P_SIMPLEPOINTER");
558 if (attr & RPC_FC_P_DEREF)
559 TRACE(" RPC_FC_P_DEREF");
560 TRACE("\n");
563 /***********************************************************************
564 * PointerMarshall
566 void WINAPI PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
567 unsigned char *Buffer,
568 unsigned char *Pointer,
569 PFORMAT_STRING pFormat)
571 unsigned type = pFormat[0], attr = pFormat[1];
572 PFORMAT_STRING desc;
573 NDR_MARSHALL m;
575 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
576 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
577 pFormat += 2;
578 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
579 else desc = pFormat + *(const SHORT*)pFormat;
580 if (attr & RPC_FC_P_DEREF) {
581 Pointer = *(unsigned char**)Pointer;
582 TRACE("deref => %p\n", Pointer);
585 switch (type) {
586 case RPC_FC_RP: /* ref pointer (always non-null) */
587 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
588 if (!Pointer)
589 RpcRaiseException(RPC_X_NULL_REF_POINTER);
590 #endif
591 break;
592 case RPC_FC_UP: /* unique pointer */
593 case RPC_FC_OP: /* object pointer - same as unique here */
594 TRACE("writing %p to buffer\n", Pointer);
595 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, (unsigned long)Pointer);
596 pStubMsg->Buffer += 4;
597 break;
598 case RPC_FC_FP:
599 default:
600 FIXME("unhandled ptr type=%02x\n", type);
601 RpcRaiseException(RPC_X_BAD_STUB_DATA);
604 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
606 if (Pointer) {
607 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
608 if (m) m(pStubMsg, Pointer, desc);
609 else FIXME("no marshaller for data type=%02x\n", *desc);
612 STD_OVERFLOW_CHECK(pStubMsg);
615 /***********************************************************************
616 * PointerUnmarshall
618 void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
619 unsigned char *Buffer,
620 unsigned char **pPointer,
621 PFORMAT_STRING pFormat,
622 unsigned char fMustAlloc)
624 unsigned type = pFormat[0], attr = pFormat[1];
625 PFORMAT_STRING desc;
626 NDR_UNMARSHALL m;
627 DWORD pointer_id = 0;
629 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
630 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
631 pFormat += 2;
632 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
633 else desc = pFormat + *(const SHORT*)pFormat;
634 if (attr & RPC_FC_P_DEREF) {
635 pPointer = *(unsigned char***)pPointer;
636 TRACE("deref => %p\n", pPointer);
639 switch (type) {
640 case RPC_FC_RP: /* ref pointer (always non-null) */
641 pointer_id = ~0UL;
642 break;
643 case RPC_FC_UP: /* unique pointer */
644 pointer_id = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
645 pStubMsg->Buffer += 4;
646 break;
647 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
648 case RPC_FC_FP:
649 default:
650 FIXME("unhandled ptr type=%02x\n", type);
651 RpcRaiseException(RPC_X_BAD_STUB_DATA);
654 *pPointer = NULL;
656 if (pointer_id) {
657 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
658 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
659 else FIXME("no unmarshaller for data type=%02x\n", *desc);
662 TRACE("pointer=%p\n", *pPointer);
665 /***********************************************************************
666 * PointerBufferSize
668 void WINAPI PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
669 unsigned char *Pointer,
670 PFORMAT_STRING pFormat)
672 unsigned type = pFormat[0], attr = pFormat[1];
673 PFORMAT_STRING desc;
674 NDR_BUFFERSIZE m;
676 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
677 TRACE("type=%d, attr=%d\n", type, attr);
678 pFormat += 2;
679 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
680 else desc = pFormat + *(const SHORT*)pFormat;
681 if (attr & RPC_FC_P_DEREF) {
682 Pointer = *(unsigned char**)Pointer;
683 TRACE("deref => %p\n", Pointer);
686 switch (type) {
687 case RPC_FC_RP: /* ref pointer (always non-null) */
688 break;
689 case RPC_FC_OP:
690 case RPC_FC_UP:
691 pStubMsg->BufferLength += 4;
692 /* NULL pointer has no further representation */
693 if (!Pointer)
694 return;
695 break;
696 case RPC_FC_FP:
697 default:
698 FIXME("unhandled ptr type=%02x\n", type);
699 RpcRaiseException(RPC_X_BAD_STUB_DATA);
702 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
703 if (m) m(pStubMsg, Pointer, desc);
704 else FIXME("no buffersizer for data type=%02x\n", *desc);
707 /***********************************************************************
708 * PointerMemorySize [RPCRT4.@]
710 unsigned long WINAPI PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
711 unsigned char *Buffer,
712 PFORMAT_STRING pFormat)
714 unsigned type = pFormat[0], attr = pFormat[1];
715 PFORMAT_STRING desc;
716 NDR_MEMORYSIZE m;
718 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
719 TRACE("type=%d, attr=", type); dump_pointer_attr(attr);
720 pFormat += 2;
721 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
722 else desc = pFormat + *(const SHORT*)pFormat;
723 if (attr & RPC_FC_P_DEREF) {
724 TRACE("deref\n");
727 switch (type) {
728 case RPC_FC_RP: /* ref pointer (always non-null) */
729 break;
730 default:
731 FIXME("unhandled ptr type=%02x\n", type);
732 RpcRaiseException(RPC_X_BAD_STUB_DATA);
735 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
736 if (m) m(pStubMsg, desc);
737 else FIXME("no memorysizer for data type=%02x\n", *desc);
739 return 0;
742 /***********************************************************************
743 * PointerFree [RPCRT4.@]
745 void WINAPI PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
746 unsigned char *Pointer,
747 PFORMAT_STRING pFormat)
749 unsigned type = pFormat[0], attr = pFormat[1];
750 PFORMAT_STRING desc;
751 NDR_FREE m;
753 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
754 TRACE("type=%d, attr=", type); dump_pointer_attr(attr);
755 if (attr & RPC_FC_P_DONTFREE) return;
756 pFormat += 2;
757 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
758 else desc = pFormat + *(const SHORT*)pFormat;
759 if (attr & RPC_FC_P_DEREF) {
760 Pointer = *(unsigned char**)Pointer;
761 TRACE("deref => %p\n", Pointer);
764 if (!Pointer) return;
766 m = NdrFreer[*desc & NDR_TABLE_MASK];
767 if (m) m(pStubMsg, Pointer, desc);
769 /* hmm... is this sensible?
770 * perhaps we should check if the memory comes from NdrAllocate,
771 * and deallocate only if so - checking if the pointer is between
772 * BufferStart and BufferEnd is probably no good since the buffer
773 * may be reallocated when the server wants to marshal the reply */
774 switch (*desc) {
775 case RPC_FC_BOGUS_STRUCT:
776 case RPC_FC_BOGUS_ARRAY:
777 case RPC_FC_USER_MARSHAL:
778 break;
779 default:
780 FIXME("unhandled data type=%02x\n", *desc);
781 case RPC_FC_CARRAY:
782 case RPC_FC_C_CSTRING:
783 case RPC_FC_C_WSTRING:
784 if (pStubMsg->ReuseBuffer) goto notfree;
785 break;
786 case RPC_FC_IP:
787 goto notfree;
790 if (attr & RPC_FC_P_ONSTACK) {
791 TRACE("not freeing stack ptr %p\n", Pointer);
792 return;
794 TRACE("freeing %p\n", Pointer);
795 NdrFree(pStubMsg, Pointer);
796 return;
797 notfree:
798 TRACE("not freeing %p\n", Pointer);
801 /***********************************************************************
802 * EmbeddedPointerMarshall
804 unsigned char * WINAPI EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
805 unsigned char *pMemory,
806 PFORMAT_STRING pFormat)
808 unsigned char *Mark = pStubMsg->BufferMark;
809 unsigned long Offset = pStubMsg->Offset;
810 unsigned ofs, rep, count, stride, xofs;
812 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
814 if (*pFormat != RPC_FC_PP) return NULL;
815 pFormat += 2;
817 while (pFormat[0] != RPC_FC_END) {
818 switch (pFormat[0]) {
819 default:
820 FIXME("unknown repeat type %d\n", pFormat[0]);
821 case RPC_FC_NO_REPEAT:
822 rep = 1;
823 stride = 0;
824 ofs = 0;
825 count = 1;
826 xofs = 0;
827 pFormat += 2;
828 break;
829 case RPC_FC_FIXED_REPEAT:
830 rep = *(const WORD*)&pFormat[2];
831 stride = *(const WORD*)&pFormat[4];
832 ofs = *(const WORD*)&pFormat[6];
833 count = *(const WORD*)&pFormat[8];
834 xofs = 0;
835 pFormat += 10;
836 break;
837 case RPC_FC_VARIABLE_REPEAT:
838 rep = pStubMsg->MaxCount;
839 stride = *(const WORD*)&pFormat[2];
840 ofs = *(const WORD*)&pFormat[4];
841 count = *(const WORD*)&pFormat[6];
842 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
843 pFormat += 8;
844 break;
846 /* ofs doesn't seem to matter in this context */
847 while (rep) {
848 PFORMAT_STRING info = pFormat;
849 unsigned char *membase = pMemory + xofs;
850 unsigned u;
851 for (u=0; u<count; u++,info+=8) {
852 unsigned char *memptr = membase + *(const SHORT*)&info[0];
853 unsigned char *bufptr = Mark + *(const SHORT*)&info[2];
854 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
856 rep--;
858 pFormat += 8 * count;
861 STD_OVERFLOW_CHECK(pStubMsg);
863 return NULL;
866 /***********************************************************************
867 * EmbeddedPointerUnmarshall
869 unsigned char * WINAPI EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
870 unsigned char **ppMemory,
871 PFORMAT_STRING pFormat,
872 unsigned char fMustAlloc)
874 unsigned char *Mark = pStubMsg->BufferMark;
875 unsigned long Offset = pStubMsg->Offset;
876 unsigned ofs, rep, count, stride, xofs;
878 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
880 if (*pFormat != RPC_FC_PP) return NULL;
881 pFormat += 2;
883 while (pFormat[0] != RPC_FC_END) {
884 switch (pFormat[0]) {
885 default:
886 FIXME("unknown repeat type %d\n", pFormat[0]);
887 case RPC_FC_NO_REPEAT:
888 rep = 1;
889 stride = 0;
890 ofs = 0;
891 count = 1;
892 xofs = 0;
893 pFormat += 2;
894 break;
895 case RPC_FC_FIXED_REPEAT:
896 rep = *(const WORD*)&pFormat[2];
897 stride = *(const WORD*)&pFormat[4];
898 ofs = *(const WORD*)&pFormat[6];
899 count = *(const WORD*)&pFormat[8];
900 xofs = 0;
901 pFormat += 10;
902 break;
903 case RPC_FC_VARIABLE_REPEAT:
904 rep = pStubMsg->MaxCount;
905 stride = *(const WORD*)&pFormat[2];
906 ofs = *(const WORD*)&pFormat[4];
907 count = *(const WORD*)&pFormat[6];
908 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
909 pFormat += 8;
910 break;
912 /* ofs doesn't seem to matter in this context */
913 while (rep) {
914 PFORMAT_STRING info = pFormat;
915 unsigned char *membase = *ppMemory + xofs;
916 unsigned u;
917 for (u=0; u<count; u++,info+=8) {
918 unsigned char *memptr = membase + *(const SHORT*)&info[0];
919 unsigned char *bufptr = Mark + *(const SHORT*)&info[2];
920 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, fMustAlloc);
922 rep--;
924 pFormat += 8 * count;
927 return NULL;
930 /***********************************************************************
931 * EmbeddedPointerBufferSize
933 void WINAPI EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
934 unsigned char *pMemory,
935 PFORMAT_STRING pFormat)
937 unsigned long Offset = pStubMsg->Offset;
938 unsigned ofs, rep, count, stride, xofs;
940 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
941 if (*pFormat != RPC_FC_PP) return;
942 pFormat += 2;
944 while (pFormat[0] != RPC_FC_END) {
945 switch (pFormat[0]) {
946 default:
947 FIXME("unknown repeat type %d\n", pFormat[0]);
948 case RPC_FC_NO_REPEAT:
949 rep = 1;
950 stride = 0;
951 ofs = 0;
952 count = 1;
953 xofs = 0;
954 pFormat += 2;
955 break;
956 case RPC_FC_FIXED_REPEAT:
957 rep = *(const WORD*)&pFormat[2];
958 stride = *(const WORD*)&pFormat[4];
959 ofs = *(const WORD*)&pFormat[6];
960 count = *(const WORD*)&pFormat[8];
961 xofs = 0;
962 pFormat += 10;
963 break;
964 case RPC_FC_VARIABLE_REPEAT:
965 rep = pStubMsg->MaxCount;
966 stride = *(const WORD*)&pFormat[2];
967 ofs = *(const WORD*)&pFormat[4];
968 count = *(const WORD*)&pFormat[6];
969 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
970 pFormat += 8;
971 break;
973 /* ofs doesn't seem to matter in this context */
974 while (rep) {
975 PFORMAT_STRING info = pFormat;
976 unsigned char *membase = pMemory + xofs;
977 unsigned u;
978 for (u=0; u<count; u++,info+=8) {
979 unsigned char *memptr = membase + *(const SHORT*)&info[0];
980 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
982 rep--;
984 pFormat += 8 * count;
988 /***********************************************************************
989 * EmbeddedPointerMemorySize
991 unsigned long WINAPI EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
992 PFORMAT_STRING pFormat)
994 unsigned long Offset = pStubMsg->Offset;
995 unsigned char *Mark = pStubMsg->BufferMark;
996 unsigned ofs, rep, count, stride, xofs;
998 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
999 if (*pFormat != RPC_FC_PP) return 0;
1000 pFormat += 2;
1002 while (pFormat[0] != RPC_FC_END) {
1003 switch (pFormat[0]) {
1004 default:
1005 FIXME("unknown repeat type %d\n", pFormat[0]);
1006 case RPC_FC_NO_REPEAT:
1007 rep = 1;
1008 stride = 0;
1009 ofs = 0;
1010 count = 1;
1011 xofs = 0;
1012 pFormat += 2;
1013 break;
1014 case RPC_FC_FIXED_REPEAT:
1015 rep = *(const WORD*)&pFormat[2];
1016 stride = *(const WORD*)&pFormat[4];
1017 ofs = *(const WORD*)&pFormat[6];
1018 count = *(const WORD*)&pFormat[8];
1019 xofs = 0;
1020 pFormat += 10;
1021 break;
1022 case RPC_FC_VARIABLE_REPEAT:
1023 rep = pStubMsg->MaxCount;
1024 stride = *(const WORD*)&pFormat[2];
1025 ofs = *(const WORD*)&pFormat[4];
1026 count = *(const WORD*)&pFormat[6];
1027 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1028 pFormat += 8;
1029 break;
1031 /* ofs doesn't seem to matter in this context */
1032 while (rep) {
1033 PFORMAT_STRING info = pFormat;
1034 unsigned u;
1035 for (u=0; u<count; u++,info+=8) {
1036 unsigned char *bufptr = Mark + *(const SHORT*)&info[2];
1037 PointerMemorySize(pStubMsg, bufptr, info+4);
1039 rep--;
1041 pFormat += 8 * count;
1044 return 0;
1047 /***********************************************************************
1048 * EmbeddedPointerFree
1050 void WINAPI EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1051 unsigned char *pMemory,
1052 PFORMAT_STRING pFormat)
1054 unsigned long Offset = pStubMsg->Offset;
1055 unsigned ofs, rep, count, stride, xofs;
1057 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1058 if (*pFormat != RPC_FC_PP) return;
1059 pFormat += 2;
1061 while (pFormat[0] != RPC_FC_END) {
1062 switch (pFormat[0]) {
1063 default:
1064 FIXME("unknown repeat type %d\n", pFormat[0]);
1065 case RPC_FC_NO_REPEAT:
1066 rep = 1;
1067 stride = 0;
1068 ofs = 0;
1069 count = 1;
1070 xofs = 0;
1071 pFormat += 2;
1072 break;
1073 case RPC_FC_FIXED_REPEAT:
1074 rep = *(const WORD*)&pFormat[2];
1075 stride = *(const WORD*)&pFormat[4];
1076 ofs = *(const WORD*)&pFormat[6];
1077 count = *(const WORD*)&pFormat[8];
1078 xofs = 0;
1079 pFormat += 10;
1080 break;
1081 case RPC_FC_VARIABLE_REPEAT:
1082 rep = pStubMsg->MaxCount;
1083 stride = *(const WORD*)&pFormat[2];
1084 ofs = *(const WORD*)&pFormat[4];
1085 count = *(const WORD*)&pFormat[6];
1086 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1087 pFormat += 8;
1088 break;
1090 /* ofs doesn't seem to matter in this context */
1091 while (rep) {
1092 PFORMAT_STRING info = pFormat;
1093 unsigned char *membase = pMemory + xofs;
1094 unsigned u;
1095 for (u=0; u<count; u++,info+=8) {
1096 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1097 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1099 rep--;
1101 pFormat += 8 * count;
1105 /***********************************************************************
1106 * NdrPointerMarshall [RPCRT4.@]
1108 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1109 unsigned char *pMemory,
1110 PFORMAT_STRING pFormat)
1112 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1114 pStubMsg->BufferMark = pStubMsg->Buffer;
1115 PointerMarshall(pStubMsg, pStubMsg->Buffer, pMemory, pFormat);
1117 STD_OVERFLOW_CHECK(pStubMsg);
1119 return NULL;
1122 /***********************************************************************
1123 * NdrPointerUnmarshall [RPCRT4.@]
1125 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1126 unsigned char **ppMemory,
1127 PFORMAT_STRING pFormat,
1128 unsigned char fMustAlloc)
1130 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1132 pStubMsg->BufferMark = pStubMsg->Buffer;
1133 PointerUnmarshall(pStubMsg, pStubMsg->Buffer, ppMemory, pFormat, fMustAlloc);
1135 return NULL;
1138 /***********************************************************************
1139 * NdrPointerBufferSize [RPCRT4.@]
1141 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1142 unsigned char *pMemory,
1143 PFORMAT_STRING pFormat)
1145 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1146 PointerBufferSize(pStubMsg, pMemory, pFormat);
1149 /***********************************************************************
1150 * NdrPointerMemorySize [RPCRT4.@]
1152 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1153 PFORMAT_STRING pFormat)
1155 /* unsigned size = *(LPWORD)(pFormat+2); */
1156 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1157 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1158 return 0;
1161 /***********************************************************************
1162 * NdrPointerFree [RPCRT4.@]
1164 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1165 unsigned char *pMemory,
1166 PFORMAT_STRING pFormat)
1168 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1169 PointerFree(pStubMsg, pMemory, pFormat);
1172 /***********************************************************************
1173 * NdrSimpleStructMarshall [RPCRT4.@]
1175 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1176 unsigned char *pMemory,
1177 PFORMAT_STRING pFormat)
1179 unsigned size = *(const WORD*)(pFormat+2);
1180 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1182 memcpy(pStubMsg->Buffer, pMemory, size);
1183 pStubMsg->BufferMark = pStubMsg->Buffer;
1184 pStubMsg->Buffer += size;
1186 if (pFormat[0] != RPC_FC_STRUCT)
1187 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1189 STD_OVERFLOW_CHECK(pStubMsg);
1191 return NULL;
1194 /***********************************************************************
1195 * NdrSimpleStructUnmarshall [RPCRT4.@]
1197 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1198 unsigned char **ppMemory,
1199 PFORMAT_STRING pFormat,
1200 unsigned char fMustAlloc)
1202 unsigned size = *(const WORD*)(pFormat+2);
1203 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1205 if (fMustAlloc) {
1206 *ppMemory = NdrAllocate(pStubMsg, size);
1207 memcpy(*ppMemory, pStubMsg->Buffer, size);
1208 } else {
1209 if (pStubMsg->ReuseBuffer && !*ppMemory)
1210 /* for servers, we may just point straight into the RPC buffer, I think
1211 * (I guess that's what MS does since MIDL code doesn't try to free) */
1212 *ppMemory = pStubMsg->Buffer;
1213 else
1214 /* for clients, memory should be provided by caller */
1215 memcpy(*ppMemory, pStubMsg->Buffer, size);
1218 pStubMsg->BufferMark = pStubMsg->Buffer;
1219 pStubMsg->Buffer += size;
1221 if (pFormat[0] != RPC_FC_STRUCT)
1222 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1224 return NULL;
1228 /***********************************************************************
1229 * NdrSimpleStructUnmarshall [RPCRT4.@]
1231 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1232 unsigned char FormatChar )
1234 FIXME("stub\n");
1238 /***********************************************************************
1239 * NdrSimpleStructUnmarshall [RPCRT4.@]
1241 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1242 unsigned char FormatChar )
1244 FIXME("stub\n");
1248 /***********************************************************************
1249 * NdrSimpleStructBufferSize [RPCRT4.@]
1251 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1252 unsigned char *pMemory,
1253 PFORMAT_STRING pFormat)
1255 unsigned size = *(const WORD*)(pFormat+2);
1256 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1257 pStubMsg->BufferLength += size;
1258 if (pFormat[0] != RPC_FC_STRUCT)
1259 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1262 /***********************************************************************
1263 * NdrSimpleStructMemorySize [RPCRT4.@]
1265 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1266 PFORMAT_STRING pFormat)
1268 /* unsigned size = *(LPWORD)(pFormat+2); */
1269 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1270 if (pFormat[0] != RPC_FC_STRUCT)
1271 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1272 return 0;
1275 /***********************************************************************
1276 * NdrSimpleStructFree [RPCRT4.@]
1278 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1279 unsigned char *pMemory,
1280 PFORMAT_STRING pFormat)
1282 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1283 if (pFormat[0] != RPC_FC_STRUCT)
1284 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1288 unsigned long WINAPI EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1289 PFORMAT_STRING pFormat)
1291 switch (*pFormat) {
1292 case RPC_FC_STRUCT:
1293 case RPC_FC_PSTRUCT:
1294 case RPC_FC_CSTRUCT:
1295 case RPC_FC_BOGUS_STRUCT:
1296 return *(const WORD*)&pFormat[2];
1297 case RPC_FC_USER_MARSHAL:
1298 return *(const WORD*)&pFormat[4];
1299 default:
1300 FIXME("unhandled embedded type %02x\n", *pFormat);
1302 return 0;
1306 unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1307 unsigned char *pMemory,
1308 PFORMAT_STRING pFormat,
1309 PFORMAT_STRING pPointer)
1311 PFORMAT_STRING desc;
1312 NDR_MARSHALL m;
1313 unsigned long size;
1315 while (*pFormat != RPC_FC_END) {
1316 switch (*pFormat) {
1317 case RPC_FC_SHORT:
1318 case RPC_FC_USHORT:
1319 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1320 memcpy(pStubMsg->Buffer, pMemory, 2);
1321 pStubMsg->Buffer += 2;
1322 pMemory += 2;
1323 break;
1324 case RPC_FC_LONG:
1325 case RPC_FC_ULONG:
1326 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1327 memcpy(pStubMsg->Buffer, pMemory, 4);
1328 pStubMsg->Buffer += 4;
1329 pMemory += 4;
1330 break;
1331 case RPC_FC_POINTER:
1332 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1333 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1334 pPointer += 4;
1335 pMemory += 4;
1336 break;
1337 case RPC_FC_ALIGNM4:
1338 ALIGN_POINTER(pMemory, 3);
1339 break;
1340 case RPC_FC_ALIGNM8:
1341 ALIGN_POINTER(pMemory, 7);
1342 break;
1343 case RPC_FC_EMBEDDED_COMPLEX:
1344 pMemory += pFormat[1];
1345 pFormat += 2;
1346 desc = pFormat + *(const SHORT*)pFormat;
1347 size = EmbeddedComplexSize(pStubMsg, desc);
1348 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1349 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1350 if (m) m(pStubMsg, pMemory, desc);
1351 else FIXME("no marshaller for embedded type %02x\n", *desc);
1352 pMemory += size;
1353 pFormat += 2;
1354 continue;
1355 case RPC_FC_PAD:
1356 break;
1357 default:
1358 FIXME("unhandled format %02x\n", *pFormat);
1360 pFormat++;
1363 return pMemory;
1366 unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1367 unsigned char *pMemory,
1368 PFORMAT_STRING pFormat,
1369 PFORMAT_STRING pPointer,
1370 unsigned char fMustAlloc)
1372 PFORMAT_STRING desc;
1373 NDR_UNMARSHALL m;
1374 unsigned long size;
1376 while (*pFormat != RPC_FC_END) {
1377 switch (*pFormat) {
1378 case RPC_FC_SHORT:
1379 case RPC_FC_USHORT:
1380 memcpy(pMemory, pStubMsg->Buffer, 2);
1381 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1382 pStubMsg->Buffer += 2;
1383 pMemory += 2;
1384 break;
1385 case RPC_FC_LONG:
1386 case RPC_FC_ULONG:
1387 memcpy(pMemory, pStubMsg->Buffer, 4);
1388 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1389 pStubMsg->Buffer += 4;
1390 pMemory += 4;
1391 break;
1392 case RPC_FC_POINTER:
1393 *(unsigned char**)pMemory = NULL;
1394 TRACE("pointer => %p\n", pMemory);
1395 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, fMustAlloc);
1396 pPointer += 4;
1397 pMemory += 4;
1398 break;
1399 case RPC_FC_ALIGNM4:
1400 ALIGN_POINTER(pMemory, 3);
1401 break;
1402 case RPC_FC_ALIGNM8:
1403 ALIGN_POINTER(pMemory, 7);
1404 break;
1405 case RPC_FC_EMBEDDED_COMPLEX:
1406 pMemory += pFormat[1];
1407 pFormat += 2;
1408 desc = pFormat + *(const SHORT*)pFormat;
1409 size = EmbeddedComplexSize(pStubMsg, desc);
1410 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1411 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1412 memset(pMemory, 0, size); /* just in case */
1413 if (m) m(pStubMsg, &pMemory, desc, fMustAlloc);
1414 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1415 pMemory += size;
1416 pFormat += 2;
1417 continue;
1418 case RPC_FC_PAD:
1419 break;
1420 default:
1421 FIXME("unhandled format %d\n", *pFormat);
1423 pFormat++;
1426 return pMemory;
1429 unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1430 unsigned char *pMemory,
1431 PFORMAT_STRING pFormat,
1432 PFORMAT_STRING pPointer)
1434 PFORMAT_STRING desc;
1435 NDR_BUFFERSIZE m;
1436 unsigned long size;
1438 while (*pFormat != RPC_FC_END) {
1439 switch (*pFormat) {
1440 case RPC_FC_SHORT:
1441 case RPC_FC_USHORT:
1442 pStubMsg->BufferLength += 2;
1443 pMemory += 2;
1444 break;
1445 case RPC_FC_LONG:
1446 case RPC_FC_ULONG:
1447 pStubMsg->BufferLength += 4;
1448 pMemory += 4;
1449 break;
1450 case RPC_FC_POINTER:
1451 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1452 pPointer += 4;
1453 pMemory += 4;
1454 break;
1455 case RPC_FC_ALIGNM4:
1456 ALIGN_POINTER(pMemory, 3);
1457 break;
1458 case RPC_FC_ALIGNM8:
1459 ALIGN_POINTER(pMemory, 7);
1460 break;
1461 case RPC_FC_EMBEDDED_COMPLEX:
1462 pMemory += pFormat[1];
1463 pFormat += 2;
1464 desc = pFormat + *(const SHORT*)pFormat;
1465 size = EmbeddedComplexSize(pStubMsg, desc);
1466 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1467 if (m) m(pStubMsg, pMemory, desc);
1468 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1469 pMemory += size;
1470 pFormat += 2;
1471 continue;
1472 case RPC_FC_PAD:
1473 break;
1474 default:
1475 FIXME("unhandled format %d\n", *pFormat);
1477 pFormat++;
1480 return pMemory;
1483 unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1484 unsigned char *pMemory,
1485 PFORMAT_STRING pFormat,
1486 PFORMAT_STRING pPointer)
1488 PFORMAT_STRING desc;
1489 NDR_FREE m;
1490 unsigned long size;
1492 while (*pFormat != RPC_FC_END) {
1493 switch (*pFormat) {
1494 case RPC_FC_SHORT:
1495 case RPC_FC_USHORT:
1496 pMemory += 2;
1497 break;
1498 case RPC_FC_LONG:
1499 case RPC_FC_ULONG:
1500 pMemory += 4;
1501 break;
1502 case RPC_FC_POINTER:
1503 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1504 pPointer += 4;
1505 pMemory += 4;
1506 break;
1507 case RPC_FC_ALIGNM4:
1508 ALIGN_POINTER(pMemory, 3);
1509 break;
1510 case RPC_FC_ALIGNM8:
1511 ALIGN_POINTER(pMemory, 7);
1512 break;
1513 case RPC_FC_EMBEDDED_COMPLEX:
1514 pMemory += pFormat[1];
1515 pFormat += 2;
1516 desc = pFormat + *(const SHORT*)pFormat;
1517 size = EmbeddedComplexSize(pStubMsg, desc);
1518 m = NdrFreer[*desc & NDR_TABLE_MASK];
1519 if (m) m(pStubMsg, pMemory, desc);
1520 else FIXME("no freer for embedded type %02x\n", *desc);
1521 pMemory += size;
1522 pFormat += 2;
1523 continue;
1524 case RPC_FC_PAD:
1525 break;
1526 default:
1527 FIXME("unhandled format %d\n", *pFormat);
1529 pFormat++;
1532 return pMemory;
1535 unsigned long WINAPI ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
1536 PFORMAT_STRING pFormat)
1538 PFORMAT_STRING desc;
1539 unsigned long size = 0;
1541 while (*pFormat != RPC_FC_END) {
1542 switch (*pFormat) {
1543 case RPC_FC_SHORT:
1544 case RPC_FC_USHORT:
1545 size += 2;
1546 break;
1547 case RPC_FC_LONG:
1548 case RPC_FC_ULONG:
1549 size += 4;
1550 break;
1551 case RPC_FC_POINTER:
1552 size += 4;
1553 break;
1554 case RPC_FC_ALIGNM4:
1555 ALIGN_LENGTH(size, 3);
1556 break;
1557 case RPC_FC_ALIGNM8:
1558 ALIGN_LENGTH(size, 7);
1559 break;
1560 case RPC_FC_EMBEDDED_COMPLEX:
1561 size += pFormat[1];
1562 pFormat += 2;
1563 desc = pFormat + *(const SHORT*)pFormat;
1564 size += EmbeddedComplexSize(pStubMsg, desc);
1565 pFormat += 2;
1566 continue;
1567 case RPC_FC_PAD:
1568 break;
1569 default:
1570 FIXME("unhandled format %d\n", *pFormat);
1572 pFormat++;
1575 return size;
1578 /***********************************************************************
1579 * NdrComplexStructMarshall [RPCRT4.@]
1581 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1582 unsigned char *pMemory,
1583 PFORMAT_STRING pFormat)
1585 PFORMAT_STRING conf_array = NULL;
1586 PFORMAT_STRING pointer_desc = NULL;
1587 unsigned char *OldMemory = pStubMsg->Memory;
1589 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1591 pFormat += 4;
1592 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1593 pFormat += 2;
1594 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1595 pFormat += 2;
1597 pStubMsg->Memory = pMemory;
1599 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
1601 if (conf_array)
1602 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
1604 pStubMsg->Memory = OldMemory;
1606 STD_OVERFLOW_CHECK(pStubMsg);
1608 return NULL;
1611 /***********************************************************************
1612 * NdrComplexStructUnmarshall [RPCRT4.@]
1614 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1615 unsigned char **ppMemory,
1616 PFORMAT_STRING pFormat,
1617 unsigned char fMustAlloc)
1619 unsigned size = *(const WORD*)(pFormat+2);
1620 PFORMAT_STRING conf_array = NULL;
1621 PFORMAT_STRING pointer_desc = NULL;
1622 unsigned char *pMemory;
1624 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1626 if (fMustAlloc || !*ppMemory)
1627 *ppMemory = NdrAllocate(pStubMsg, size);
1629 pFormat += 4;
1630 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1631 pFormat += 2;
1632 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1633 pFormat += 2;
1635 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
1637 if (conf_array)
1638 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
1640 return NULL;
1643 /***********************************************************************
1644 * NdrComplexStructBufferSize [RPCRT4.@]
1646 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1647 unsigned char *pMemory,
1648 PFORMAT_STRING pFormat)
1650 PFORMAT_STRING conf_array = NULL;
1651 PFORMAT_STRING pointer_desc = NULL;
1652 unsigned char *OldMemory = pStubMsg->Memory;
1654 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1656 pFormat += 4;
1657 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1658 pFormat += 2;
1659 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1660 pFormat += 2;
1662 pStubMsg->Memory = pMemory;
1664 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
1666 if (conf_array)
1667 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
1669 pStubMsg->Memory = OldMemory;
1672 /***********************************************************************
1673 * NdrComplexStructMemorySize [RPCRT4.@]
1675 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1676 PFORMAT_STRING pFormat)
1678 /* unsigned size = *(LPWORD)(pFormat+2); */
1679 PFORMAT_STRING conf_array = NULL;
1680 PFORMAT_STRING pointer_desc = NULL;
1682 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1684 pFormat += 4;
1685 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1686 pFormat += 2;
1687 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1688 pFormat += 2;
1690 return 0;
1693 /***********************************************************************
1694 * NdrComplexStructFree [RPCRT4.@]
1696 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1697 unsigned char *pMemory,
1698 PFORMAT_STRING pFormat)
1700 PFORMAT_STRING conf_array = NULL;
1701 PFORMAT_STRING pointer_desc = NULL;
1702 unsigned char *OldMemory = pStubMsg->Memory;
1704 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1706 pFormat += 4;
1707 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1708 pFormat += 2;
1709 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1710 pFormat += 2;
1712 pStubMsg->Memory = pMemory;
1714 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
1716 if (conf_array)
1717 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
1719 pStubMsg->Memory = OldMemory;
1722 /***********************************************************************
1723 * NdrConformantArrayMarshall [RPCRT4.@]
1725 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1726 unsigned char *pMemory,
1727 PFORMAT_STRING pFormat)
1729 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
1730 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1731 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1733 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1734 size = pStubMsg->MaxCount;
1736 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
1737 pStubMsg->Buffer += 4;
1739 memcpy(pStubMsg->Buffer, pMemory, size*esize);
1740 pStubMsg->BufferMark = pStubMsg->Buffer;
1741 pStubMsg->Buffer += size*esize;
1743 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1745 STD_OVERFLOW_CHECK(pStubMsg);
1747 return NULL;
1750 /***********************************************************************
1751 * NdrConformantArrayUnmarshall [RPCRT4.@]
1753 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1754 unsigned char **ppMemory,
1755 PFORMAT_STRING pFormat,
1756 unsigned char fMustAlloc)
1758 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
1759 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1760 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1762 pFormat = ReadConformance(pStubMsg, pFormat+4);
1763 size = pStubMsg->MaxCount;
1765 if (fMustAlloc) {
1766 *ppMemory = NdrAllocate(pStubMsg, size*esize);
1767 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
1768 } else {
1769 if (pStubMsg->ReuseBuffer && !*ppMemory)
1770 /* for servers, we may just point straight into the RPC buffer, I think
1771 * (I guess that's what MS does since MIDL code doesn't try to free) */
1772 *ppMemory = pStubMsg->Buffer;
1773 else
1774 /* for clients, memory should be provided by caller */
1775 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
1778 pStubMsg->BufferMark = pStubMsg->Buffer;
1779 pStubMsg->Buffer += size*esize;
1781 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
1783 return NULL;
1786 /***********************************************************************
1787 * NdrConformantArrayBufferSize [RPCRT4.@]
1789 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1790 unsigned char *pMemory,
1791 PFORMAT_STRING pFormat)
1793 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
1794 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1795 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1797 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1798 size = pStubMsg->MaxCount;
1800 pStubMsg->BufferLength += size*esize;
1802 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1805 /***********************************************************************
1806 * NdrConformantArrayMemorySize [RPCRT4.@]
1808 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1809 PFORMAT_STRING pFormat)
1811 DWORD size = 0;
1812 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1813 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1815 pFormat = ReadConformance(pStubMsg, pFormat+4);
1816 size = pStubMsg->MaxCount;
1818 EmbeddedPointerMemorySize(pStubMsg, pFormat);
1820 return 0;
1823 /***********************************************************************
1824 * NdrConformantArrayFree [RPCRT4.@]
1826 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
1827 unsigned char *pMemory,
1828 PFORMAT_STRING pFormat)
1830 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1831 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1833 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
1837 /***********************************************************************
1838 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
1840 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
1841 unsigned char* pMemory,
1842 PFORMAT_STRING pFormat )
1844 FIXME( "stub\n" );
1845 return NULL;
1849 /***********************************************************************
1850 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
1852 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
1853 unsigned char** ppMemory,
1854 PFORMAT_STRING pFormat,
1855 unsigned char fMustAlloc )
1857 FIXME( "stub\n" );
1858 return NULL;
1862 /***********************************************************************
1863 * NdrConformantVaryingArrayFree [RPCRT4.@]
1865 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
1866 unsigned char* pMemory,
1867 PFORMAT_STRING pFormat )
1869 FIXME( "stub\n" );
1873 /***********************************************************************
1874 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
1876 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
1877 unsigned char* pMemory, PFORMAT_STRING pFormat )
1879 FIXME( "stub\n" );
1883 /***********************************************************************
1884 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
1886 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
1887 PFORMAT_STRING pFormat )
1889 FIXME( "stub\n" );
1890 return 0;
1894 /***********************************************************************
1895 * NdrComplexArrayMarshall [RPCRT4.@]
1897 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1898 unsigned char *pMemory,
1899 PFORMAT_STRING pFormat)
1901 DWORD size = 0, count, def;
1902 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1904 def = *(const WORD*)&pFormat[2];
1905 pFormat += 4;
1907 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1908 size = pStubMsg->MaxCount;
1909 TRACE("conformance=%ld\n", size);
1911 if (*(const DWORD*)pFormat != 0xffffffff)
1912 FIXME("compute variance\n");
1913 pFormat += 4;
1915 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
1916 pStubMsg->Buffer += 4;
1918 for (count=0; count<size; count++)
1919 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
1921 STD_OVERFLOW_CHECK(pStubMsg);
1923 return NULL;
1926 /***********************************************************************
1927 * NdrComplexArrayUnmarshall [RPCRT4.@]
1929 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1930 unsigned char **ppMemory,
1931 PFORMAT_STRING pFormat,
1932 unsigned char fMustAlloc)
1934 DWORD size = 0, count, esize;
1935 unsigned char *pMemory;
1936 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1938 pFormat += 4;
1940 pFormat = ReadConformance(pStubMsg, pFormat);
1941 size = pStubMsg->MaxCount;
1942 TRACE("conformance=%ld\n", size);
1944 pFormat += 4;
1946 esize = ComplexStructSize(pStubMsg, pFormat);
1948 if (fMustAlloc || !*ppMemory)
1949 *ppMemory = NdrAllocate(pStubMsg, size*esize);
1951 pMemory = *ppMemory;
1952 for (count=0; count<size; count++)
1953 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
1955 return NULL;
1958 /***********************************************************************
1959 * NdrComplexArrayBufferSize [RPCRT4.@]
1961 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1962 unsigned char *pMemory,
1963 PFORMAT_STRING pFormat)
1965 DWORD size = 0, count, def;
1966 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1968 def = *(const WORD*)&pFormat[2];
1969 pFormat += 4;
1971 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1972 size = pStubMsg->MaxCount;
1973 TRACE("conformance=%ld\n", size);
1975 if (*(const DWORD*)pFormat != 0xffffffff)
1976 FIXME("compute variance\n");
1977 pFormat += 4;
1979 for (count=0; count<size; count++)
1980 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1983 /***********************************************************************
1984 * NdrComplexArrayMemorySize [RPCRT4.@]
1986 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1987 PFORMAT_STRING pFormat)
1989 DWORD size = 0;
1990 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1992 pFormat += 4;
1994 pFormat = ReadConformance(pStubMsg, pFormat);
1995 size = pStubMsg->MaxCount;
1996 TRACE("conformance=%ld\n", size);
1998 pFormat += 4;
2000 return 0;
2003 /***********************************************************************
2004 * NdrComplexArrayFree [RPCRT4.@]
2006 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2007 unsigned char *pMemory,
2008 PFORMAT_STRING pFormat)
2010 DWORD size = 0, count, def;
2011 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2013 def = *(const WORD*)&pFormat[2];
2014 pFormat += 4;
2016 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2017 size = pStubMsg->MaxCount;
2018 TRACE("conformance=%ld\n", size);
2020 if (*(const DWORD*)pFormat != 0xffffffff)
2021 FIXME("compute variance\n");
2022 pFormat += 4;
2024 for (count=0; count<size; count++)
2025 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2028 unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2030 return MAKELONG(pStubMsg->dwDestContext,
2031 pStubMsg->RpcMsg->DataRepresentation);
2034 /***********************************************************************
2035 * NdrUserMarshalMarshall [RPCRT4.@]
2037 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2038 unsigned char *pMemory,
2039 PFORMAT_STRING pFormat)
2041 /* unsigned flags = pFormat[1]; */
2042 unsigned index = *(const WORD*)&pFormat[2];
2043 unsigned long uflag = UserMarshalFlags(pStubMsg);
2044 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2045 TRACE("index=%d\n", index);
2047 pStubMsg->Buffer =
2048 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2049 &uflag, pStubMsg->Buffer, pMemory);
2051 STD_OVERFLOW_CHECK(pStubMsg);
2053 return NULL;
2056 /***********************************************************************
2057 * NdrUserMarshalUnmarshall [RPCRT4.@]
2059 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2060 unsigned char **ppMemory,
2061 PFORMAT_STRING pFormat,
2062 unsigned char fMustAlloc)
2064 /* unsigned flags = pFormat[1];*/
2065 unsigned index = *(const WORD*)&pFormat[2];
2066 DWORD memsize = *(const WORD*)&pFormat[4];
2067 unsigned long uflag = UserMarshalFlags(pStubMsg);
2068 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2069 TRACE("index=%d\n", index);
2071 if (fMustAlloc || !*ppMemory)
2072 *ppMemory = NdrAllocate(pStubMsg, memsize);
2074 pStubMsg->Buffer =
2075 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2076 &uflag, pStubMsg->Buffer, *ppMemory);
2078 return NULL;
2081 /***********************************************************************
2082 * NdrUserMarshalBufferSize [RPCRT4.@]
2084 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2085 unsigned char *pMemory,
2086 PFORMAT_STRING pFormat)
2088 /* unsigned flags = pFormat[1];*/
2089 unsigned index = *(const WORD*)&pFormat[2];
2090 DWORD bufsize = *(const WORD*)&pFormat[6];
2091 unsigned long uflag = UserMarshalFlags(pStubMsg);
2092 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2093 TRACE("index=%d\n", index);
2095 if (bufsize) {
2096 TRACE("size=%ld\n", bufsize);
2097 pStubMsg->BufferLength += bufsize;
2098 return;
2101 pStubMsg->BufferLength =
2102 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2103 &uflag, pStubMsg->BufferLength, pMemory);
2106 /***********************************************************************
2107 * NdrUserMarshalMemorySize [RPCRT4.@]
2109 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2110 PFORMAT_STRING pFormat)
2112 unsigned index = *(const WORD*)&pFormat[2];
2113 /* DWORD memsize = *(const WORD*)&pFormat[4]; */
2114 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
2115 TRACE("index=%d\n", index);
2117 return 0;
2120 /***********************************************************************
2121 * NdrUserMarshalFree [RPCRT4.@]
2123 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2124 unsigned char *pMemory,
2125 PFORMAT_STRING pFormat)
2127 /* unsigned flags = pFormat[1]; */
2128 unsigned index = *(const WORD*)&pFormat[2];
2129 unsigned long uflag = UserMarshalFlags(pStubMsg);
2130 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2131 TRACE("index=%d\n", index);
2133 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2134 &uflag, pMemory);
2137 /***********************************************************************
2138 * NdrClearOutParameters [RPCRT4.@]
2140 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2141 PFORMAT_STRING pFormat,
2142 void *ArgAddr)
2144 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2147 /***********************************************************************
2148 * NdrConvert [RPCRT4.@]
2150 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2152 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2153 /* FIXME: since this stub doesn't do any converting, the proper behavior
2154 is to raise an exception */
2157 /***********************************************************************
2158 * NdrConvert2 [RPCRT4.@]
2160 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2162 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2163 pStubMsg, pFormat, NumberParams);
2164 /* FIXME: since this stub doesn't do any converting, the proper behavior
2165 is to raise an exception */