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 */