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
21 * - figure out whether we *really* got this right
22 * - check for errors and throw exceptions
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
48 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
49 (*((UINT32 *)(pchar)) = (uint32))
51 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
52 (*((UINT32 *)(pchar)))
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) \
64 MAKEWORD(*(pchar), *((pchar)+1)), \
65 MAKEWORD(*((pchar)+2), *((pchar)+3))))
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) \
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)
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)
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); \
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,
113 NdrPointerMarshall, NdrPointerMarshall,
114 NdrPointerMarshall, NdrPointerMarshall,
116 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
118 NdrComplexStructMarshall,
120 NdrConformantArrayMarshall, 0, 0, 0, 0, 0,
121 NdrComplexArrayMarshall,
123 NdrConformantStringMarshall, 0, 0,
124 NdrConformantStringMarshall, 0, 0, 0, 0,
128 NdrInterfacePointerMarshall,
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,
139 NdrPointerUnmarshall, NdrPointerUnmarshall,
140 NdrPointerUnmarshall, NdrPointerUnmarshall,
142 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
144 NdrComplexStructUnmarshall,
146 NdrConformantArrayUnmarshall, 0, 0, 0, 0, 0,
147 NdrComplexArrayUnmarshall,
149 NdrConformantStringUnmarshall, 0, 0,
150 NdrConformantStringUnmarshall, 0, 0, 0, 0,
154 NdrInterfacePointerUnmarshall,
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,
165 NdrPointerBufferSize, NdrPointerBufferSize,
166 NdrPointerBufferSize, NdrPointerBufferSize,
168 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
170 NdrComplexStructBufferSize,
172 NdrConformantArrayBufferSize, 0, 0, 0, 0, 0,
173 NdrComplexArrayBufferSize,
175 NdrConformantStringBufferSize, 0, 0,
176 NdrConformantStringBufferSize, 0, 0, 0, 0,
180 NdrInterfacePointerBufferSize,
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,
191 NdrPointerMemorySize, NdrPointerMemorySize,
192 NdrPointerMemorySize, NdrPointerMemorySize,
194 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
196 NdrComplexStructMemorySize,
198 NdrConformantArrayMemorySize, 0, 0, 0, 0, 0,
199 NdrComplexArrayMemorySize,
201 NdrConformantStringMemorySize, 0, 0,
202 NdrConformantStringMemorySize, 0, 0, 0, 0,
206 NdrInterfacePointerMemorySize,
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,
217 NdrPointerFree, NdrPointerFree,
218 NdrPointerFree, NdrPointerFree,
220 NdrSimpleStructFree, NdrSimpleStructFree,
222 NdrComplexStructFree,
224 NdrConformantArrayFree, 0, 0, 0, 0, 0,
227 0, 0, 0, 0, 0, 0, 0, 0,
231 NdrInterfacePointerFree,
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);
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);
264 if (pFormat[0] == 0xff) {
265 /* null descriptor */
266 pStubMsg->MaxCount = def;
270 switch (pFormat[0] & 0xf0) {
271 case RPC_FC_NORMAL_CONFORMANCE:
272 TRACE("normal conformance, ofs=%ld\n", ofs);
275 case RPC_FC_POINTER_CONFORMANCE:
276 TRACE("pointer conformance, ofs=%ld\n", ofs);
277 ptr = pStubMsg->Memory + ofs;
279 case RPC_FC_TOP_LEVEL_CONFORMANCE:
280 TRACE("toplevel conformance, ofs=%ld\n", ofs);
281 if (pStubMsg->StackTop) {
282 ptr = pStubMsg->StackTop + ofs;
285 /* -Os mode, MaxCount is already set */
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;
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;
305 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
308 switch (pFormat[1]) {
309 case RPC_FC_DEREFERENCE:
312 case RPC_FC_CALLBACK:
313 /* ofs is index into StubDesc->apfnExprEval */
314 FIXME("handle callback\n");
329 data = *(USHORT*)ptr;
338 FIXME("unknown conformance data type %x\n", dtype);
341 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
344 switch (pFormat[1]) {
346 pStubMsg->MaxCount = data;
348 case RPC_FC_DEREFERENCE:
349 /* already handled */
352 FIXME("unknown conformance op %d\n", pFormat[1]);
357 TRACE("resulting conformance is %ld\n", pStubMsg->MaxCount);
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')
373 * data: CHARTYPE[maxlen]
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;
388 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
391 if (*pFormat == RPC_FC_C_CSTRING) {
392 TRACE("string=%s\n", debugstr_a(pszMessage));
393 len = strlen(pszMessage)+1;
396 else if (*pFormat == RPC_FC_C_WSTRING) {
397 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
398 len = strlenW((LPWSTR)pszMessage)+1;
402 ERR("Unhandled string type: %#x\n", *pFormat);
403 /* FIXME: raise an exception. */
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;
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) */
419 memcpy(c, pszMessage, len*esize); /* the string itself */
421 pStubMsg->Buffer = c;
423 STD_OVERFLOW_CHECK(pStubMsg);
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);
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;
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 */
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);
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;
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;
512 ERR("Unhandled string type: %#x\n", *pFormat);
513 /* FIXME: raise an exception */
517 if (pFormat[1] != RPC_FC_PAD) {
518 FIXME("sized string format=%d\n", pFormat[1]);
522 *ppMemory = NdrAllocate(pStubMsg, len*esize + BUFFER_PARANOIA);
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");
563 /***********************************************************************
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];
575 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
576 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
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);
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 */
589 RpcRaiseException(RPC_X_NULL_REF_POINTER);
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;
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);
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 /***********************************************************************
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];
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);
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);
640 case RPC_FC_RP: /* ref pointer (always non-null) */
643 case RPC_FC_UP: /* unique pointer */
644 pointer_id = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
645 pStubMsg->Buffer += 4;
647 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
650 FIXME("unhandled ptr type=%02x\n", type);
651 RpcRaiseException(RPC_X_BAD_STUB_DATA);
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 /***********************************************************************
668 void WINAPI PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
669 unsigned char *Pointer,
670 PFORMAT_STRING pFormat)
672 unsigned type = pFormat[0], attr = pFormat[1];
676 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
677 TRACE("type=%d, attr=%d\n", type, attr);
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);
687 case RPC_FC_RP: /* ref pointer (always non-null) */
691 pStubMsg->BufferLength += 4;
692 /* NULL pointer has no further representation */
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];
718 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
719 TRACE("type=%d, attr=", type); dump_pointer_attr(attr);
721 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
722 else desc = pFormat + *(const SHORT*)pFormat;
723 if (attr & RPC_FC_P_DEREF) {
728 case RPC_FC_RP: /* ref pointer (always non-null) */
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);
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];
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;
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 */
775 case RPC_FC_BOGUS_STRUCT:
776 case RPC_FC_BOGUS_ARRAY:
777 case RPC_FC_USER_MARSHAL:
780 FIXME("unhandled data type=%02x\n", *desc);
782 case RPC_FC_C_CSTRING:
783 case RPC_FC_C_WSTRING:
784 if (pStubMsg->ReuseBuffer) goto notfree;
790 if (attr & RPC_FC_P_ONSTACK) {
791 TRACE("not freeing stack ptr %p\n", Pointer);
794 TRACE("freeing %p\n", Pointer);
795 NdrFree(pStubMsg, Pointer);
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;
817 while (pFormat[0] != RPC_FC_END) {
818 switch (pFormat[0]) {
820 FIXME("unknown repeat type %d\n", pFormat[0]);
821 case RPC_FC_NO_REPEAT:
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];
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;
846 /* ofs doesn't seem to matter in this context */
848 PFORMAT_STRING info = pFormat;
849 unsigned char *membase = pMemory + xofs;
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);
858 pFormat += 8 * count;
861 STD_OVERFLOW_CHECK(pStubMsg);
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;
883 while (pFormat[0] != RPC_FC_END) {
884 switch (pFormat[0]) {
886 FIXME("unknown repeat type %d\n", pFormat[0]);
887 case RPC_FC_NO_REPEAT:
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];
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;
912 /* ofs doesn't seem to matter in this context */
914 PFORMAT_STRING info = pFormat;
915 unsigned char *membase = *ppMemory + xofs;
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);
924 pFormat += 8 * count;
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;
944 while (pFormat[0] != RPC_FC_END) {
945 switch (pFormat[0]) {
947 FIXME("unknown repeat type %d\n", pFormat[0]);
948 case RPC_FC_NO_REPEAT:
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];
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;
973 /* ofs doesn't seem to matter in this context */
975 PFORMAT_STRING info = pFormat;
976 unsigned char *membase = pMemory + xofs;
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);
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;
1002 while (pFormat[0] != RPC_FC_END) {
1003 switch (pFormat[0]) {
1005 FIXME("unknown repeat type %d\n", pFormat[0]);
1006 case RPC_FC_NO_REPEAT:
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];
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;
1031 /* ofs doesn't seem to matter in this context */
1033 PFORMAT_STRING info = pFormat;
1035 for (u=0; u<count; u++,info+=8) {
1036 unsigned char *bufptr = Mark + *(const SHORT*)&info[2];
1037 PointerMemorySize(pStubMsg, bufptr, info+4);
1041 pFormat += 8 * count;
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;
1061 while (pFormat[0] != RPC_FC_END) {
1062 switch (pFormat[0]) {
1064 FIXME("unknown repeat type %d\n", pFormat[0]);
1065 case RPC_FC_NO_REPEAT:
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];
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;
1090 /* ofs doesn't seem to matter in this context */
1092 PFORMAT_STRING info = pFormat;
1093 unsigned char *membase = pMemory + xofs;
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);
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);
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);
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);
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);
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);
1206 *ppMemory = NdrAllocate(pStubMsg, size);
1207 memcpy(*ppMemory, pStubMsg->Buffer, size);
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;
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);
1228 /***********************************************************************
1229 * NdrSimpleStructUnmarshall [RPCRT4.@]
1231 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1232 unsigned char FormatChar )
1238 /***********************************************************************
1239 * NdrSimpleStructUnmarshall [RPCRT4.@]
1241 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1242 unsigned char FormatChar )
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);
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)
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];
1300 FIXME("unhandled embedded type %02x\n", *pFormat);
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;
1315 while (*pFormat != RPC_FC_END) {
1319 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1320 memcpy(pStubMsg->Buffer, pMemory, 2);
1321 pStubMsg->Buffer += 2;
1326 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1327 memcpy(pStubMsg->Buffer, pMemory, 4);
1328 pStubMsg->Buffer += 4;
1331 case RPC_FC_POINTER:
1332 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1333 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1337 case RPC_FC_ALIGNM4:
1338 ALIGN_POINTER(pMemory, 3);
1340 case RPC_FC_ALIGNM8:
1341 ALIGN_POINTER(pMemory, 7);
1343 case RPC_FC_EMBEDDED_COMPLEX:
1344 pMemory += pFormat[1];
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);
1358 FIXME("unhandled format %02x\n", *pFormat);
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;
1376 while (*pFormat != RPC_FC_END) {
1380 memcpy(pMemory, pStubMsg->Buffer, 2);
1381 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1382 pStubMsg->Buffer += 2;
1387 memcpy(pMemory, pStubMsg->Buffer, 4);
1388 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1389 pStubMsg->Buffer += 4;
1392 case RPC_FC_POINTER:
1393 *(unsigned char**)pMemory = NULL;
1394 TRACE("pointer => %p\n", pMemory);
1395 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, fMustAlloc);
1399 case RPC_FC_ALIGNM4:
1400 ALIGN_POINTER(pMemory, 3);
1402 case RPC_FC_ALIGNM8:
1403 ALIGN_POINTER(pMemory, 7);
1405 case RPC_FC_EMBEDDED_COMPLEX:
1406 pMemory += pFormat[1];
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);
1421 FIXME("unhandled format %d\n", *pFormat);
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;
1438 while (*pFormat != RPC_FC_END) {
1442 pStubMsg->BufferLength += 2;
1447 pStubMsg->BufferLength += 4;
1450 case RPC_FC_POINTER:
1451 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1455 case RPC_FC_ALIGNM4:
1456 ALIGN_POINTER(pMemory, 3);
1458 case RPC_FC_ALIGNM8:
1459 ALIGN_POINTER(pMemory, 7);
1461 case RPC_FC_EMBEDDED_COMPLEX:
1462 pMemory += pFormat[1];
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);
1475 FIXME("unhandled format %d\n", *pFormat);
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;
1492 while (*pFormat != RPC_FC_END) {
1502 case RPC_FC_POINTER:
1503 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1507 case RPC_FC_ALIGNM4:
1508 ALIGN_POINTER(pMemory, 3);
1510 case RPC_FC_ALIGNM8:
1511 ALIGN_POINTER(pMemory, 7);
1513 case RPC_FC_EMBEDDED_COMPLEX:
1514 pMemory += pFormat[1];
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);
1527 FIXME("unhandled format %d\n", *pFormat);
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) {
1551 case RPC_FC_POINTER:
1554 case RPC_FC_ALIGNM4:
1555 ALIGN_LENGTH(size, 3);
1557 case RPC_FC_ALIGNM8:
1558 ALIGN_LENGTH(size, 7);
1560 case RPC_FC_EMBEDDED_COMPLEX:
1563 desc = pFormat + *(const SHORT*)pFormat;
1564 size += EmbeddedComplexSize(pStubMsg, desc);
1570 FIXME("unhandled format %d\n", *pFormat);
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);
1592 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1594 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1597 pStubMsg->Memory = pMemory;
1599 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
1602 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
1604 pStubMsg->Memory = OldMemory;
1606 STD_OVERFLOW_CHECK(pStubMsg);
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);
1630 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1632 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1635 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
1638 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
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);
1657 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1659 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1662 pStubMsg->Memory = pMemory;
1664 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
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);
1685 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1687 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
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);
1707 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1709 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1712 pStubMsg->Memory = pMemory;
1714 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
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);
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;
1766 *ppMemory = NdrAllocate(pStubMsg, size*esize);
1767 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
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;
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);
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)
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);
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 )
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 )
1862 /***********************************************************************
1863 * NdrConformantVaryingArrayFree [RPCRT4.@]
1865 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
1866 unsigned char* pMemory,
1867 PFORMAT_STRING pFormat )
1873 /***********************************************************************
1874 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
1876 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
1877 unsigned char* pMemory, PFORMAT_STRING pFormat )
1883 /***********************************************************************
1884 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
1886 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
1887 PFORMAT_STRING pFormat )
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];
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");
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);
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);
1940 pFormat = ReadConformance(pStubMsg, pFormat);
1941 size = pStubMsg->MaxCount;
1942 TRACE("conformance=%ld\n", size);
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);
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];
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");
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)
1990 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1994 pFormat = ReadConformance(pStubMsg, pFormat);
1995 size = pStubMsg->MaxCount;
1996 TRACE("conformance=%ld\n", size);
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];
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");
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);
2048 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2049 &uflag, pStubMsg->Buffer, pMemory);
2051 STD_OVERFLOW_CHECK(pStubMsg);
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);
2075 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2076 &uflag, pStubMsg->Buffer, *ppMemory);
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);
2096 TRACE("size=%ld\n", bufsize);
2097 pStubMsg->BufferLength += bufsize;
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);
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(
2137 /***********************************************************************
2138 * NdrClearOutParameters [RPCRT4.@]
2140 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2141 PFORMAT_STRING pFormat,
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 */