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 /***********************************************************************
551 void WINAPI PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
552 unsigned char *Buffer,
553 unsigned char *Pointer,
554 PFORMAT_STRING pFormat)
556 unsigned type = pFormat[0], attr = pFormat[1];
560 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
561 TRACE("type=%d, attr=%d\n", type, attr);
563 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
564 else desc = pFormat + *(SHORT*)pFormat;
565 if (attr & RPC_FC_P_DEREF) {
566 Pointer = *(unsigned char**)Pointer;
567 TRACE("deref => %p\n", Pointer);
570 *(LPVOID*)Buffer = 0;
573 case RPC_FC_RP: /* ref pointer (always non-null) */
576 FIXME("unhandled ptr type=%02x\n", type);
579 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
580 if (m) m(pStubMsg, Pointer, desc);
581 else FIXME("no marshaller for data type=%02x\n", *desc);
583 STD_OVERFLOW_CHECK(pStubMsg);
586 /***********************************************************************
589 void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
590 unsigned char *Buffer,
591 unsigned char **pPointer,
592 PFORMAT_STRING pFormat,
593 unsigned char fMustAlloc)
595 unsigned type = pFormat[0], attr = pFormat[1];
599 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
600 TRACE("type=%d, attr=%d\n", type, attr);
602 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
603 else desc = pFormat + *(SHORT*)pFormat;
604 if (attr & RPC_FC_P_DEREF) {
605 pPointer = *(unsigned char***)pPointer;
606 TRACE("deref => %p\n", pPointer);
610 case RPC_FC_RP: /* ref pointer (always non-null) */
613 FIXME("unhandled ptr type=%02x\n", type);
618 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
619 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
620 else FIXME("no unmarshaller for data type=%02x\n", *desc);
621 TRACE("pointer=%p\n", *pPointer);
624 /***********************************************************************
627 void WINAPI PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
628 unsigned char *Pointer,
629 PFORMAT_STRING pFormat)
631 unsigned type = pFormat[0], attr = pFormat[1];
635 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
636 TRACE("type=%d, attr=%d\n", type, attr);
638 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
639 else desc = pFormat + *(SHORT*)pFormat;
640 if (attr & RPC_FC_P_DEREF) {
641 Pointer = *(unsigned char**)Pointer;
642 TRACE("deref => %p\n", Pointer);
646 case RPC_FC_RP: /* ref pointer (always non-null) */
649 FIXME("unhandled ptr type=%02x\n", type);
652 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
653 if (m) m(pStubMsg, Pointer, desc);
654 else FIXME("no buffersizer for data type=%02x\n", *desc);
657 /***********************************************************************
658 * PointerMemorySize [RPCRT4.@]
660 unsigned long WINAPI PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
661 unsigned char *Buffer,
662 PFORMAT_STRING pFormat)
664 unsigned type = pFormat[0], attr = pFormat[1];
668 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
669 TRACE("type=%d, attr=%d\n", type, attr);
671 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
672 else desc = pFormat + *(SHORT*)pFormat;
673 if (attr & RPC_FC_P_DEREF) {
678 case RPC_FC_RP: /* ref pointer (always non-null) */
681 FIXME("unhandled ptr type=%02x\n", type);
684 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
685 if (m) m(pStubMsg, desc);
686 else FIXME("no memorysizer for data type=%02x\n", *desc);
691 /***********************************************************************
692 * PointerFree [RPCRT4.@]
694 void WINAPI PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
695 unsigned char *Pointer,
696 PFORMAT_STRING pFormat)
698 unsigned type = pFormat[0], attr = pFormat[1];
702 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
703 TRACE("type=%d, attr=%d\n", type, attr);
704 if (attr & RPC_FC_P_DONTFREE) return;
706 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
707 else desc = pFormat + *(SHORT*)pFormat;
708 if (attr & RPC_FC_P_DEREF) {
709 Pointer = *(unsigned char**)Pointer;
710 TRACE("deref => %p\n", Pointer);
713 if (!Pointer) return;
715 m = NdrFreer[*desc & NDR_TABLE_MASK];
716 if (m) m(pStubMsg, Pointer, desc);
718 /* hmm... is this sensible?
719 * perhaps we should check if the memory comes from NdrAllocate,
720 * and deallocate only if so - checking if the pointer is between
721 * BufferStart and BufferEnd is probably no good since the buffer
722 * may be reallocated when the server wants to marshal the reply */
724 case RPC_FC_BOGUS_STRUCT:
725 case RPC_FC_BOGUS_ARRAY:
726 case RPC_FC_USER_MARSHAL:
729 FIXME("unhandled data type=%02x\n", *desc);
731 case RPC_FC_C_CSTRING:
732 case RPC_FC_C_WSTRING:
733 if (pStubMsg->ReuseBuffer) goto notfree;
739 if (attr & RPC_FC_P_ONSTACK) {
740 TRACE("not freeing stack ptr %p\n", Pointer);
743 TRACE("freeing %p\n", Pointer);
744 NdrFree(pStubMsg, Pointer);
747 TRACE("not freeing %p\n", Pointer);
750 /***********************************************************************
751 * EmbeddedPointerMarshall
753 unsigned char * WINAPI EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
754 unsigned char *pMemory,
755 PFORMAT_STRING pFormat)
757 unsigned char *Mark = pStubMsg->BufferMark;
758 unsigned long Offset = pStubMsg->Offset;
759 unsigned ofs, rep, count, stride, xofs;
761 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
763 if (*pFormat != RPC_FC_PP) return NULL;
766 while (pFormat[0] != RPC_FC_END) {
767 switch (pFormat[0]) {
769 FIXME("unknown repeat type %d\n", pFormat[0]);
770 case RPC_FC_NO_REPEAT:
778 case RPC_FC_FIXED_REPEAT:
779 rep = *(WORD*)&pFormat[2];
780 stride = *(WORD*)&pFormat[4];
781 ofs = *(WORD*)&pFormat[6];
782 count = *(WORD*)&pFormat[8];
786 case RPC_FC_VARIABLE_REPEAT:
787 rep = pStubMsg->MaxCount;
788 stride = *(WORD*)&pFormat[2];
789 ofs = *(WORD*)&pFormat[4];
790 count = *(WORD*)&pFormat[6];
791 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
795 /* ofs doesn't seem to matter in this context */
797 PFORMAT_STRING info = pFormat;
798 unsigned char *membase = pMemory + xofs;
800 for (u=0; u<count; u++,info+=8) {
801 unsigned char *memptr = membase + *(SHORT*)&info[0];
802 unsigned char *bufptr = Mark + *(SHORT*)&info[2];
803 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
807 pFormat += 8 * count;
810 STD_OVERFLOW_CHECK(pStubMsg);
815 /***********************************************************************
816 * EmbeddedPointerUnmarshall
818 unsigned char * WINAPI EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
819 unsigned char **ppMemory,
820 PFORMAT_STRING pFormat,
821 unsigned char fMustAlloc)
823 unsigned char *Mark = pStubMsg->BufferMark;
824 unsigned long Offset = pStubMsg->Offset;
825 unsigned ofs, rep, count, stride, xofs;
827 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
829 if (*pFormat != RPC_FC_PP) return NULL;
832 while (pFormat[0] != RPC_FC_END) {
833 switch (pFormat[0]) {
835 FIXME("unknown repeat type %d\n", pFormat[0]);
836 case RPC_FC_NO_REPEAT:
844 case RPC_FC_FIXED_REPEAT:
845 rep = *(WORD*)&pFormat[2];
846 stride = *(WORD*)&pFormat[4];
847 ofs = *(WORD*)&pFormat[6];
848 count = *(WORD*)&pFormat[8];
852 case RPC_FC_VARIABLE_REPEAT:
853 rep = pStubMsg->MaxCount;
854 stride = *(WORD*)&pFormat[2];
855 ofs = *(WORD*)&pFormat[4];
856 count = *(WORD*)&pFormat[6];
857 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
861 /* ofs doesn't seem to matter in this context */
863 PFORMAT_STRING info = pFormat;
864 unsigned char *membase = *ppMemory + xofs;
866 for (u=0; u<count; u++,info+=8) {
867 unsigned char *memptr = membase + *(SHORT*)&info[0];
868 unsigned char *bufptr = Mark + *(SHORT*)&info[2];
869 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, fMustAlloc);
873 pFormat += 8 * count;
879 /***********************************************************************
880 * EmbeddedPointerBufferSize
882 void WINAPI EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
883 unsigned char *pMemory,
884 PFORMAT_STRING pFormat)
886 unsigned long Offset = pStubMsg->Offset;
887 unsigned ofs, rep, count, stride, xofs;
889 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
890 if (*pFormat != RPC_FC_PP) return;
893 while (pFormat[0] != RPC_FC_END) {
894 switch (pFormat[0]) {
896 FIXME("unknown repeat type %d\n", pFormat[0]);
897 case RPC_FC_NO_REPEAT:
905 case RPC_FC_FIXED_REPEAT:
906 rep = *(WORD*)&pFormat[2];
907 stride = *(WORD*)&pFormat[4];
908 ofs = *(WORD*)&pFormat[6];
909 count = *(WORD*)&pFormat[8];
913 case RPC_FC_VARIABLE_REPEAT:
914 rep = pStubMsg->MaxCount;
915 stride = *(WORD*)&pFormat[2];
916 ofs = *(WORD*)&pFormat[4];
917 count = *(WORD*)&pFormat[6];
918 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
922 /* ofs doesn't seem to matter in this context */
924 PFORMAT_STRING info = pFormat;
925 unsigned char *membase = pMemory + xofs;
927 for (u=0; u<count; u++,info+=8) {
928 unsigned char *memptr = membase + *(SHORT*)&info[0];
929 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
933 pFormat += 8 * count;
937 /***********************************************************************
938 * EmbeddedPointerMemorySize
940 unsigned long WINAPI EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
941 PFORMAT_STRING pFormat)
943 unsigned long Offset = pStubMsg->Offset;
944 unsigned char *Mark = pStubMsg->BufferMark;
945 unsigned ofs, rep, count, stride, xofs;
947 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
948 if (*pFormat != RPC_FC_PP) return 0;
951 while (pFormat[0] != RPC_FC_END) {
952 switch (pFormat[0]) {
954 FIXME("unknown repeat type %d\n", pFormat[0]);
955 case RPC_FC_NO_REPEAT:
963 case RPC_FC_FIXED_REPEAT:
964 rep = *(WORD*)&pFormat[2];
965 stride = *(WORD*)&pFormat[4];
966 ofs = *(WORD*)&pFormat[6];
967 count = *(WORD*)&pFormat[8];
971 case RPC_FC_VARIABLE_REPEAT:
972 rep = pStubMsg->MaxCount;
973 stride = *(WORD*)&pFormat[2];
974 ofs = *(WORD*)&pFormat[4];
975 count = *(WORD*)&pFormat[6];
976 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
980 /* ofs doesn't seem to matter in this context */
982 PFORMAT_STRING info = pFormat;
984 for (u=0; u<count; u++,info+=8) {
985 unsigned char *bufptr = Mark + *(SHORT*)&info[2];
986 PointerMemorySize(pStubMsg, bufptr, info+4);
990 pFormat += 8 * count;
996 /***********************************************************************
997 * EmbeddedPointerFree
999 void WINAPI EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1000 unsigned char *pMemory,
1001 PFORMAT_STRING pFormat)
1003 unsigned long Offset = pStubMsg->Offset;
1004 unsigned ofs, rep, count, stride, xofs;
1006 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1007 if (*pFormat != RPC_FC_PP) return;
1010 while (pFormat[0] != RPC_FC_END) {
1011 switch (pFormat[0]) {
1013 FIXME("unknown repeat type %d\n", pFormat[0]);
1014 case RPC_FC_NO_REPEAT:
1022 case RPC_FC_FIXED_REPEAT:
1023 rep = *(WORD*)&pFormat[2];
1024 stride = *(WORD*)&pFormat[4];
1025 ofs = *(WORD*)&pFormat[6];
1026 count = *(WORD*)&pFormat[8];
1030 case RPC_FC_VARIABLE_REPEAT:
1031 rep = pStubMsg->MaxCount;
1032 stride = *(WORD*)&pFormat[2];
1033 ofs = *(WORD*)&pFormat[4];
1034 count = *(WORD*)&pFormat[6];
1035 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1039 /* ofs doesn't seem to matter in this context */
1041 PFORMAT_STRING info = pFormat;
1042 unsigned char *membase = pMemory + xofs;
1044 for (u=0; u<count; u++,info+=8) {
1045 unsigned char *memptr = membase + *(SHORT*)&info[0];
1046 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1050 pFormat += 8 * count;
1054 /***********************************************************************
1055 * NdrPointerMarshall [RPCRT4.@]
1057 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1058 unsigned char *pMemory,
1059 PFORMAT_STRING pFormat)
1061 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1063 pStubMsg->BufferMark = pStubMsg->Buffer;
1064 PointerMarshall(pStubMsg, pStubMsg->Buffer, pMemory, pFormat);
1065 pStubMsg->Buffer += 4;
1067 STD_OVERFLOW_CHECK(pStubMsg);
1072 /***********************************************************************
1073 * NdrPointerUnmarshall [RPCRT4.@]
1075 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1076 unsigned char **ppMemory,
1077 PFORMAT_STRING pFormat,
1078 unsigned char fMustAlloc)
1080 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1082 pStubMsg->BufferMark = pStubMsg->Buffer;
1083 PointerUnmarshall(pStubMsg, pStubMsg->Buffer, ppMemory, pFormat, fMustAlloc);
1084 pStubMsg->Buffer += 4;
1089 /***********************************************************************
1090 * NdrPointerBufferSize [RPCRT4.@]
1092 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1093 unsigned char *pMemory,
1094 PFORMAT_STRING pFormat)
1096 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1097 pStubMsg->BufferLength += 4;
1098 PointerBufferSize(pStubMsg, pMemory, pFormat);
1101 /***********************************************************************
1102 * NdrPointerMemorySize [RPCRT4.@]
1104 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1105 PFORMAT_STRING pFormat)
1107 /* unsigned size = *(LPWORD)(pFormat+2); */
1108 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1109 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1113 /***********************************************************************
1114 * NdrPointerFree [RPCRT4.@]
1116 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1117 unsigned char *pMemory,
1118 PFORMAT_STRING pFormat)
1120 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1121 PointerFree(pStubMsg, pMemory, pFormat);
1124 /***********************************************************************
1125 * NdrSimpleStructMarshall [RPCRT4.@]
1127 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1128 unsigned char *pMemory,
1129 PFORMAT_STRING pFormat)
1131 unsigned size = *(LPWORD)(pFormat+2);
1132 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1134 memcpy(pStubMsg->Buffer, pMemory, size);
1135 pStubMsg->BufferMark = pStubMsg->Buffer;
1136 pStubMsg->Buffer += size;
1138 if (pFormat[0] != RPC_FC_STRUCT)
1139 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1141 STD_OVERFLOW_CHECK(pStubMsg);
1146 /***********************************************************************
1147 * NdrSimpleStructUnmarshall [RPCRT4.@]
1149 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1150 unsigned char **ppMemory,
1151 PFORMAT_STRING pFormat,
1152 unsigned char fMustAlloc)
1154 unsigned size = *(LPWORD)(pFormat+2);
1155 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1158 *ppMemory = NdrAllocate(pStubMsg, size);
1159 memcpy(*ppMemory, pStubMsg->Buffer, size);
1161 if (pStubMsg->ReuseBuffer && !*ppMemory)
1162 /* for servers, we may just point straight into the RPC buffer, I think
1163 * (I guess that's what MS does since MIDL code doesn't try to free) */
1164 *ppMemory = pStubMsg->Buffer;
1166 /* for clients, memory should be provided by caller */
1167 memcpy(*ppMemory, pStubMsg->Buffer, size);
1170 pStubMsg->BufferMark = pStubMsg->Buffer;
1171 pStubMsg->Buffer += size;
1173 if (pFormat[0] != RPC_FC_STRUCT)
1174 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1180 /***********************************************************************
1181 * NdrSimpleStructUnmarshall [RPCRT4.@]
1183 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1184 unsigned char FormatChar )
1190 /***********************************************************************
1191 * NdrSimpleStructUnmarshall [RPCRT4.@]
1193 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1194 unsigned char FormatChar )
1200 /***********************************************************************
1201 * NdrSimpleStructBufferSize [RPCRT4.@]
1203 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1204 unsigned char *pMemory,
1205 PFORMAT_STRING pFormat)
1207 unsigned size = *(LPWORD)(pFormat+2);
1208 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1209 pStubMsg->BufferLength += size;
1210 if (pFormat[0] != RPC_FC_STRUCT)
1211 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1214 /***********************************************************************
1215 * NdrSimpleStructMemorySize [RPCRT4.@]
1217 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1218 PFORMAT_STRING pFormat)
1220 /* unsigned size = *(LPWORD)(pFormat+2); */
1221 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1222 if (pFormat[0] != RPC_FC_STRUCT)
1223 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1227 /***********************************************************************
1228 * NdrSimpleStructFree [RPCRT4.@]
1230 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1231 unsigned char *pMemory,
1232 PFORMAT_STRING pFormat)
1234 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1235 if (pFormat[0] != RPC_FC_STRUCT)
1236 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1240 unsigned long WINAPI EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1241 PFORMAT_STRING pFormat)
1245 case RPC_FC_PSTRUCT:
1246 case RPC_FC_CSTRUCT:
1247 case RPC_FC_BOGUS_STRUCT:
1248 return *(WORD*)&pFormat[2];
1249 case RPC_FC_USER_MARSHAL:
1250 return *(WORD*)&pFormat[4];
1252 FIXME("unhandled embedded type %02x\n", *pFormat);
1258 unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1259 unsigned char *pMemory,
1260 PFORMAT_STRING pFormat,
1261 PFORMAT_STRING pPointer)
1263 PFORMAT_STRING desc;
1267 while (*pFormat != RPC_FC_END) {
1271 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1272 memcpy(pStubMsg->Buffer, pMemory, 2);
1273 pStubMsg->Buffer += 2;
1278 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1279 memcpy(pStubMsg->Buffer, pMemory, 4);
1280 pStubMsg->Buffer += 4;
1283 case RPC_FC_POINTER:
1284 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1285 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1289 case RPC_FC_ALIGNM4:
1290 ALIGN_POINTER(pMemory, 3);
1292 case RPC_FC_ALIGNM8:
1293 ALIGN_POINTER(pMemory, 7);
1295 case RPC_FC_EMBEDDED_COMPLEX:
1296 pMemory += pFormat[1];
1298 desc = pFormat + *(SHORT*)pFormat;
1299 size = EmbeddedComplexSize(pStubMsg, desc);
1300 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1301 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1302 if (m) m(pStubMsg, pMemory, desc);
1303 else FIXME("no marshaller for embedded type %02x\n", *desc);
1310 FIXME("unhandled format %02x\n", *pFormat);
1318 unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1319 unsigned char *pMemory,
1320 PFORMAT_STRING pFormat,
1321 PFORMAT_STRING pPointer,
1322 unsigned char fMustAlloc)
1324 PFORMAT_STRING desc;
1328 while (*pFormat != RPC_FC_END) {
1332 memcpy(pMemory, pStubMsg->Buffer, 2);
1333 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1334 pStubMsg->Buffer += 2;
1339 memcpy(pMemory, pStubMsg->Buffer, 4);
1340 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1341 pStubMsg->Buffer += 4;
1344 case RPC_FC_POINTER:
1345 *(unsigned char**)pMemory = NULL;
1346 TRACE("pointer => %p\n", pMemory);
1347 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, fMustAlloc);
1351 case RPC_FC_ALIGNM4:
1352 ALIGN_POINTER(pMemory, 3);
1354 case RPC_FC_ALIGNM8:
1355 ALIGN_POINTER(pMemory, 7);
1357 case RPC_FC_EMBEDDED_COMPLEX:
1358 pMemory += pFormat[1];
1360 desc = pFormat + *(SHORT*)pFormat;
1361 size = EmbeddedComplexSize(pStubMsg, desc);
1362 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1363 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1364 memset(pMemory, 0, size); /* just in case */
1365 if (m) m(pStubMsg, &pMemory, desc, fMustAlloc);
1366 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1373 FIXME("unhandled format %d\n", *pFormat);
1381 unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1382 unsigned char *pMemory,
1383 PFORMAT_STRING pFormat,
1384 PFORMAT_STRING pPointer)
1386 PFORMAT_STRING desc;
1390 while (*pFormat != RPC_FC_END) {
1394 pStubMsg->BufferLength += 2;
1399 pStubMsg->BufferLength += 4;
1402 case RPC_FC_POINTER:
1403 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1407 case RPC_FC_ALIGNM4:
1408 ALIGN_POINTER(pMemory, 3);
1410 case RPC_FC_ALIGNM8:
1411 ALIGN_POINTER(pMemory, 7);
1413 case RPC_FC_EMBEDDED_COMPLEX:
1414 pMemory += pFormat[1];
1416 desc = pFormat + *(SHORT*)pFormat;
1417 size = EmbeddedComplexSize(pStubMsg, desc);
1418 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1419 if (m) m(pStubMsg, pMemory, desc);
1420 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1427 FIXME("unhandled format %d\n", *pFormat);
1435 unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1436 unsigned char *pMemory,
1437 PFORMAT_STRING pFormat,
1438 PFORMAT_STRING pPointer)
1440 PFORMAT_STRING desc;
1444 while (*pFormat != RPC_FC_END) {
1454 case RPC_FC_POINTER:
1455 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
1459 case RPC_FC_ALIGNM4:
1460 ALIGN_POINTER(pMemory, 3);
1462 case RPC_FC_ALIGNM8:
1463 ALIGN_POINTER(pMemory, 7);
1465 case RPC_FC_EMBEDDED_COMPLEX:
1466 pMemory += pFormat[1];
1468 desc = pFormat + *(SHORT*)pFormat;
1469 size = EmbeddedComplexSize(pStubMsg, desc);
1470 m = NdrFreer[*desc & NDR_TABLE_MASK];
1471 if (m) m(pStubMsg, pMemory, desc);
1472 else FIXME("no freer for embedded type %02x\n", *desc);
1479 FIXME("unhandled format %d\n", *pFormat);
1487 unsigned long WINAPI ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
1488 PFORMAT_STRING pFormat)
1490 PFORMAT_STRING desc;
1491 unsigned long size = 0;
1493 while (*pFormat != RPC_FC_END) {
1503 case RPC_FC_POINTER:
1506 case RPC_FC_ALIGNM4:
1507 ALIGN_LENGTH(size, 3);
1509 case RPC_FC_ALIGNM8:
1510 ALIGN_LENGTH(size, 7);
1512 case RPC_FC_EMBEDDED_COMPLEX:
1515 desc = pFormat + *(SHORT*)pFormat;
1516 size += EmbeddedComplexSize(pStubMsg, desc);
1522 FIXME("unhandled format %d\n", *pFormat);
1530 /***********************************************************************
1531 * NdrComplexStructMarshall [RPCRT4.@]
1533 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1534 unsigned char *pMemory,
1535 PFORMAT_STRING pFormat)
1537 PFORMAT_STRING conf_array = NULL;
1538 PFORMAT_STRING pointer_desc = NULL;
1539 unsigned char *OldMemory = pStubMsg->Memory;
1541 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1544 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1546 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1549 pStubMsg->Memory = pMemory;
1551 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
1554 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
1556 pStubMsg->Memory = OldMemory;
1558 STD_OVERFLOW_CHECK(pStubMsg);
1563 /***********************************************************************
1564 * NdrComplexStructUnmarshall [RPCRT4.@]
1566 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1567 unsigned char **ppMemory,
1568 PFORMAT_STRING pFormat,
1569 unsigned char fMustAlloc)
1571 unsigned size = *(LPWORD)(pFormat+2);
1572 PFORMAT_STRING conf_array = NULL;
1573 PFORMAT_STRING pointer_desc = NULL;
1574 unsigned char *pMemory;
1576 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1578 if (fMustAlloc || !*ppMemory)
1579 *ppMemory = NdrAllocate(pStubMsg, size);
1582 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1584 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1587 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
1590 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
1595 /***********************************************************************
1596 * NdrComplexStructBufferSize [RPCRT4.@]
1598 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1599 unsigned char *pMemory,
1600 PFORMAT_STRING pFormat)
1602 PFORMAT_STRING conf_array = NULL;
1603 PFORMAT_STRING pointer_desc = NULL;
1604 unsigned char *OldMemory = pStubMsg->Memory;
1606 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1609 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1611 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1614 pStubMsg->Memory = pMemory;
1616 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
1619 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
1621 pStubMsg->Memory = OldMemory;
1624 /***********************************************************************
1625 * NdrComplexStructMemorySize [RPCRT4.@]
1627 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1628 PFORMAT_STRING pFormat)
1630 /* unsigned size = *(LPWORD)(pFormat+2); */
1631 PFORMAT_STRING conf_array = NULL;
1632 PFORMAT_STRING pointer_desc = NULL;
1634 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1637 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1639 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1645 /***********************************************************************
1646 * NdrComplexStructFree [RPCRT4.@]
1648 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1649 unsigned char *pMemory,
1650 PFORMAT_STRING pFormat)
1652 PFORMAT_STRING conf_array = NULL;
1653 PFORMAT_STRING pointer_desc = NULL;
1654 unsigned char *OldMemory = pStubMsg->Memory;
1656 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1659 if (*(WORD*)pFormat) conf_array = pFormat + *(WORD*)pFormat;
1661 if (*(WORD*)pFormat) pointer_desc = pFormat + *(WORD*)pFormat;
1664 pStubMsg->Memory = pMemory;
1666 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
1669 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
1671 pStubMsg->Memory = OldMemory;
1674 /***********************************************************************
1675 * NdrConformantArrayMarshall [RPCRT4.@]
1677 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1678 unsigned char *pMemory,
1679 PFORMAT_STRING pFormat)
1681 DWORD size = 0, esize = *(LPWORD)(pFormat+2);
1682 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1683 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1685 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1686 size = pStubMsg->MaxCount;
1688 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
1689 pStubMsg->Buffer += 4;
1691 memcpy(pStubMsg->Buffer, pMemory, size*esize);
1692 pStubMsg->BufferMark = pStubMsg->Buffer;
1693 pStubMsg->Buffer += size*esize;
1695 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1697 STD_OVERFLOW_CHECK(pStubMsg);
1702 /***********************************************************************
1703 * NdrConformantArrayUnmarshall [RPCRT4.@]
1705 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1706 unsigned char **ppMemory,
1707 PFORMAT_STRING pFormat,
1708 unsigned char fMustAlloc)
1710 DWORD size = 0, esize = *(LPWORD)(pFormat+2);
1711 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1712 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1714 pFormat = ReadConformance(pStubMsg, pFormat+4);
1715 size = pStubMsg->MaxCount;
1718 *ppMemory = NdrAllocate(pStubMsg, size*esize);
1719 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
1721 if (pStubMsg->ReuseBuffer && !*ppMemory)
1722 /* for servers, we may just point straight into the RPC buffer, I think
1723 * (I guess that's what MS does since MIDL code doesn't try to free) */
1724 *ppMemory = pStubMsg->Buffer;
1726 /* for clients, memory should be provided by caller */
1727 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
1730 pStubMsg->BufferMark = pStubMsg->Buffer;
1731 pStubMsg->Buffer += size*esize;
1733 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
1738 /***********************************************************************
1739 * NdrConformantArrayBufferSize [RPCRT4.@]
1741 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1742 unsigned char *pMemory,
1743 PFORMAT_STRING pFormat)
1745 DWORD size = 0, esize = *(LPWORD)(pFormat+2);
1746 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1747 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1749 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1750 size = pStubMsg->MaxCount;
1752 pStubMsg->BufferLength += size*esize;
1754 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1757 /***********************************************************************
1758 * NdrConformantArrayMemorySize [RPCRT4.@]
1760 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1761 PFORMAT_STRING pFormat)
1764 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1765 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1767 pFormat = ReadConformance(pStubMsg, pFormat+4);
1768 size = pStubMsg->MaxCount;
1770 EmbeddedPointerMemorySize(pStubMsg, pFormat);
1775 /***********************************************************************
1776 * NdrConformantArrayFree [RPCRT4.@]
1778 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
1779 unsigned char *pMemory,
1780 PFORMAT_STRING pFormat)
1782 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1783 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
1785 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
1789 /***********************************************************************
1790 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
1792 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
1793 unsigned char* pMemory,
1794 PFORMAT_STRING pFormat )
1801 /***********************************************************************
1802 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
1804 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
1805 unsigned char** ppMemory,
1806 PFORMAT_STRING pFormat,
1807 unsigned char fMustAlloc )
1814 /***********************************************************************
1815 * NdrConformantVaryingArrayFree [RPCRT4.@]
1817 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
1818 unsigned char* pMemory,
1819 PFORMAT_STRING pFormat )
1825 /***********************************************************************
1826 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
1828 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
1829 unsigned char* pMemory, PFORMAT_STRING pFormat )
1835 /***********************************************************************
1836 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
1838 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
1839 PFORMAT_STRING pFormat )
1846 /***********************************************************************
1847 * NdrComplexArrayMarshall [RPCRT4.@]
1849 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1850 unsigned char *pMemory,
1851 PFORMAT_STRING pFormat)
1853 DWORD size = 0, count, def;
1854 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1856 def = *(WORD*)&pFormat[2];
1859 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1860 size = pStubMsg->MaxCount;
1861 TRACE("conformance=%ld\n", size);
1863 if (*(DWORD*)pFormat != 0xffffffff)
1864 FIXME("compute variance\n");
1867 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size);
1868 pStubMsg->Buffer += 4;
1870 for (count=0; count<size; count++)
1871 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
1873 STD_OVERFLOW_CHECK(pStubMsg);
1878 /***********************************************************************
1879 * NdrComplexArrayUnmarshall [RPCRT4.@]
1881 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1882 unsigned char **ppMemory,
1883 PFORMAT_STRING pFormat,
1884 unsigned char fMustAlloc)
1886 DWORD size = 0, count, esize;
1887 unsigned char *pMemory;
1888 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1892 pFormat = ReadConformance(pStubMsg, pFormat);
1893 size = pStubMsg->MaxCount;
1894 TRACE("conformance=%ld\n", size);
1898 esize = ComplexStructSize(pStubMsg, pFormat);
1900 if (fMustAlloc || !*ppMemory)
1901 *ppMemory = NdrAllocate(pStubMsg, size*esize);
1903 pMemory = *ppMemory;
1904 for (count=0; count<size; count++)
1905 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
1910 /***********************************************************************
1911 * NdrComplexArrayBufferSize [RPCRT4.@]
1913 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1914 unsigned char *pMemory,
1915 PFORMAT_STRING pFormat)
1917 DWORD size = 0, count, def;
1918 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1920 def = *(WORD*)&pFormat[2];
1923 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1924 size = pStubMsg->MaxCount;
1925 TRACE("conformance=%ld\n", size);
1927 if (*(DWORD*)pFormat != 0xffffffff)
1928 FIXME("compute variance\n");
1931 for (count=0; count<size; count++)
1932 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
1935 /***********************************************************************
1936 * NdrComplexArrayMemorySize [RPCRT4.@]
1938 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1939 PFORMAT_STRING pFormat)
1942 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1946 pFormat = ReadConformance(pStubMsg, pFormat);
1947 size = pStubMsg->MaxCount;
1948 TRACE("conformance=%ld\n", size);
1955 /***********************************************************************
1956 * NdrComplexArrayFree [RPCRT4.@]
1958 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
1959 unsigned char *pMemory,
1960 PFORMAT_STRING pFormat)
1962 DWORD size = 0, count, def;
1963 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1965 def = *(WORD*)&pFormat[2];
1968 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
1969 size = pStubMsg->MaxCount;
1970 TRACE("conformance=%ld\n", size);
1972 if (*(DWORD*)pFormat != 0xffffffff)
1973 FIXME("compute variance\n");
1976 for (count=0; count<size; count++)
1977 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
1980 unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
1982 return MAKELONG(pStubMsg->dwDestContext,
1983 pStubMsg->RpcMsg->DataRepresentation);
1986 /***********************************************************************
1987 * NdrUserMarshalMarshall [RPCRT4.@]
1989 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1990 unsigned char *pMemory,
1991 PFORMAT_STRING pFormat)
1993 /* unsigned flags = pFormat[1]; */
1994 unsigned index = *(WORD*)&pFormat[2];
1995 unsigned long uflag = UserMarshalFlags(pStubMsg);
1996 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1997 TRACE("index=%d\n", index);
2000 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2001 &uflag, pStubMsg->Buffer, pMemory);
2003 STD_OVERFLOW_CHECK(pStubMsg);
2008 /***********************************************************************
2009 * NdrUserMarshalUnmarshall [RPCRT4.@]
2011 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2012 unsigned char **ppMemory,
2013 PFORMAT_STRING pFormat,
2014 unsigned char fMustAlloc)
2016 /* unsigned flags = pFormat[1];*/
2017 unsigned index = *(WORD*)&pFormat[2];
2018 DWORD memsize = *(WORD*)&pFormat[4];
2019 unsigned long uflag = UserMarshalFlags(pStubMsg);
2020 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2021 TRACE("index=%d\n", index);
2023 if (fMustAlloc || !*ppMemory)
2024 *ppMemory = NdrAllocate(pStubMsg, memsize);
2027 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2028 &uflag, pStubMsg->Buffer, *ppMemory);
2033 /***********************************************************************
2034 * NdrUserMarshalBufferSize [RPCRT4.@]
2036 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2037 unsigned char *pMemory,
2038 PFORMAT_STRING pFormat)
2040 /* unsigned flags = pFormat[1];*/
2041 unsigned index = *(WORD*)&pFormat[2];
2042 DWORD bufsize = *(WORD*)&pFormat[6];
2043 unsigned long uflag = UserMarshalFlags(pStubMsg);
2044 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2045 TRACE("index=%d\n", index);
2048 TRACE("size=%ld\n", bufsize);
2049 pStubMsg->BufferLength += bufsize;
2053 pStubMsg->BufferLength =
2054 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2055 &uflag, pStubMsg->BufferLength, pMemory);
2058 /***********************************************************************
2059 * NdrUserMarshalMemorySize [RPCRT4.@]
2061 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2062 PFORMAT_STRING pFormat)
2064 unsigned index = *(WORD*)&pFormat[2];
2065 /* DWORD memsize = *(WORD*)&pFormat[4]; */
2066 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
2067 TRACE("index=%d\n", index);
2072 /***********************************************************************
2073 * NdrUserMarshalFree [RPCRT4.@]
2075 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2076 unsigned char *pMemory,
2077 PFORMAT_STRING pFormat)
2079 /* unsigned flags = pFormat[1]; */
2080 unsigned index = *(WORD*)&pFormat[2];
2081 unsigned long uflag = UserMarshalFlags(pStubMsg);
2082 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2083 TRACE("index=%d\n", index);
2085 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2089 /***********************************************************************
2090 * NdrClearOutParameters [RPCRT4.@]
2092 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2093 PFORMAT_STRING pFormat,
2096 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2099 /***********************************************************************
2100 * NdrConvert [RPCRT4.@]
2102 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2104 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2105 /* FIXME: since this stub doesn't do any converting, the proper behavior
2106 is to raise an exception */
2109 /***********************************************************************
2110 * NdrConvert2 [RPCRT4.@]
2112 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2114 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2115 pStubMsg, pFormat, NumberParams);
2116 /* FIXME: since this stub doesn't do any converting, the proper behavior
2117 is to raise an exception */