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
37 #include "wine/unicode.h"
38 #include "wine/rpcfc.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
44 #define BUFFER_PARANOIA 20
47 #define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
48 (*((UINT32 *)(pchar)) = (uint32))
50 #define LITTLE_ENDIAN_UINT32_READ(pchar) \
51 (*((UINT32 *)(pchar)))
53 /* these would work for i386 too, but less efficient */
54 #define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
55 (*(pchar) = LOBYTE(LOWORD(uint32)), \
56 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
57 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
58 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
59 (uint32)) /* allow as r-value */
61 #define LITTLE_ENDIAN_UINT32_READ(pchar) \
63 MAKEWORD(*(pchar), *((pchar)+1)), \
64 MAKEWORD(*((pchar)+2), *((pchar)+3))))
67 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
68 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
69 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
70 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
71 *(pchar) = HIBYTE(HIWORD(uint32)), \
72 (uint32)) /* allow as r-value */
74 #define BIG_ENDIAN_UINT32_READ(pchar) \
76 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
77 MAKEWORD(*((pchar)+1), *(pchar))))
79 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
80 #define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
81 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
82 #define NDR_LOCAL_UINT32_READ(pchar) \
83 BIG_ENDIAN_UINT32_READ(pchar)
85 #define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
86 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
87 #define NDR_LOCAL_UINT32_READ(pchar) \
88 LITTLE_ENDIAN_UINT32_READ(pchar)
91 /* _Align must be the desired alignment minus 1,
92 * e.g. ALIGN_LENGTH(len, 3) to align on a dword boundary. */
93 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
94 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
95 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
96 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
98 #define STD_OVERFLOW_CHECK(_Msg) do { \
99 TRACE("buffer=%d/%ld\n", _Msg->Buffer - _Msg->BufferStart, _Msg->BufferLength); \
100 if (_Msg->Buffer > _Msg->BufferEnd) ERR("buffer overflow %d bytes\n", _Msg->Buffer - _Msg->BufferEnd); \
103 #define NDR_TABLE_SIZE 128
104 #define NDR_TABLE_MASK 127
106 NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
107 0, 0, 0, 0, 0, 0, 0, 0,
108 0, 0, 0, 0, 0, 0, 0, 0,
112 NdrPointerMarshall
, NdrPointerMarshall
,
113 NdrPointerMarshall
, NdrPointerMarshall
,
115 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
117 NdrComplexStructMarshall
,
119 NdrConformantArrayMarshall
, 0, 0, 0, 0, 0,
120 NdrComplexArrayMarshall
,
122 NdrConformantStringMarshall
, 0, 0,
123 NdrConformantStringMarshall
, 0, 0, 0, 0,
127 NdrInterfacePointerMarshall
,
130 NdrUserMarshalMarshall
132 NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
133 0, 0, 0, 0, 0, 0, 0, 0,
134 0, 0, 0, 0, 0, 0, 0, 0,
138 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
139 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
141 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
143 NdrComplexStructUnmarshall
,
145 NdrConformantArrayUnmarshall
, 0, 0, 0, 0, 0,
146 NdrComplexArrayUnmarshall
,
148 NdrConformantStringUnmarshall
, 0, 0,
149 NdrConformantStringUnmarshall
, 0, 0, 0, 0,
153 NdrInterfacePointerUnmarshall
,
156 NdrUserMarshalUnmarshall
158 NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
159 0, 0, 0, 0, 0, 0, 0, 0,
160 0, 0, 0, 0, 0, 0, 0, 0,
164 NdrPointerBufferSize
, NdrPointerBufferSize
,
165 NdrPointerBufferSize
, NdrPointerBufferSize
,
167 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
169 NdrComplexStructBufferSize
,
171 NdrConformantArrayBufferSize
, 0, 0, 0, 0, 0,
172 NdrComplexArrayBufferSize
,
174 NdrConformantStringBufferSize
, 0, 0,
175 NdrConformantStringBufferSize
, 0, 0, 0, 0,
179 NdrInterfacePointerBufferSize
,
182 NdrUserMarshalBufferSize
184 NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
185 0, 0, 0, 0, 0, 0, 0, 0,
186 0, 0, 0, 0, 0, 0, 0, 0,
190 NdrPointerMemorySize
, NdrPointerMemorySize
,
191 NdrPointerMemorySize
, NdrPointerMemorySize
,
193 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
195 NdrComplexStructMemorySize
,
197 NdrConformantArrayMemorySize
, 0, 0, 0, 0, 0,
198 NdrComplexArrayMemorySize
,
200 NdrConformantStringMemorySize
, 0, 0,
201 NdrConformantStringMemorySize
, 0, 0, 0, 0,
205 NdrInterfacePointerMemorySize
,
208 NdrUserMarshalMemorySize
210 NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
211 0, 0, 0, 0, 0, 0, 0, 0,
212 0, 0, 0, 0, 0, 0, 0, 0,
216 NdrPointerFree
, NdrPointerFree
,
217 NdrPointerFree
, NdrPointerFree
,
219 NdrSimpleStructFree
, NdrSimpleStructFree
,
221 NdrComplexStructFree
,
223 NdrConformantArrayFree
, 0, 0, 0, 0, 0,
226 0, 0, 0, 0, 0, 0, 0, 0,
230 NdrInterfacePointerFree
,
236 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
238 /* hmm, this is probably supposed to do more? */
239 return pStubMsg
->pfnAllocate(len
);
242 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
244 pStubMsg
->pfnFree(Pointer
);
247 PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
249 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
250 pStubMsg
->Buffer
+= 4;
251 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
255 PFORMAT_STRING
ComputeConformance(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
256 PFORMAT_STRING pFormat
, ULONG_PTR def
)
258 BYTE dtype
= pFormat
[0] & 0xf;
259 DWORD ofs
= (DWORD
)pFormat
[2] | ((DWORD
)pFormat
[3] << 8);
263 if (pFormat
[0] == 0xff) {
264 /* null descriptor */
265 pStubMsg
->MaxCount
= def
;
269 switch (pFormat
[0] & 0xf0) {
270 case RPC_FC_NORMAL_CONFORMANCE
:
271 TRACE("normal conformance, ofs=%ld\n", ofs
);
274 case RPC_FC_POINTER_CONFORMANCE
:
275 TRACE("pointer conformance, ofs=%ld\n", ofs
);
276 ptr
= pStubMsg
->Memory
+ ofs
;
278 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
279 TRACE("toplevel conformance, ofs=%ld\n", ofs
);
280 if (pStubMsg
->StackTop
) {
281 ptr
= pStubMsg
->StackTop
+ ofs
;
284 /* -Os mode, MaxCount is already set */
288 case RPC_FC_CONSTANT_CONFORMANCE
:
289 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
290 TRACE("constant conformance, val=%ld\n", data
);
291 pStubMsg
->MaxCount
= data
;
293 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
294 FIXME("toplevel multidimensional conformance, ofs=%ld\n", ofs
);
295 if (pStubMsg
->StackTop
) {
296 ptr
= pStubMsg
->StackTop
+ ofs
;
304 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
307 switch (pFormat
[1]) {
308 case RPC_FC_DEREFERENCE
:
311 case RPC_FC_CALLBACK
:
312 /* ofs is index into StubDesc->apfnExprEval */
313 FIXME("handle callback\n");
328 data
= *(USHORT
*)ptr
;
337 FIXME("unknown conformance data type %x\n", dtype
);
340 TRACE("dereferenced data type %x at %p, got %ld\n", dtype
, ptr
, data
);
343 switch (pFormat
[1]) {
345 pStubMsg
->MaxCount
= data
;
347 case RPC_FC_DEREFERENCE
:
348 /* already handled */
351 FIXME("unknown conformance op %d\n", pFormat
[1]);
356 TRACE("resulting conformance is %ld\n", pStubMsg
->MaxCount
);
362 * NdrConformantString:
364 * What MS calls a ConformantString is, in DCE terminology,
365 * a Varying-Conformant String.
367 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
368 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
369 * into unmarshalled string)
370 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
372 * data: CHARTYPE[maxlen]
374 * ], where CHARTYPE is the appropriate character type (specified externally)
378 /***********************************************************************
379 * NdrConformantStringMarshall [RPCRT4.@]
381 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
382 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
384 unsigned long len
, esize
;
387 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
390 if (*pFormat
== RPC_FC_C_CSTRING
) {
391 TRACE("string=%s\n", debugstr_a(pszMessage
));
392 len
= strlen(pszMessage
)+1;
395 else if (*pFormat
== RPC_FC_C_WSTRING
) {
396 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
397 len
= strlenW((LPWSTR
)pszMessage
)+1;
401 ERR("Unhandled string type: %#x\n", *pFormat
);
402 /* FIXME: raise an exception. */
406 if (pFormat
[1] != RPC_FC_PAD
) {
407 FIXME("sized string format=%d\n", pFormat
[1]);
410 assert( (pStubMsg
->BufferLength
>= (len
*esize
+ 13)) && (pStubMsg
->Buffer
!= NULL
) );
412 c
= pStubMsg
->Buffer
;
414 NDR_LOCAL_UINT32_WRITE(c
, len
); /* max length: strlen + 1 (for '\0') */
415 c
+= 8; /* offset: 0 */
416 NDR_LOCAL_UINT32_WRITE(c
, len
); /* actual length: (same) */
418 memcpy(c
, pszMessage
, len
*esize
); /* the string itself */
420 pStubMsg
->Buffer
= c
;
422 STD_OVERFLOW_CHECK(pStubMsg
);
425 return NULL
; /* is this always right? */
428 /***********************************************************************
429 * NdrConformantStringBufferSize [RPCRT4.@]
431 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
432 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
434 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
437 if (*pFormat
== RPC_FC_C_CSTRING
) {
438 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 1 octet for '\0' */
439 TRACE("string=%s\n", debugstr_a(pMemory
));
440 pStubMsg
->BufferLength
+= strlen(pMemory
) + 13 + BUFFER_PARANOIA
;
442 else if (*pFormat
== RPC_FC_C_WSTRING
) {
443 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 2 octets for L'\0' */
444 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
445 pStubMsg
->BufferLength
+= strlenW((LPWSTR
)pMemory
)*2 + 14 + BUFFER_PARANOIA
;
448 ERR("Unhandled string type: %#x\n", *pFormat
);
449 /* FIXME: raise an exception */
452 if (pFormat
[1] != RPC_FC_PAD
) {
453 FIXME("sized string format=%d\n", pFormat
[1]);
457 /************************************************************************
458 * NdrConformantStringMemorySize [RPCRT4.@]
460 unsigned long WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
461 PFORMAT_STRING pFormat
)
463 unsigned long rslt
= 0;
465 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
467 assert(pStubMsg
&& pFormat
);
469 if (*pFormat
== RPC_FC_C_CSTRING
) {
470 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
); /* maxlen */
472 else if (*pFormat
== RPC_FC_C_WSTRING
) {
473 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
)*2; /* maxlen */
476 ERR("Unhandled string type: %#x\n", *pFormat
);
477 /* FIXME: raise an exception */
480 if (pFormat
[1] != RPC_FC_PAD
) {
481 FIXME("sized string format=%d\n", pFormat
[1]);
484 TRACE(" --> %lu\n", rslt
);
488 /************************************************************************
489 * NdrConformantStringUnmarshall [RPCRT4.@]
491 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
492 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
494 unsigned long len
, esize
, ofs
;
497 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
498 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
500 assert(pFormat
&& ppMemory
&& pStubMsg
);
502 pStubMsg
->Buffer
+= 4;
503 ofs
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
504 pStubMsg
->Buffer
+= 4;
505 len
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
506 pStubMsg
->Buffer
+= 4;
508 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
509 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
511 ERR("Unhandled string type: %#x\n", *pFormat
);
512 /* FIXME: raise an exception */
516 if (pFormat
[1] != RPC_FC_PAD
) {
517 FIXME("sized string format=%d\n", pFormat
[1]);
521 *ppMemory
= NdrAllocate(pStubMsg
, len
*esize
+ BUFFER_PARANOIA
);
523 if (pStubMsg
->ReuseBuffer
&& !*ppMemory
)
524 /* for servers, we may just point straight into the RPC buffer, I think
525 * (I guess that's what MS does since MIDL code doesn't try to free) */
526 *ppMemory
= pStubMsg
->Buffer
- ofs
*esize
;
527 /* for clients, memory should be provided by caller */
530 pMem
= *ppMemory
+ ofs
*esize
;
532 if (pMem
!= pStubMsg
->Buffer
)
533 memcpy(pMem
, pStubMsg
->Buffer
, len
*esize
);
535 pStubMsg
->Buffer
+= len
*esize
;
537 if (*pFormat
== RPC_FC_C_CSTRING
) {
538 TRACE("string=%s\n", debugstr_a(pMem
));
540 else if (*pFormat
== RPC_FC_C_WSTRING
) {
541 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMem
));
544 return NULL
; /* FIXME: is this always right? */
547 /***********************************************************************
550 void WINAPI
PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
551 unsigned char *Buffer
,
552 unsigned char *Pointer
,
553 PFORMAT_STRING pFormat
)
555 unsigned type
= pFormat
[0], attr
= pFormat
[1];
559 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
560 TRACE("type=%d, attr=%d\n", type
, attr
);
562 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
563 else desc
= pFormat
+ *(SHORT
*)pFormat
;
564 if (attr
& RPC_FC_P_DEREF
) {
565 Pointer
= *(unsigned char**)Pointer
;
566 TRACE("deref => %p\n", Pointer
);
569 *(LPVOID
*)Buffer
= 0;
572 case RPC_FC_RP
: /* ref pointer (always non-null) */
575 FIXME("unhandled ptr type=%02x\n", type
);
578 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
579 if (m
) m(pStubMsg
, Pointer
, desc
);
580 else FIXME("no marshaller for data type=%02x\n", *desc
);
582 STD_OVERFLOW_CHECK(pStubMsg
);
585 /***********************************************************************
588 void WINAPI
PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
589 unsigned char *Buffer
,
590 unsigned char **pPointer
,
591 PFORMAT_STRING pFormat
,
592 unsigned char fMustAlloc
)
594 unsigned type
= pFormat
[0], attr
= pFormat
[1];
598 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pFormat
, fMustAlloc
);
599 TRACE("type=%d, attr=%d\n", type
, attr
);
601 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
602 else desc
= pFormat
+ *(SHORT
*)pFormat
;
603 if (attr
& RPC_FC_P_DEREF
) {
604 pPointer
= *(unsigned char***)pPointer
;
605 TRACE("deref => %p\n", pPointer
);
609 case RPC_FC_RP
: /* ref pointer (always non-null) */
612 FIXME("unhandled ptr type=%02x\n", type
);
617 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
618 if (m
) m(pStubMsg
, pPointer
, desc
, fMustAlloc
);
619 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
620 TRACE("pointer=%p\n", *pPointer
);
623 /***********************************************************************
626 void WINAPI
PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
627 unsigned char *Pointer
,
628 PFORMAT_STRING pFormat
)
630 unsigned type
= pFormat
[0], attr
= pFormat
[1];
634 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
635 TRACE("type=%d, attr=%d\n", type
, attr
);
637 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
638 else desc
= pFormat
+ *(SHORT
*)pFormat
;
639 if (attr
& RPC_FC_P_DEREF
) {
640 Pointer
= *(unsigned char**)Pointer
;
641 TRACE("deref => %p\n", Pointer
);
645 case RPC_FC_RP
: /* ref pointer (always non-null) */
648 FIXME("unhandled ptr type=%02x\n", type
);
651 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
652 if (m
) m(pStubMsg
, Pointer
, desc
);
653 else FIXME("no buffersizer for data type=%02x\n", *desc
);
656 /***********************************************************************
657 * PointerMemorySize [RPCRT4.@]
659 unsigned long WINAPI
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
660 unsigned char *Buffer
,
661 PFORMAT_STRING pFormat
)
663 unsigned type
= pFormat
[0], attr
= pFormat
[1];
667 FIXME("(%p,%p,%p): stub\n", pStubMsg
, Buffer
, pFormat
);
668 TRACE("type=%d, attr=%d\n", type
, attr
);
670 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
671 else desc
= pFormat
+ *(SHORT
*)pFormat
;
672 if (attr
& RPC_FC_P_DEREF
) {
677 case RPC_FC_RP
: /* ref pointer (always non-null) */
680 FIXME("unhandled ptr type=%02x\n", type
);
683 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
684 if (m
) m(pStubMsg
, desc
);
685 else FIXME("no memorysizer for data type=%02x\n", *desc
);
690 /***********************************************************************
691 * PointerFree [RPCRT4.@]
693 void WINAPI
PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
694 unsigned char *Pointer
,
695 PFORMAT_STRING pFormat
)
697 unsigned type
= pFormat
[0], attr
= pFormat
[1];
701 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
702 TRACE("type=%d, attr=%d\n", type
, attr
);
703 if (attr
& RPC_FC_P_DONTFREE
) return;
705 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
706 else desc
= pFormat
+ *(SHORT
*)pFormat
;
707 if (attr
& RPC_FC_P_DEREF
) {
708 Pointer
= *(unsigned char**)Pointer
;
709 TRACE("deref => %p\n", Pointer
);
712 if (!Pointer
) return;
714 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
715 if (m
) m(pStubMsg
, Pointer
, desc
);
717 /* hmm... is this sensible?
718 * perhaps we should check if the memory comes from NdrAllocate,
719 * and deallocate only if so - checking if the pointer is between
720 * BufferStart and BufferEnd is probably no good since the buffer
721 * may be reallocated when the server wants to marshal the reply */
723 case RPC_FC_BOGUS_STRUCT
:
724 case RPC_FC_BOGUS_ARRAY
:
725 case RPC_FC_USER_MARSHAL
:
728 FIXME("unhandled data type=%02x\n", *desc
);
730 case RPC_FC_C_CSTRING
:
731 case RPC_FC_C_WSTRING
:
732 if (pStubMsg
->ReuseBuffer
) goto notfree
;
738 if (attr
& RPC_FC_P_ONSTACK
) {
739 TRACE("not freeing stack ptr %p\n", Pointer
);
742 TRACE("freeing %p\n", Pointer
);
743 NdrFree(pStubMsg
, Pointer
);
746 TRACE("not freeing %p\n", Pointer
);
749 /***********************************************************************
750 * EmbeddedPointerMarshall
752 unsigned char * WINAPI
EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
753 unsigned char *pMemory
,
754 PFORMAT_STRING pFormat
)
756 unsigned char *Mark
= pStubMsg
->BufferMark
;
757 unsigned long Offset
= pStubMsg
->Offset
;
758 unsigned ofs
, rep
, count
, stride
, xofs
;
760 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
762 if (*pFormat
!= RPC_FC_PP
) return NULL
;
765 while (pFormat
[0] != RPC_FC_END
) {
766 switch (pFormat
[0]) {
768 FIXME("unknown repeat type %d\n", pFormat
[0]);
769 case RPC_FC_NO_REPEAT
:
777 case RPC_FC_FIXED_REPEAT
:
778 rep
= *(WORD
*)&pFormat
[2];
779 stride
= *(WORD
*)&pFormat
[4];
780 ofs
= *(WORD
*)&pFormat
[6];
781 count
= *(WORD
*)&pFormat
[8];
785 case RPC_FC_VARIABLE_REPEAT
:
786 rep
= pStubMsg
->MaxCount
;
787 stride
= *(WORD
*)&pFormat
[2];
788 ofs
= *(WORD
*)&pFormat
[4];
789 count
= *(WORD
*)&pFormat
[6];
790 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
794 /* ofs doesn't seem to matter in this context */
796 PFORMAT_STRING info
= pFormat
;
797 unsigned char *membase
= pMemory
+ xofs
;
799 for (u
=0; u
<count
; u
++,info
+=8) {
800 unsigned char *memptr
= membase
+ *(SHORT
*)&info
[0];
801 unsigned char *bufptr
= Mark
+ *(SHORT
*)&info
[2];
802 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
806 pFormat
+= 8 * count
;
809 STD_OVERFLOW_CHECK(pStubMsg
);
814 /***********************************************************************
815 * EmbeddedPointerUnmarshall
817 unsigned char * WINAPI
EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
818 unsigned char **ppMemory
,
819 PFORMAT_STRING pFormat
,
820 unsigned char fMustAlloc
)
822 unsigned char *Mark
= pStubMsg
->BufferMark
;
823 unsigned long Offset
= pStubMsg
->Offset
;
824 unsigned ofs
, rep
, count
, stride
, xofs
;
826 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
828 if (*pFormat
!= RPC_FC_PP
) return NULL
;
831 while (pFormat
[0] != RPC_FC_END
) {
832 switch (pFormat
[0]) {
834 FIXME("unknown repeat type %d\n", pFormat
[0]);
835 case RPC_FC_NO_REPEAT
:
843 case RPC_FC_FIXED_REPEAT
:
844 rep
= *(WORD
*)&pFormat
[2];
845 stride
= *(WORD
*)&pFormat
[4];
846 ofs
= *(WORD
*)&pFormat
[6];
847 count
= *(WORD
*)&pFormat
[8];
851 case RPC_FC_VARIABLE_REPEAT
:
852 rep
= pStubMsg
->MaxCount
;
853 stride
= *(WORD
*)&pFormat
[2];
854 ofs
= *(WORD
*)&pFormat
[4];
855 count
= *(WORD
*)&pFormat
[6];
856 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
860 /* ofs doesn't seem to matter in this context */
862 PFORMAT_STRING info
= pFormat
;
863 unsigned char *membase
= *ppMemory
+ xofs
;
865 for (u
=0; u
<count
; u
++,info
+=8) {
866 unsigned char *memptr
= membase
+ *(SHORT
*)&info
[0];
867 unsigned char *bufptr
= Mark
+ *(SHORT
*)&info
[2];
868 PointerUnmarshall(pStubMsg
, bufptr
, (unsigned char**)memptr
, info
+4, fMustAlloc
);
872 pFormat
+= 8 * count
;
878 /***********************************************************************
879 * EmbeddedPointerBufferSize
881 void WINAPI
EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
882 unsigned char *pMemory
,
883 PFORMAT_STRING pFormat
)
885 unsigned long Offset
= pStubMsg
->Offset
;
886 unsigned ofs
, rep
, count
, stride
, xofs
;
888 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
889 if (*pFormat
!= RPC_FC_PP
) return;
892 while (pFormat
[0] != RPC_FC_END
) {
893 switch (pFormat
[0]) {
895 FIXME("unknown repeat type %d\n", pFormat
[0]);
896 case RPC_FC_NO_REPEAT
:
904 case RPC_FC_FIXED_REPEAT
:
905 rep
= *(WORD
*)&pFormat
[2];
906 stride
= *(WORD
*)&pFormat
[4];
907 ofs
= *(WORD
*)&pFormat
[6];
908 count
= *(WORD
*)&pFormat
[8];
912 case RPC_FC_VARIABLE_REPEAT
:
913 rep
= pStubMsg
->MaxCount
;
914 stride
= *(WORD
*)&pFormat
[2];
915 ofs
= *(WORD
*)&pFormat
[4];
916 count
= *(WORD
*)&pFormat
[6];
917 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
921 /* ofs doesn't seem to matter in this context */
923 PFORMAT_STRING info
= pFormat
;
924 unsigned char *membase
= pMemory
+ xofs
;
926 for (u
=0; u
<count
; u
++,info
+=8) {
927 unsigned char *memptr
= membase
+ *(SHORT
*)&info
[0];
928 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
932 pFormat
+= 8 * count
;
936 /***********************************************************************
937 * EmbeddedPointerMemorySize
939 unsigned long WINAPI
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
940 PFORMAT_STRING pFormat
)
942 unsigned long Offset
= pStubMsg
->Offset
;
943 unsigned char *Mark
= pStubMsg
->BufferMark
;
944 unsigned ofs
, rep
, count
, stride
, xofs
;
946 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
947 if (*pFormat
!= RPC_FC_PP
) return 0;
950 while (pFormat
[0] != RPC_FC_END
) {
951 switch (pFormat
[0]) {
953 FIXME("unknown repeat type %d\n", pFormat
[0]);
954 case RPC_FC_NO_REPEAT
:
962 case RPC_FC_FIXED_REPEAT
:
963 rep
= *(WORD
*)&pFormat
[2];
964 stride
= *(WORD
*)&pFormat
[4];
965 ofs
= *(WORD
*)&pFormat
[6];
966 count
= *(WORD
*)&pFormat
[8];
970 case RPC_FC_VARIABLE_REPEAT
:
971 rep
= pStubMsg
->MaxCount
;
972 stride
= *(WORD
*)&pFormat
[2];
973 ofs
= *(WORD
*)&pFormat
[4];
974 count
= *(WORD
*)&pFormat
[6];
975 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
979 /* ofs doesn't seem to matter in this context */
981 PFORMAT_STRING info
= pFormat
;
983 for (u
=0; u
<count
; u
++,info
+=8) {
984 unsigned char *bufptr
= Mark
+ *(SHORT
*)&info
[2];
985 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
989 pFormat
+= 8 * count
;
995 /***********************************************************************
996 * EmbeddedPointerFree
998 void WINAPI
EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
999 unsigned char *pMemory
,
1000 PFORMAT_STRING pFormat
)
1002 unsigned long Offset
= pStubMsg
->Offset
;
1003 unsigned ofs
, rep
, count
, stride
, xofs
;
1005 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1006 if (*pFormat
!= RPC_FC_PP
) return;
1009 while (pFormat
[0] != RPC_FC_END
) {
1010 switch (pFormat
[0]) {
1012 FIXME("unknown repeat type %d\n", pFormat
[0]);
1013 case RPC_FC_NO_REPEAT
:
1021 case RPC_FC_FIXED_REPEAT
:
1022 rep
= *(WORD
*)&pFormat
[2];
1023 stride
= *(WORD
*)&pFormat
[4];
1024 ofs
= *(WORD
*)&pFormat
[6];
1025 count
= *(WORD
*)&pFormat
[8];
1029 case RPC_FC_VARIABLE_REPEAT
:
1030 rep
= pStubMsg
->MaxCount
;
1031 stride
= *(WORD
*)&pFormat
[2];
1032 ofs
= *(WORD
*)&pFormat
[4];
1033 count
= *(WORD
*)&pFormat
[6];
1034 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1038 /* ofs doesn't seem to matter in this context */
1040 PFORMAT_STRING info
= pFormat
;
1041 unsigned char *membase
= pMemory
+ xofs
;
1043 for (u
=0; u
<count
; u
++,info
+=8) {
1044 unsigned char *memptr
= membase
+ *(SHORT
*)&info
[0];
1045 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1049 pFormat
+= 8 * count
;
1053 /***********************************************************************
1054 * NdrPointerMarshall [RPCRT4.@]
1056 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1057 unsigned char *pMemory
,
1058 PFORMAT_STRING pFormat
)
1060 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1062 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1063 PointerMarshall(pStubMsg
, pStubMsg
->Buffer
, pMemory
, pFormat
);
1064 pStubMsg
->Buffer
+= 4;
1066 STD_OVERFLOW_CHECK(pStubMsg
);
1071 /***********************************************************************
1072 * NdrPointerUnmarshall [RPCRT4.@]
1074 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1075 unsigned char **ppMemory
,
1076 PFORMAT_STRING pFormat
,
1077 unsigned char fMustAlloc
)
1079 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1081 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1082 PointerUnmarshall(pStubMsg
, pStubMsg
->Buffer
, ppMemory
, pFormat
, fMustAlloc
);
1083 pStubMsg
->Buffer
+= 4;
1088 /***********************************************************************
1089 * NdrPointerBufferSize [RPCRT4.@]
1091 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1092 unsigned char *pMemory
,
1093 PFORMAT_STRING pFormat
)
1095 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1096 pStubMsg
->BufferLength
+= 4;
1097 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1100 /***********************************************************************
1101 * NdrPointerMemorySize [RPCRT4.@]
1103 unsigned long WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1104 PFORMAT_STRING pFormat
)
1106 /* unsigned size = *(LPWORD)(pFormat+2); */
1107 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1108 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1112 /***********************************************************************
1113 * NdrPointerFree [RPCRT4.@]
1115 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1116 unsigned char *pMemory
,
1117 PFORMAT_STRING pFormat
)
1119 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1120 PointerFree(pStubMsg
, pMemory
, pFormat
);
1123 /***********************************************************************
1124 * NdrSimpleStructMarshall [RPCRT4.@]
1126 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1127 unsigned char *pMemory
,
1128 PFORMAT_STRING pFormat
)
1130 unsigned size
= *(LPWORD
)(pFormat
+2);
1131 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1133 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
1134 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1135 pStubMsg
->Buffer
+= size
;
1137 if (pFormat
[0] != RPC_FC_STRUCT
)
1138 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1140 STD_OVERFLOW_CHECK(pStubMsg
);
1145 /***********************************************************************
1146 * NdrSimpleStructUnmarshall [RPCRT4.@]
1148 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1149 unsigned char **ppMemory
,
1150 PFORMAT_STRING pFormat
,
1151 unsigned char fMustAlloc
)
1153 unsigned size
= *(LPWORD
)(pFormat
+2);
1154 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1157 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1158 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1160 if (pStubMsg
->ReuseBuffer
&& !*ppMemory
)
1161 /* for servers, we may just point straight into the RPC buffer, I think
1162 * (I guess that's what MS does since MIDL code doesn't try to free) */
1163 *ppMemory
= pStubMsg
->Buffer
;
1165 /* for clients, memory should be provided by caller */
1166 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1169 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1170 pStubMsg
->Buffer
+= size
;
1172 if (pFormat
[0] != RPC_FC_STRUCT
)
1173 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
+4, fMustAlloc
);
1179 /***********************************************************************
1180 * NdrSimpleStructUnmarshall [RPCRT4.@]
1182 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1183 unsigned char FormatChar
)
1189 /***********************************************************************
1190 * NdrSimpleStructUnmarshall [RPCRT4.@]
1192 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1193 unsigned char FormatChar
)
1199 /***********************************************************************
1200 * NdrSimpleStructBufferSize [RPCRT4.@]
1202 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1203 unsigned char *pMemory
,
1204 PFORMAT_STRING pFormat
)
1206 unsigned size
= *(LPWORD
)(pFormat
+2);
1207 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1208 pStubMsg
->BufferLength
+= size
;
1209 if (pFormat
[0] != RPC_FC_STRUCT
)
1210 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1213 /***********************************************************************
1214 * NdrSimpleStructMemorySize [RPCRT4.@]
1216 unsigned long WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1217 PFORMAT_STRING pFormat
)
1219 /* unsigned size = *(LPWORD)(pFormat+2); */
1220 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1221 if (pFormat
[0] != RPC_FC_STRUCT
)
1222 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1226 /***********************************************************************
1227 * NdrSimpleStructFree [RPCRT4.@]
1229 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1230 unsigned char *pMemory
,
1231 PFORMAT_STRING pFormat
)
1233 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1234 if (pFormat
[0] != RPC_FC_STRUCT
)
1235 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1239 unsigned long WINAPI
EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg
,
1240 PFORMAT_STRING pFormat
)
1244 case RPC_FC_PSTRUCT
:
1245 case RPC_FC_CSTRUCT
:
1246 case RPC_FC_BOGUS_STRUCT
:
1247 return *(WORD
*)&pFormat
[2];
1248 case RPC_FC_USER_MARSHAL
:
1249 return *(WORD
*)&pFormat
[4];
1251 FIXME("unhandled embedded type %02x\n", *pFormat
);
1257 unsigned char * WINAPI
ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1258 unsigned char *pMemory
,
1259 PFORMAT_STRING pFormat
,
1260 PFORMAT_STRING pPointer
)
1262 PFORMAT_STRING desc
;
1266 while (*pFormat
!= RPC_FC_END
) {
1270 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1271 memcpy(pStubMsg
->Buffer
, pMemory
, 2);
1272 pStubMsg
->Buffer
+= 2;
1277 TRACE("long=%ld <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1278 memcpy(pStubMsg
->Buffer
, pMemory
, 4);
1279 pStubMsg
->Buffer
+= 4;
1282 case RPC_FC_POINTER
:
1283 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1284 NdrPointerMarshall(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1288 case RPC_FC_ALIGNM4
:
1289 ALIGN_POINTER(pMemory
, 3);
1291 case RPC_FC_ALIGNM8
:
1292 ALIGN_POINTER(pMemory
, 7);
1294 case RPC_FC_EMBEDDED_COMPLEX
:
1295 pMemory
+= pFormat
[1];
1297 desc
= pFormat
+ *(SHORT
*)pFormat
;
1298 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1299 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1300 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1301 if (m
) m(pStubMsg
, pMemory
, desc
);
1302 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1309 FIXME("unhandled format %02x\n", *pFormat
);
1317 unsigned char * WINAPI
ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1318 unsigned char *pMemory
,
1319 PFORMAT_STRING pFormat
,
1320 PFORMAT_STRING pPointer
,
1321 unsigned char fMustAlloc
)
1323 PFORMAT_STRING desc
;
1327 while (*pFormat
!= RPC_FC_END
) {
1331 memcpy(pMemory
, pStubMsg
->Buffer
, 2);
1332 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1333 pStubMsg
->Buffer
+= 2;
1338 memcpy(pMemory
, pStubMsg
->Buffer
, 4);
1339 TRACE("long=%ld => %p\n", *(DWORD
*)pMemory
, pMemory
);
1340 pStubMsg
->Buffer
+= 4;
1343 case RPC_FC_POINTER
:
1344 *(unsigned char**)pMemory
= NULL
;
1345 TRACE("pointer => %p\n", pMemory
);
1346 NdrPointerUnmarshall(pStubMsg
, (unsigned char**)pMemory
, pPointer
, fMustAlloc
);
1350 case RPC_FC_ALIGNM4
:
1351 ALIGN_POINTER(pMemory
, 3);
1353 case RPC_FC_ALIGNM8
:
1354 ALIGN_POINTER(pMemory
, 7);
1356 case RPC_FC_EMBEDDED_COMPLEX
:
1357 pMemory
+= pFormat
[1];
1359 desc
= pFormat
+ *(SHORT
*)pFormat
;
1360 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1361 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
1362 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1363 memset(pMemory
, 0, size
); /* just in case */
1364 if (m
) m(pStubMsg
, &pMemory
, desc
, fMustAlloc
);
1365 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
1372 FIXME("unhandled format %d\n", *pFormat
);
1380 unsigned char * WINAPI
ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1381 unsigned char *pMemory
,
1382 PFORMAT_STRING pFormat
,
1383 PFORMAT_STRING pPointer
)
1385 PFORMAT_STRING desc
;
1389 while (*pFormat
!= RPC_FC_END
) {
1393 pStubMsg
->BufferLength
+= 2;
1398 pStubMsg
->BufferLength
+= 4;
1401 case RPC_FC_POINTER
:
1402 NdrPointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1406 case RPC_FC_ALIGNM4
:
1407 ALIGN_POINTER(pMemory
, 3);
1409 case RPC_FC_ALIGNM8
:
1410 ALIGN_POINTER(pMemory
, 7);
1412 case RPC_FC_EMBEDDED_COMPLEX
:
1413 pMemory
+= pFormat
[1];
1415 desc
= pFormat
+ *(SHORT
*)pFormat
;
1416 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1417 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1418 if (m
) m(pStubMsg
, pMemory
, desc
);
1419 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
1426 FIXME("unhandled format %d\n", *pFormat
);
1434 unsigned char * WINAPI
ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
1435 unsigned char *pMemory
,
1436 PFORMAT_STRING pFormat
,
1437 PFORMAT_STRING pPointer
)
1439 PFORMAT_STRING desc
;
1443 while (*pFormat
!= RPC_FC_END
) {
1453 case RPC_FC_POINTER
:
1454 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1458 case RPC_FC_ALIGNM4
:
1459 ALIGN_POINTER(pMemory
, 3);
1461 case RPC_FC_ALIGNM8
:
1462 ALIGN_POINTER(pMemory
, 7);
1464 case RPC_FC_EMBEDDED_COMPLEX
:
1465 pMemory
+= pFormat
[1];
1467 desc
= pFormat
+ *(SHORT
*)pFormat
;
1468 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1469 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1470 if (m
) m(pStubMsg
, pMemory
, desc
);
1471 else FIXME("no freer for embedded type %02x\n", *desc
);
1478 FIXME("unhandled format %d\n", *pFormat
);
1486 unsigned long WINAPI
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
,
1487 PFORMAT_STRING pFormat
)
1489 PFORMAT_STRING desc
;
1490 unsigned long size
= 0;
1492 while (*pFormat
!= RPC_FC_END
) {
1502 case RPC_FC_POINTER
:
1505 case RPC_FC_ALIGNM4
:
1506 ALIGN_LENGTH(size
, 3);
1508 case RPC_FC_ALIGNM8
:
1509 ALIGN_LENGTH(size
, 7);
1511 case RPC_FC_EMBEDDED_COMPLEX
:
1514 desc
= pFormat
+ *(SHORT
*)pFormat
;
1515 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
1521 FIXME("unhandled format %d\n", *pFormat
);
1529 /***********************************************************************
1530 * NdrComplexStructMarshall [RPCRT4.@]
1532 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1533 unsigned char *pMemory
,
1534 PFORMAT_STRING pFormat
)
1536 PFORMAT_STRING conf_array
= NULL
;
1537 PFORMAT_STRING pointer_desc
= NULL
;
1538 unsigned char *OldMemory
= pStubMsg
->Memory
;
1540 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1543 if (*(WORD
*)pFormat
) conf_array
= pFormat
+ *(WORD
*)pFormat
;
1545 if (*(WORD
*)pFormat
) pointer_desc
= pFormat
+ *(WORD
*)pFormat
;
1548 pStubMsg
->Memory
= pMemory
;
1550 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
1553 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
1555 pStubMsg
->Memory
= OldMemory
;
1557 STD_OVERFLOW_CHECK(pStubMsg
);
1562 /***********************************************************************
1563 * NdrComplexStructUnmarshall [RPCRT4.@]
1565 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1566 unsigned char **ppMemory
,
1567 PFORMAT_STRING pFormat
,
1568 unsigned char fMustAlloc
)
1570 unsigned size
= *(LPWORD
)(pFormat
+2);
1571 PFORMAT_STRING conf_array
= NULL
;
1572 PFORMAT_STRING pointer_desc
= NULL
;
1573 unsigned char *pMemory
;
1575 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1577 if (fMustAlloc
|| !*ppMemory
)
1578 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1581 if (*(WORD
*)pFormat
) conf_array
= pFormat
+ *(WORD
*)pFormat
;
1583 if (*(WORD
*)pFormat
) pointer_desc
= pFormat
+ *(WORD
*)pFormat
;
1586 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
1589 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
1594 /***********************************************************************
1595 * NdrComplexStructBufferSize [RPCRT4.@]
1597 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1598 unsigned char *pMemory
,
1599 PFORMAT_STRING pFormat
)
1601 PFORMAT_STRING conf_array
= NULL
;
1602 PFORMAT_STRING pointer_desc
= NULL
;
1603 unsigned char *OldMemory
= pStubMsg
->Memory
;
1605 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1608 if (*(WORD
*)pFormat
) conf_array
= pFormat
+ *(WORD
*)pFormat
;
1610 if (*(WORD
*)pFormat
) pointer_desc
= pFormat
+ *(WORD
*)pFormat
;
1613 pStubMsg
->Memory
= pMemory
;
1615 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
1618 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
1620 pStubMsg
->Memory
= OldMemory
;
1623 /***********************************************************************
1624 * NdrComplexStructMemorySize [RPCRT4.@]
1626 unsigned long WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1627 PFORMAT_STRING pFormat
)
1629 /* unsigned size = *(LPWORD)(pFormat+2); */
1630 PFORMAT_STRING conf_array
= NULL
;
1631 PFORMAT_STRING pointer_desc
= NULL
;
1633 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1636 if (*(WORD
*)pFormat
) conf_array
= pFormat
+ *(WORD
*)pFormat
;
1638 if (*(WORD
*)pFormat
) pointer_desc
= pFormat
+ *(WORD
*)pFormat
;
1644 /***********************************************************************
1645 * NdrComplexStructFree [RPCRT4.@]
1647 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1648 unsigned char *pMemory
,
1649 PFORMAT_STRING pFormat
)
1651 PFORMAT_STRING conf_array
= NULL
;
1652 PFORMAT_STRING pointer_desc
= NULL
;
1653 unsigned char *OldMemory
= pStubMsg
->Memory
;
1655 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1658 if (*(WORD
*)pFormat
) conf_array
= pFormat
+ *(WORD
*)pFormat
;
1660 if (*(WORD
*)pFormat
) pointer_desc
= pFormat
+ *(WORD
*)pFormat
;
1663 pStubMsg
->Memory
= pMemory
;
1665 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
1668 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
1670 pStubMsg
->Memory
= OldMemory
;
1673 /***********************************************************************
1674 * NdrConformantArrayMarshall [RPCRT4.@]
1676 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1677 unsigned char *pMemory
,
1678 PFORMAT_STRING pFormat
)
1680 DWORD size
= 0, esize
= *(LPWORD
)(pFormat
+2);
1681 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1682 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1684 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1685 size
= pStubMsg
->MaxCount
;
1687 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, size
);
1688 pStubMsg
->Buffer
+= 4;
1690 memcpy(pStubMsg
->Buffer
, pMemory
, size
*esize
);
1691 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1692 pStubMsg
->Buffer
+= size
*esize
;
1694 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1696 STD_OVERFLOW_CHECK(pStubMsg
);
1701 /***********************************************************************
1702 * NdrConformantArrayUnmarshall [RPCRT4.@]
1704 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1705 unsigned char **ppMemory
,
1706 PFORMAT_STRING pFormat
,
1707 unsigned char fMustAlloc
)
1709 DWORD size
= 0, esize
= *(LPWORD
)(pFormat
+2);
1710 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1711 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1713 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1714 size
= pStubMsg
->MaxCount
;
1717 *ppMemory
= NdrAllocate(pStubMsg
, size
*esize
);
1718 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
*esize
);
1720 if (pStubMsg
->ReuseBuffer
&& !*ppMemory
)
1721 /* for servers, we may just point straight into the RPC buffer, I think
1722 * (I guess that's what MS does since MIDL code doesn't try to free) */
1723 *ppMemory
= pStubMsg
->Buffer
;
1725 /* for clients, memory should be provided by caller */
1726 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
*esize
);
1729 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1730 pStubMsg
->Buffer
+= size
*esize
;
1732 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1737 /***********************************************************************
1738 * NdrConformantArrayBufferSize [RPCRT4.@]
1740 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1741 unsigned char *pMemory
,
1742 PFORMAT_STRING pFormat
)
1744 DWORD size
= 0, esize
= *(LPWORD
)(pFormat
+2);
1745 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1746 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1748 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1749 size
= pStubMsg
->MaxCount
;
1751 pStubMsg
->BufferLength
+= size
*esize
;
1753 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1756 /***********************************************************************
1757 * NdrConformantArrayMemorySize [RPCRT4.@]
1759 unsigned long WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1760 PFORMAT_STRING pFormat
)
1763 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1764 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1766 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1767 size
= pStubMsg
->MaxCount
;
1769 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
1774 /***********************************************************************
1775 * NdrConformantArrayFree [RPCRT4.@]
1777 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
1778 unsigned char *pMemory
,
1779 PFORMAT_STRING pFormat
)
1781 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1782 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1784 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
1788 /***********************************************************************
1789 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
1791 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
1792 unsigned char* pMemory
,
1793 PFORMAT_STRING pFormat
)
1800 /***********************************************************************
1801 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
1803 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
1804 unsigned char** ppMemory
,
1805 PFORMAT_STRING pFormat
,
1806 unsigned char fMustAlloc
)
1813 /***********************************************************************
1814 * NdrConformantVaryingArrayFree [RPCRT4.@]
1816 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
1817 unsigned char* pMemory
,
1818 PFORMAT_STRING pFormat
)
1824 /***********************************************************************
1825 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
1827 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
1828 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
1834 /***********************************************************************
1835 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
1837 unsigned long WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
1838 PFORMAT_STRING pFormat
)
1845 /***********************************************************************
1846 * NdrComplexArrayMarshall [RPCRT4.@]
1848 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1849 unsigned char *pMemory
,
1850 PFORMAT_STRING pFormat
)
1852 DWORD size
= 0, count
, def
;
1853 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1855 def
= *(WORD
*)&pFormat
[2];
1858 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1859 size
= pStubMsg
->MaxCount
;
1860 TRACE("conformance=%ld\n", size
);
1862 if (*(DWORD
*)pFormat
!= 0xffffffff)
1863 FIXME("compute variance\n");
1866 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, size
);
1867 pStubMsg
->Buffer
+= 4;
1869 for (count
=0; count
<size
; count
++)
1870 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
1872 STD_OVERFLOW_CHECK(pStubMsg
);
1877 /***********************************************************************
1878 * NdrComplexArrayUnmarshall [RPCRT4.@]
1880 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1881 unsigned char **ppMemory
,
1882 PFORMAT_STRING pFormat
,
1883 unsigned char fMustAlloc
)
1885 DWORD size
= 0, count
, esize
;
1886 unsigned char *pMemory
;
1887 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1891 pFormat
= ReadConformance(pStubMsg
, pFormat
);
1892 size
= pStubMsg
->MaxCount
;
1893 TRACE("conformance=%ld\n", size
);
1897 esize
= ComplexStructSize(pStubMsg
, pFormat
);
1899 if (fMustAlloc
|| !*ppMemory
)
1900 *ppMemory
= NdrAllocate(pStubMsg
, size
*esize
);
1902 pMemory
= *ppMemory
;
1903 for (count
=0; count
<size
; count
++)
1904 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
1909 /***********************************************************************
1910 * NdrComplexArrayBufferSize [RPCRT4.@]
1912 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1913 unsigned char *pMemory
,
1914 PFORMAT_STRING pFormat
)
1916 DWORD size
= 0, count
, def
;
1917 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1919 def
= *(WORD
*)&pFormat
[2];
1922 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1923 size
= pStubMsg
->MaxCount
;
1924 TRACE("conformance=%ld\n", size
);
1926 if (*(DWORD
*)pFormat
!= 0xffffffff)
1927 FIXME("compute variance\n");
1930 for (count
=0; count
<size
; count
++)
1931 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
1934 /***********************************************************************
1935 * NdrComplexArrayMemorySize [RPCRT4.@]
1937 unsigned long WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1938 PFORMAT_STRING pFormat
)
1941 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1945 pFormat
= ReadConformance(pStubMsg
, pFormat
);
1946 size
= pStubMsg
->MaxCount
;
1947 TRACE("conformance=%ld\n", size
);
1954 /***********************************************************************
1955 * NdrComplexArrayFree [RPCRT4.@]
1957 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
1958 unsigned char *pMemory
,
1959 PFORMAT_STRING pFormat
)
1961 DWORD size
= 0, count
, def
;
1962 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1964 def
= *(WORD
*)&pFormat
[2];
1967 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1968 size
= pStubMsg
->MaxCount
;
1969 TRACE("conformance=%ld\n", size
);
1971 if (*(DWORD
*)pFormat
!= 0xffffffff)
1972 FIXME("compute variance\n");
1975 for (count
=0; count
<size
; count
++)
1976 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
1979 unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg
)
1981 return MAKELONG(pStubMsg
->dwDestContext
,
1982 pStubMsg
->RpcMsg
->DataRepresentation
);
1985 /***********************************************************************
1986 * NdrUserMarshalMarshall [RPCRT4.@]
1988 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1989 unsigned char *pMemory
,
1990 PFORMAT_STRING pFormat
)
1992 /* unsigned flags = pFormat[1]; */
1993 unsigned index
= *(WORD
*)&pFormat
[2];
1994 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
1995 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1996 TRACE("index=%d\n", index
);
1999 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
2000 &uflag
, pStubMsg
->Buffer
, pMemory
);
2002 STD_OVERFLOW_CHECK(pStubMsg
);
2007 /***********************************************************************
2008 * NdrUserMarshalUnmarshall [RPCRT4.@]
2010 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2011 unsigned char **ppMemory
,
2012 PFORMAT_STRING pFormat
,
2013 unsigned char fMustAlloc
)
2015 /* unsigned flags = pFormat[1];*/
2016 unsigned index
= *(WORD
*)&pFormat
[2];
2017 DWORD memsize
= *(WORD
*)&pFormat
[4];
2018 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2019 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2020 TRACE("index=%d\n", index
);
2022 if (fMustAlloc
|| !*ppMemory
)
2023 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2026 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
2027 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
2032 /***********************************************************************
2033 * NdrUserMarshalBufferSize [RPCRT4.@]
2035 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2036 unsigned char *pMemory
,
2037 PFORMAT_STRING pFormat
)
2039 /* unsigned flags = pFormat[1];*/
2040 unsigned index
= *(WORD
*)&pFormat
[2];
2041 DWORD bufsize
= *(WORD
*)&pFormat
[6];
2042 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2043 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2044 TRACE("index=%d\n", index
);
2047 TRACE("size=%ld\n", bufsize
);
2048 pStubMsg
->BufferLength
+= bufsize
;
2052 pStubMsg
->BufferLength
=
2053 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
2054 &uflag
, pStubMsg
->BufferLength
, pMemory
);
2057 /***********************************************************************
2058 * NdrUserMarshalMemorySize [RPCRT4.@]
2060 unsigned long WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2061 PFORMAT_STRING pFormat
)
2063 unsigned index
= *(WORD
*)&pFormat
[2];
2064 /* DWORD memsize = *(WORD*)&pFormat[4]; */
2065 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
2066 TRACE("index=%d\n", index
);
2071 /***********************************************************************
2072 * NdrUserMarshalFree [RPCRT4.@]
2074 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
2075 unsigned char *pMemory
,
2076 PFORMAT_STRING pFormat
)
2078 /* unsigned flags = pFormat[1]; */
2079 unsigned index
= *(WORD
*)&pFormat
[2];
2080 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2081 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2082 TRACE("index=%d\n", index
);
2084 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
2088 /***********************************************************************
2089 * NdrClearOutParameters [RPCRT4.@]
2091 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
2092 PFORMAT_STRING pFormat
,
2095 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
2098 /***********************************************************************
2099 * NdrConvert [RPCRT4.@]
2101 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2103 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
2104 /* FIXME: since this stub doesn't do any converting, the proper behavior
2105 is to raise an exception */
2108 /***********************************************************************
2109 * NdrConvert2 [RPCRT4.@]
2111 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, long NumberParams
)
2113 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2114 pStubMsg
, pFormat
, NumberParams
);
2115 /* FIXME: since this stub doesn't do any converting, the proper behavior
2116 is to raise an exception */