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 (pszMessage
== NULL
) {
392 TRACE("string=%s\n", debugstr_a(pszMessage
));
396 else if (*pFormat
== RPC_FC_C_CSTRING
) {
397 TRACE("string=%s\n", debugstr_a(pszMessage
));
398 len
= strlen(pszMessage
)+1;
401 else if (*pFormat
== RPC_FC_C_WSTRING
) {
402 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
403 len
= strlenW((LPWSTR
)pszMessage
)+1;
407 ERR("Unhandled string type: %#x\n", *pFormat
);
408 /* FIXME: raise an exception. */
412 if (pFormat
[1] != RPC_FC_PAD
) {
413 FIXME("sized string format=%d\n", pFormat
[1]);
416 assert( (pStubMsg
->BufferLength
>= (len
*esize
+ 13)) && (pStubMsg
->Buffer
!= NULL
) );
418 c
= pStubMsg
->Buffer
;
420 NDR_LOCAL_UINT32_WRITE(c
, len
); /* max length: strlen + 1 (for '\0') */
421 c
+= 8; /* offset: 0 */
422 NDR_LOCAL_UINT32_WRITE(c
, len
); /* actual length: (same) */
425 memcpy(c
, pszMessage
, len
*esize
); /* the string itself */
428 pStubMsg
->Buffer
= c
;
430 STD_OVERFLOW_CHECK(pStubMsg
);
433 return NULL
; /* is this always right? */
436 /***********************************************************************
437 * NdrConformantStringBufferSize [RPCRT4.@]
439 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
440 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
442 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
445 if (pMemory
== NULL
) {
446 /* we need 12 octets for the [maxlen, offset, len] DWORDS */
447 TRACE("string=NULL\n");
448 pStubMsg
->BufferLength
+= 12 + BUFFER_PARANOIA
;
450 else if (*pFormat
== RPC_FC_C_CSTRING
) {
451 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 1 octet for '\0' */
452 TRACE("string=%s\n", debugstr_a(pMemory
));
453 pStubMsg
->BufferLength
+= strlen(pMemory
) + 13 + BUFFER_PARANOIA
;
455 else if (*pFormat
== RPC_FC_C_WSTRING
) {
456 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 2 octets for L'\0' */
457 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
458 pStubMsg
->BufferLength
+= strlenW((LPWSTR
)pMemory
)*2 + 14 + BUFFER_PARANOIA
;
461 ERR("Unhandled string type: %#x\n", *pFormat
);
462 /* FIXME: raise an exception */
465 if (pFormat
[1] != RPC_FC_PAD
) {
466 FIXME("sized string format=%d\n", pFormat
[1]);
470 /************************************************************************
471 * NdrConformantStringMemorySize [RPCRT4.@]
473 unsigned long WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
474 PFORMAT_STRING pFormat
)
476 unsigned long rslt
= 0;
478 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
480 assert(pStubMsg
&& pFormat
);
482 if (*pFormat
== RPC_FC_C_CSTRING
) {
483 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
); /* maxlen */
485 else if (*pFormat
== RPC_FC_C_WSTRING
) {
486 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
)*2; /* maxlen */
489 ERR("Unhandled string type: %#x\n", *pFormat
);
490 /* FIXME: raise an exception */
493 if (pFormat
[1] != RPC_FC_PAD
) {
494 FIXME("sized string format=%d\n", pFormat
[1]);
497 TRACE(" --> %lu\n", rslt
);
501 /************************************************************************
502 * NdrConformantStringUnmarshall [RPCRT4.@]
504 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
505 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
507 unsigned long len
, esize
, ofs
;
510 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
511 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
513 assert(pFormat
&& ppMemory
&& pStubMsg
);
515 pStubMsg
->Buffer
+= 4;
516 ofs
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
517 pStubMsg
->Buffer
+= 4;
518 len
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
519 pStubMsg
->Buffer
+= 4;
521 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
522 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
524 ERR("Unhandled string type: %#x\n", *pFormat
);
525 /* FIXME: raise an exception */
529 if (pFormat
[1] != RPC_FC_PAD
) {
530 FIXME("sized string format=%d\n", pFormat
[1]);
534 *ppMemory
= NdrAllocate(pStubMsg
, len
*esize
+ BUFFER_PARANOIA
);
536 if (pStubMsg
->ReuseBuffer
&& !*ppMemory
)
537 /* for servers, we may just point straight into the RPC buffer, I think
538 * (I guess that's what MS does since MIDL code doesn't try to free) */
539 *ppMemory
= pStubMsg
->Buffer
- ofs
*esize
;
540 /* for clients, memory should be provided by caller */
548 pMem
= *ppMemory
+ ofs
*esize
;
550 if (pMem
!= pStubMsg
->Buffer
)
551 memcpy(pMem
, pStubMsg
->Buffer
, len
*esize
);
553 pStubMsg
->Buffer
+= len
*esize
;
555 if (*pFormat
== RPC_FC_C_CSTRING
) {
556 TRACE("string=%s\n", debugstr_a(pMem
));
558 else if (*pFormat
== RPC_FC_C_WSTRING
) {
559 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMem
));
562 return NULL
; /* FIXME: is this always right? */
565 static inline void dump_pointer_attr(unsigned char attr
)
567 if (attr
& RPC_FC_P_ALLOCALLNODES
)
568 TRACE(" RPC_FC_P_ALLOCALLNODES");
569 if (attr
& RPC_FC_P_DONTFREE
)
570 TRACE(" RPC_FC_P_DONTFREE");
571 if (attr
& RPC_FC_P_ONSTACK
)
572 TRACE(" RPC_FC_P_ONSTACK");
573 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
574 TRACE(" RPC_FC_P_SIMPLEPOINTER");
575 if (attr
& RPC_FC_P_DEREF
)
576 TRACE(" RPC_FC_P_DEREF");
580 /***********************************************************************
583 void WINAPI
PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
584 unsigned char *Buffer
,
585 unsigned char *Pointer
,
586 PFORMAT_STRING pFormat
)
588 unsigned type
= pFormat
[0], attr
= pFormat
[1];
592 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
593 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
595 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
596 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
597 if (attr
& RPC_FC_P_DEREF
) {
598 Pointer
= *(unsigned char**)Pointer
;
599 TRACE("deref => %p\n", Pointer
);
603 case RPC_FC_RP
: /* ref pointer (always non-null) */
604 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
606 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
609 case RPC_FC_UP
: /* unique pointer */
610 case RPC_FC_OP
: /* object pointer - same as unique here */
611 TRACE("writing %p to buffer\n", Pointer
);
612 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, (unsigned long)Pointer
);
613 pStubMsg
->Buffer
+= 4;
617 FIXME("unhandled ptr type=%02x\n", type
);
618 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
621 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
624 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
625 if (m
) m(pStubMsg
, Pointer
, desc
);
626 else FIXME("no marshaller for data type=%02x\n", *desc
);
629 STD_OVERFLOW_CHECK(pStubMsg
);
632 /***********************************************************************
635 void WINAPI
PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
636 unsigned char *Buffer
,
637 unsigned char **pPointer
,
638 PFORMAT_STRING pFormat
,
639 unsigned char fMustAlloc
)
641 unsigned type
= pFormat
[0], attr
= pFormat
[1];
644 DWORD pointer_id
= 0;
646 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pFormat
, fMustAlloc
);
647 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
649 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
650 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
651 if (attr
& RPC_FC_P_DEREF
) {
652 pPointer
= *(unsigned char***)pPointer
;
653 TRACE("deref => %p\n", pPointer
);
657 case RPC_FC_RP
: /* ref pointer (always non-null) */
660 case RPC_FC_UP
: /* unique pointer */
661 pointer_id
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
662 pStubMsg
->Buffer
+= 4;
664 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
667 FIXME("unhandled ptr type=%02x\n", type
);
668 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
674 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
675 if (m
) m(pStubMsg
, pPointer
, desc
, fMustAlloc
);
676 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
679 TRACE("pointer=%p\n", *pPointer
);
682 /***********************************************************************
685 void WINAPI
PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
686 unsigned char *Pointer
,
687 PFORMAT_STRING pFormat
)
689 unsigned type
= pFormat
[0], attr
= pFormat
[1];
693 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
694 TRACE("type=%d, attr=%d\n", type
, attr
);
696 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
697 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
698 if (attr
& RPC_FC_P_DEREF
) {
699 Pointer
= *(unsigned char**)Pointer
;
700 TRACE("deref => %p\n", Pointer
);
704 case RPC_FC_RP
: /* ref pointer (always non-null) */
708 pStubMsg
->BufferLength
+= 4;
709 /* NULL pointer has no further representation */
715 FIXME("unhandled ptr type=%02x\n", type
);
716 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
719 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
720 if (m
) m(pStubMsg
, Pointer
, desc
);
721 else FIXME("no buffersizer for data type=%02x\n", *desc
);
724 /***********************************************************************
725 * PointerMemorySize [RPCRT4.@]
727 unsigned long WINAPI
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
728 unsigned char *Buffer
,
729 PFORMAT_STRING pFormat
)
731 unsigned type
= pFormat
[0], attr
= pFormat
[1];
735 FIXME("(%p,%p,%p): stub\n", pStubMsg
, Buffer
, pFormat
);
736 TRACE("type=%d, attr=", type
); dump_pointer_attr(attr
);
738 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
739 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
740 if (attr
& RPC_FC_P_DEREF
) {
745 case RPC_FC_RP
: /* ref pointer (always non-null) */
748 FIXME("unhandled ptr type=%02x\n", type
);
749 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
752 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
753 if (m
) m(pStubMsg
, desc
);
754 else FIXME("no memorysizer for data type=%02x\n", *desc
);
759 /***********************************************************************
760 * PointerFree [RPCRT4.@]
762 void WINAPI
PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
763 unsigned char *Pointer
,
764 PFORMAT_STRING pFormat
)
766 unsigned type
= pFormat
[0], attr
= pFormat
[1];
770 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
771 TRACE("type=%d, attr=", type
); dump_pointer_attr(attr
);
772 if (attr
& RPC_FC_P_DONTFREE
) return;
774 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
775 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
776 if (attr
& RPC_FC_P_DEREF
) {
777 Pointer
= *(unsigned char**)Pointer
;
778 TRACE("deref => %p\n", Pointer
);
781 if (!Pointer
) return;
783 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
784 if (m
) m(pStubMsg
, Pointer
, desc
);
786 /* hmm... is this sensible?
787 * perhaps we should check if the memory comes from NdrAllocate,
788 * and deallocate only if so - checking if the pointer is between
789 * BufferStart and BufferEnd is probably no good since the buffer
790 * may be reallocated when the server wants to marshal the reply */
792 case RPC_FC_BOGUS_STRUCT
:
793 case RPC_FC_BOGUS_ARRAY
:
794 case RPC_FC_USER_MARSHAL
:
797 FIXME("unhandled data type=%02x\n", *desc
);
799 case RPC_FC_C_CSTRING
:
800 case RPC_FC_C_WSTRING
:
801 if (pStubMsg
->ReuseBuffer
) goto notfree
;
807 if (attr
& RPC_FC_P_ONSTACK
) {
808 TRACE("not freeing stack ptr %p\n", Pointer
);
811 TRACE("freeing %p\n", Pointer
);
812 NdrFree(pStubMsg
, Pointer
);
815 TRACE("not freeing %p\n", Pointer
);
818 /***********************************************************************
819 * EmbeddedPointerMarshall
821 unsigned char * WINAPI
EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
822 unsigned char *pMemory
,
823 PFORMAT_STRING pFormat
)
825 unsigned char *Mark
= pStubMsg
->BufferMark
;
826 unsigned long Offset
= pStubMsg
->Offset
;
827 unsigned ofs
, rep
, count
, stride
, xofs
;
829 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
831 if (*pFormat
!= RPC_FC_PP
) return NULL
;
834 while (pFormat
[0] != RPC_FC_END
) {
835 switch (pFormat
[0]) {
837 FIXME("unknown repeat type %d\n", pFormat
[0]);
838 case RPC_FC_NO_REPEAT
:
846 case RPC_FC_FIXED_REPEAT
:
847 rep
= *(const WORD
*)&pFormat
[2];
848 stride
= *(const WORD
*)&pFormat
[4];
849 ofs
= *(const WORD
*)&pFormat
[6];
850 count
= *(const WORD
*)&pFormat
[8];
854 case RPC_FC_VARIABLE_REPEAT
:
855 rep
= pStubMsg
->MaxCount
;
856 stride
= *(const WORD
*)&pFormat
[2];
857 ofs
= *(const WORD
*)&pFormat
[4];
858 count
= *(const WORD
*)&pFormat
[6];
859 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
863 /* ofs doesn't seem to matter in this context */
865 PFORMAT_STRING info
= pFormat
;
866 unsigned char *membase
= pMemory
+ xofs
;
868 for (u
=0; u
<count
; u
++,info
+=8) {
869 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
870 unsigned char *bufptr
= Mark
+ *(const SHORT
*)&info
[2];
871 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
875 pFormat
+= 8 * count
;
878 STD_OVERFLOW_CHECK(pStubMsg
);
883 /***********************************************************************
884 * EmbeddedPointerUnmarshall
886 unsigned char * WINAPI
EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
887 unsigned char **ppMemory
,
888 PFORMAT_STRING pFormat
,
889 unsigned char fMustAlloc
)
891 unsigned char *Mark
= pStubMsg
->BufferMark
;
892 unsigned long Offset
= pStubMsg
->Offset
;
893 unsigned ofs
, rep
, count
, stride
, xofs
;
895 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
897 if (*pFormat
!= RPC_FC_PP
) return NULL
;
900 while (pFormat
[0] != RPC_FC_END
) {
901 switch (pFormat
[0]) {
903 FIXME("unknown repeat type %d\n", pFormat
[0]);
904 case RPC_FC_NO_REPEAT
:
912 case RPC_FC_FIXED_REPEAT
:
913 rep
= *(const WORD
*)&pFormat
[2];
914 stride
= *(const WORD
*)&pFormat
[4];
915 ofs
= *(const WORD
*)&pFormat
[6];
916 count
= *(const WORD
*)&pFormat
[8];
920 case RPC_FC_VARIABLE_REPEAT
:
921 rep
= pStubMsg
->MaxCount
;
922 stride
= *(const WORD
*)&pFormat
[2];
923 ofs
= *(const WORD
*)&pFormat
[4];
924 count
= *(const WORD
*)&pFormat
[6];
925 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
929 /* ofs doesn't seem to matter in this context */
931 PFORMAT_STRING info
= pFormat
;
932 unsigned char *membase
= *ppMemory
+ xofs
;
934 for (u
=0; u
<count
; u
++,info
+=8) {
935 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
936 unsigned char *bufptr
= Mark
+ *(const SHORT
*)&info
[2];
937 PointerUnmarshall(pStubMsg
, bufptr
, (unsigned char**)memptr
, info
+4, fMustAlloc
);
941 pFormat
+= 8 * count
;
947 /***********************************************************************
948 * EmbeddedPointerBufferSize
950 void WINAPI
EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
951 unsigned char *pMemory
,
952 PFORMAT_STRING pFormat
)
954 unsigned long Offset
= pStubMsg
->Offset
;
955 unsigned ofs
, rep
, count
, stride
, xofs
;
957 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
958 if (*pFormat
!= RPC_FC_PP
) return;
961 while (pFormat
[0] != RPC_FC_END
) {
962 switch (pFormat
[0]) {
964 FIXME("unknown repeat type %d\n", pFormat
[0]);
965 case RPC_FC_NO_REPEAT
:
973 case RPC_FC_FIXED_REPEAT
:
974 rep
= *(const WORD
*)&pFormat
[2];
975 stride
= *(const WORD
*)&pFormat
[4];
976 ofs
= *(const WORD
*)&pFormat
[6];
977 count
= *(const WORD
*)&pFormat
[8];
981 case RPC_FC_VARIABLE_REPEAT
:
982 rep
= pStubMsg
->MaxCount
;
983 stride
= *(const WORD
*)&pFormat
[2];
984 ofs
= *(const WORD
*)&pFormat
[4];
985 count
= *(const WORD
*)&pFormat
[6];
986 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
990 /* ofs doesn't seem to matter in this context */
992 PFORMAT_STRING info
= pFormat
;
993 unsigned char *membase
= pMemory
+ xofs
;
995 for (u
=0; u
<count
; u
++,info
+=8) {
996 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
997 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1001 pFormat
+= 8 * count
;
1005 /***********************************************************************
1006 * EmbeddedPointerMemorySize
1008 unsigned long WINAPI
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1009 PFORMAT_STRING pFormat
)
1011 unsigned long Offset
= pStubMsg
->Offset
;
1012 unsigned char *Mark
= pStubMsg
->BufferMark
;
1013 unsigned ofs
, rep
, count
, stride
, xofs
;
1015 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1016 if (*pFormat
!= RPC_FC_PP
) return 0;
1019 while (pFormat
[0] != RPC_FC_END
) {
1020 switch (pFormat
[0]) {
1022 FIXME("unknown repeat type %d\n", pFormat
[0]);
1023 case RPC_FC_NO_REPEAT
:
1031 case RPC_FC_FIXED_REPEAT
:
1032 rep
= *(const WORD
*)&pFormat
[2];
1033 stride
= *(const WORD
*)&pFormat
[4];
1034 ofs
= *(const WORD
*)&pFormat
[6];
1035 count
= *(const WORD
*)&pFormat
[8];
1039 case RPC_FC_VARIABLE_REPEAT
:
1040 rep
= pStubMsg
->MaxCount
;
1041 stride
= *(const WORD
*)&pFormat
[2];
1042 ofs
= *(const WORD
*)&pFormat
[4];
1043 count
= *(const WORD
*)&pFormat
[6];
1044 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1048 /* ofs doesn't seem to matter in this context */
1050 PFORMAT_STRING info
= pFormat
;
1052 for (u
=0; u
<count
; u
++,info
+=8) {
1053 unsigned char *bufptr
= Mark
+ *(const SHORT
*)&info
[2];
1054 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1058 pFormat
+= 8 * count
;
1064 /***********************************************************************
1065 * EmbeddedPointerFree
1067 void WINAPI
EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1068 unsigned char *pMemory
,
1069 PFORMAT_STRING pFormat
)
1071 unsigned long Offset
= pStubMsg
->Offset
;
1072 unsigned ofs
, rep
, count
, stride
, xofs
;
1074 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1075 if (*pFormat
!= RPC_FC_PP
) return;
1078 while (pFormat
[0] != RPC_FC_END
) {
1079 switch (pFormat
[0]) {
1081 FIXME("unknown repeat type %d\n", pFormat
[0]);
1082 case RPC_FC_NO_REPEAT
:
1090 case RPC_FC_FIXED_REPEAT
:
1091 rep
= *(const WORD
*)&pFormat
[2];
1092 stride
= *(const WORD
*)&pFormat
[4];
1093 ofs
= *(const WORD
*)&pFormat
[6];
1094 count
= *(const WORD
*)&pFormat
[8];
1098 case RPC_FC_VARIABLE_REPEAT
:
1099 rep
= pStubMsg
->MaxCount
;
1100 stride
= *(const WORD
*)&pFormat
[2];
1101 ofs
= *(const WORD
*)&pFormat
[4];
1102 count
= *(const WORD
*)&pFormat
[6];
1103 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1107 /* ofs doesn't seem to matter in this context */
1109 PFORMAT_STRING info
= pFormat
;
1110 unsigned char *membase
= pMemory
+ xofs
;
1112 for (u
=0; u
<count
; u
++,info
+=8) {
1113 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1114 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1118 pFormat
+= 8 * count
;
1122 /***********************************************************************
1123 * NdrPointerMarshall [RPCRT4.@]
1125 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1126 unsigned char *pMemory
,
1127 PFORMAT_STRING pFormat
)
1129 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1131 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1132 PointerMarshall(pStubMsg
, pStubMsg
->Buffer
, pMemory
, pFormat
);
1134 STD_OVERFLOW_CHECK(pStubMsg
);
1139 /***********************************************************************
1140 * NdrPointerUnmarshall [RPCRT4.@]
1142 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1143 unsigned char **ppMemory
,
1144 PFORMAT_STRING pFormat
,
1145 unsigned char fMustAlloc
)
1147 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1149 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1150 PointerUnmarshall(pStubMsg
, pStubMsg
->Buffer
, ppMemory
, pFormat
, fMustAlloc
);
1155 /***********************************************************************
1156 * NdrPointerBufferSize [RPCRT4.@]
1158 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1159 unsigned char *pMemory
,
1160 PFORMAT_STRING pFormat
)
1162 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1163 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1166 /***********************************************************************
1167 * NdrPointerMemorySize [RPCRT4.@]
1169 unsigned long WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1170 PFORMAT_STRING pFormat
)
1172 /* unsigned size = *(LPWORD)(pFormat+2); */
1173 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1174 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1178 /***********************************************************************
1179 * NdrPointerFree [RPCRT4.@]
1181 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1182 unsigned char *pMemory
,
1183 PFORMAT_STRING pFormat
)
1185 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1186 PointerFree(pStubMsg
, pMemory
, pFormat
);
1189 /***********************************************************************
1190 * NdrSimpleStructMarshall [RPCRT4.@]
1192 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1193 unsigned char *pMemory
,
1194 PFORMAT_STRING pFormat
)
1196 unsigned size
= *(const WORD
*)(pFormat
+2);
1197 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1199 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
1200 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1201 pStubMsg
->Buffer
+= size
;
1203 if (pFormat
[0] != RPC_FC_STRUCT
)
1204 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1207 * This test does not work when NdrSimpleStructMarshall is called
1208 * by an rpc-server to marshall data to return to the client because
1209 * BufferStart and BufferEnd are bogus. MIDL does not update them
1210 * when a new buffer is allocated in order to return data to the caller.
1213 STD_OVERFLOW_CHECK(pStubMsg
);
1219 /***********************************************************************
1220 * NdrSimpleStructUnmarshall [RPCRT4.@]
1222 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1223 unsigned char **ppMemory
,
1224 PFORMAT_STRING pFormat
,
1225 unsigned char fMustAlloc
)
1227 unsigned size
= *(const WORD
*)(pFormat
+2);
1228 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1231 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1232 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1234 if (pStubMsg
->ReuseBuffer
&& !*ppMemory
)
1235 /* for servers, we may just point straight into the RPC buffer, I think
1236 * (I guess that's what MS does since MIDL code doesn't try to free) */
1237 *ppMemory
= pStubMsg
->Buffer
;
1239 /* for clients, memory should be provided by caller */
1240 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1243 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1244 pStubMsg
->Buffer
+= size
;
1246 if (pFormat
[0] != RPC_FC_STRUCT
)
1247 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
+4, fMustAlloc
);
1253 /***********************************************************************
1254 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1256 void WINAPI
NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1257 unsigned char *pMemory
,
1258 unsigned char FormatChar
)
1264 /***********************************************************************
1265 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1267 void WINAPI
NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1268 unsigned char *pMemory
,
1269 unsigned char FormatChar
)
1275 /***********************************************************************
1276 * NdrSimpleStructBufferSize [RPCRT4.@]
1278 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1279 unsigned char *pMemory
,
1280 PFORMAT_STRING pFormat
)
1282 unsigned size
= *(const WORD
*)(pFormat
+2);
1283 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1284 pStubMsg
->BufferLength
+= size
;
1285 if (pFormat
[0] != RPC_FC_STRUCT
)
1286 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1289 /***********************************************************************
1290 * NdrSimpleStructMemorySize [RPCRT4.@]
1292 unsigned long WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1293 PFORMAT_STRING pFormat
)
1295 /* unsigned size = *(LPWORD)(pFormat+2); */
1296 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1297 if (pFormat
[0] != RPC_FC_STRUCT
)
1298 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1302 /***********************************************************************
1303 * NdrSimpleStructFree [RPCRT4.@]
1305 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1306 unsigned char *pMemory
,
1307 PFORMAT_STRING pFormat
)
1309 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1310 if (pFormat
[0] != RPC_FC_STRUCT
)
1311 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1315 unsigned long WINAPI
EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg
,
1316 PFORMAT_STRING pFormat
)
1320 case RPC_FC_PSTRUCT
:
1321 case RPC_FC_CSTRUCT
:
1322 case RPC_FC_BOGUS_STRUCT
:
1323 return *(const WORD
*)&pFormat
[2];
1324 case RPC_FC_USER_MARSHAL
:
1325 return *(const WORD
*)&pFormat
[4];
1327 FIXME("unhandled embedded type %02x\n", *pFormat
);
1333 unsigned char * WINAPI
ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1334 unsigned char *pMemory
,
1335 PFORMAT_STRING pFormat
,
1336 PFORMAT_STRING pPointer
)
1338 PFORMAT_STRING desc
;
1342 while (*pFormat
!= RPC_FC_END
) {
1346 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1347 memcpy(pStubMsg
->Buffer
, pMemory
, 2);
1348 pStubMsg
->Buffer
+= 2;
1353 TRACE("long=%ld <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1354 memcpy(pStubMsg
->Buffer
, pMemory
, 4);
1355 pStubMsg
->Buffer
+= 4;
1358 case RPC_FC_POINTER
:
1359 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1360 NdrPointerMarshall(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1364 case RPC_FC_ALIGNM4
:
1365 ALIGN_POINTER(pMemory
, 3);
1367 case RPC_FC_ALIGNM8
:
1368 ALIGN_POINTER(pMemory
, 7);
1370 case RPC_FC_EMBEDDED_COMPLEX
:
1371 pMemory
+= pFormat
[1];
1373 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1374 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1375 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1376 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1377 if (m
) m(pStubMsg
, pMemory
, desc
);
1378 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1385 FIXME("unhandled format %02x\n", *pFormat
);
1393 unsigned char * WINAPI
ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1394 unsigned char *pMemory
,
1395 PFORMAT_STRING pFormat
,
1396 PFORMAT_STRING pPointer
,
1397 unsigned char fMustAlloc
)
1399 PFORMAT_STRING desc
;
1403 while (*pFormat
!= RPC_FC_END
) {
1407 memcpy(pMemory
, pStubMsg
->Buffer
, 2);
1408 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1409 pStubMsg
->Buffer
+= 2;
1414 memcpy(pMemory
, pStubMsg
->Buffer
, 4);
1415 TRACE("long=%ld => %p\n", *(DWORD
*)pMemory
, pMemory
);
1416 pStubMsg
->Buffer
+= 4;
1419 case RPC_FC_POINTER
:
1420 *(unsigned char**)pMemory
= NULL
;
1421 TRACE("pointer => %p\n", pMemory
);
1422 NdrPointerUnmarshall(pStubMsg
, (unsigned char**)pMemory
, pPointer
, fMustAlloc
);
1426 case RPC_FC_ALIGNM4
:
1427 ALIGN_POINTER(pMemory
, 3);
1429 case RPC_FC_ALIGNM8
:
1430 ALIGN_POINTER(pMemory
, 7);
1432 case RPC_FC_EMBEDDED_COMPLEX
:
1433 pMemory
+= pFormat
[1];
1435 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1436 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1437 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
1438 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1439 memset(pMemory
, 0, size
); /* just in case */
1440 if (m
) m(pStubMsg
, &pMemory
, desc
, fMustAlloc
);
1441 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
1448 FIXME("unhandled format %d\n", *pFormat
);
1456 unsigned char * WINAPI
ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1457 unsigned char *pMemory
,
1458 PFORMAT_STRING pFormat
,
1459 PFORMAT_STRING pPointer
)
1461 PFORMAT_STRING desc
;
1465 while (*pFormat
!= RPC_FC_END
) {
1469 pStubMsg
->BufferLength
+= 2;
1474 pStubMsg
->BufferLength
+= 4;
1477 case RPC_FC_POINTER
:
1478 NdrPointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1482 case RPC_FC_ALIGNM4
:
1483 ALIGN_POINTER(pMemory
, 3);
1485 case RPC_FC_ALIGNM8
:
1486 ALIGN_POINTER(pMemory
, 7);
1488 case RPC_FC_EMBEDDED_COMPLEX
:
1489 pMemory
+= pFormat
[1];
1491 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1492 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1493 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1494 if (m
) m(pStubMsg
, pMemory
, desc
);
1495 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
1502 FIXME("unhandled format %d\n", *pFormat
);
1510 unsigned char * WINAPI
ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
1511 unsigned char *pMemory
,
1512 PFORMAT_STRING pFormat
,
1513 PFORMAT_STRING pPointer
)
1515 PFORMAT_STRING desc
;
1519 while (*pFormat
!= RPC_FC_END
) {
1529 case RPC_FC_POINTER
:
1530 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1534 case RPC_FC_ALIGNM4
:
1535 ALIGN_POINTER(pMemory
, 3);
1537 case RPC_FC_ALIGNM8
:
1538 ALIGN_POINTER(pMemory
, 7);
1540 case RPC_FC_EMBEDDED_COMPLEX
:
1541 pMemory
+= pFormat
[1];
1543 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1544 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1545 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1546 if (m
) m(pStubMsg
, pMemory
, desc
);
1547 else FIXME("no freer for embedded type %02x\n", *desc
);
1554 FIXME("unhandled format %d\n", *pFormat
);
1562 unsigned long WINAPI
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
,
1563 PFORMAT_STRING pFormat
)
1565 PFORMAT_STRING desc
;
1566 unsigned long size
= 0;
1568 while (*pFormat
!= RPC_FC_END
) {
1578 case RPC_FC_POINTER
:
1581 case RPC_FC_ALIGNM4
:
1582 ALIGN_LENGTH(size
, 3);
1584 case RPC_FC_ALIGNM8
:
1585 ALIGN_LENGTH(size
, 7);
1587 case RPC_FC_EMBEDDED_COMPLEX
:
1590 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1591 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
1597 FIXME("unhandled format %d\n", *pFormat
);
1605 /***********************************************************************
1606 * NdrComplexStructMarshall [RPCRT4.@]
1608 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1609 unsigned char *pMemory
,
1610 PFORMAT_STRING pFormat
)
1612 PFORMAT_STRING conf_array
= NULL
;
1613 PFORMAT_STRING pointer_desc
= NULL
;
1614 unsigned char *OldMemory
= pStubMsg
->Memory
;
1616 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1619 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
1621 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
1624 pStubMsg
->Memory
= pMemory
;
1626 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
1629 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
1631 pStubMsg
->Memory
= OldMemory
;
1633 STD_OVERFLOW_CHECK(pStubMsg
);
1638 /***********************************************************************
1639 * NdrComplexStructUnmarshall [RPCRT4.@]
1641 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1642 unsigned char **ppMemory
,
1643 PFORMAT_STRING pFormat
,
1644 unsigned char fMustAlloc
)
1646 unsigned size
= *(const WORD
*)(pFormat
+2);
1647 PFORMAT_STRING conf_array
= NULL
;
1648 PFORMAT_STRING pointer_desc
= NULL
;
1649 unsigned char *pMemory
;
1651 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1653 if (fMustAlloc
|| !*ppMemory
)
1654 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1657 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
1659 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
1662 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
1665 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
1670 /***********************************************************************
1671 * NdrComplexStructBufferSize [RPCRT4.@]
1673 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1674 unsigned char *pMemory
,
1675 PFORMAT_STRING pFormat
)
1677 PFORMAT_STRING conf_array
= NULL
;
1678 PFORMAT_STRING pointer_desc
= NULL
;
1679 unsigned char *OldMemory
= pStubMsg
->Memory
;
1681 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1684 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
1686 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
1689 pStubMsg
->Memory
= pMemory
;
1691 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
1694 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
1696 pStubMsg
->Memory
= OldMemory
;
1699 /***********************************************************************
1700 * NdrComplexStructMemorySize [RPCRT4.@]
1702 unsigned long WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1703 PFORMAT_STRING pFormat
)
1705 /* unsigned size = *(LPWORD)(pFormat+2); */
1706 PFORMAT_STRING conf_array
= NULL
;
1707 PFORMAT_STRING pointer_desc
= NULL
;
1709 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1712 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
1714 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
1720 /***********************************************************************
1721 * NdrComplexStructFree [RPCRT4.@]
1723 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1724 unsigned char *pMemory
,
1725 PFORMAT_STRING pFormat
)
1727 PFORMAT_STRING conf_array
= NULL
;
1728 PFORMAT_STRING pointer_desc
= NULL
;
1729 unsigned char *OldMemory
= pStubMsg
->Memory
;
1731 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1734 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
1736 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
1739 pStubMsg
->Memory
= pMemory
;
1741 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
1744 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
1746 pStubMsg
->Memory
= OldMemory
;
1749 /***********************************************************************
1750 * NdrConformantArrayMarshall [RPCRT4.@]
1752 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1753 unsigned char *pMemory
,
1754 PFORMAT_STRING pFormat
)
1756 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
1757 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1758 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1760 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1761 size
= pStubMsg
->MaxCount
;
1763 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, size
);
1764 pStubMsg
->Buffer
+= 4;
1766 memcpy(pStubMsg
->Buffer
, pMemory
, size
*esize
);
1767 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1768 pStubMsg
->Buffer
+= size
*esize
;
1770 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1772 STD_OVERFLOW_CHECK(pStubMsg
);
1777 /***********************************************************************
1778 * NdrConformantArrayUnmarshall [RPCRT4.@]
1780 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1781 unsigned char **ppMemory
,
1782 PFORMAT_STRING pFormat
,
1783 unsigned char fMustAlloc
)
1785 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
1786 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1787 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1789 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1790 size
= pStubMsg
->MaxCount
;
1793 *ppMemory
= NdrAllocate(pStubMsg
, size
*esize
);
1794 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
*esize
);
1796 if (pStubMsg
->ReuseBuffer
&& !*ppMemory
)
1797 /* for servers, we may just point straight into the RPC buffer, I think
1798 * (I guess that's what MS does since MIDL code doesn't try to free) */
1799 *ppMemory
= pStubMsg
->Buffer
;
1801 /* for clients, memory should be provided by caller */
1802 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
*esize
);
1805 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1806 pStubMsg
->Buffer
+= size
*esize
;
1808 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1813 /***********************************************************************
1814 * NdrConformantArrayBufferSize [RPCRT4.@]
1816 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1817 unsigned char *pMemory
,
1818 PFORMAT_STRING pFormat
)
1820 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
1821 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1822 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1824 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1825 size
= pStubMsg
->MaxCount
;
1827 pStubMsg
->BufferLength
+= size
*esize
;
1829 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1832 /***********************************************************************
1833 * NdrConformantArrayMemorySize [RPCRT4.@]
1835 unsigned long WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1836 PFORMAT_STRING pFormat
)
1839 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1840 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1842 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1843 size
= pStubMsg
->MaxCount
;
1845 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
1850 /***********************************************************************
1851 * NdrConformantArrayFree [RPCRT4.@]
1853 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
1854 unsigned char *pMemory
,
1855 PFORMAT_STRING pFormat
)
1857 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1858 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1860 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
1864 /***********************************************************************
1865 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
1867 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
1868 unsigned char* pMemory
,
1869 PFORMAT_STRING pFormat
)
1876 /***********************************************************************
1877 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
1879 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
1880 unsigned char** ppMemory
,
1881 PFORMAT_STRING pFormat
,
1882 unsigned char fMustAlloc
)
1889 /***********************************************************************
1890 * NdrConformantVaryingArrayFree [RPCRT4.@]
1892 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
1893 unsigned char* pMemory
,
1894 PFORMAT_STRING pFormat
)
1900 /***********************************************************************
1901 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
1903 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
1904 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
1910 /***********************************************************************
1911 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
1913 unsigned long WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
1914 PFORMAT_STRING pFormat
)
1921 /***********************************************************************
1922 * NdrComplexArrayMarshall [RPCRT4.@]
1924 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1925 unsigned char *pMemory
,
1926 PFORMAT_STRING pFormat
)
1928 DWORD size
= 0, count
, def
;
1929 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1931 def
= *(const WORD
*)&pFormat
[2];
1934 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1935 size
= pStubMsg
->MaxCount
;
1936 TRACE("conformance=%ld\n", size
);
1938 if (*(const DWORD
*)pFormat
!= 0xffffffff)
1939 FIXME("compute variance\n");
1942 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, size
);
1943 pStubMsg
->Buffer
+= 4;
1945 for (count
=0; count
<size
; count
++)
1946 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
1948 STD_OVERFLOW_CHECK(pStubMsg
);
1953 /***********************************************************************
1954 * NdrComplexArrayUnmarshall [RPCRT4.@]
1956 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1957 unsigned char **ppMemory
,
1958 PFORMAT_STRING pFormat
,
1959 unsigned char fMustAlloc
)
1961 DWORD size
= 0, count
, esize
;
1962 unsigned char *pMemory
;
1963 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1967 pFormat
= ReadConformance(pStubMsg
, pFormat
);
1968 size
= pStubMsg
->MaxCount
;
1969 TRACE("conformance=%ld\n", size
);
1973 esize
= ComplexStructSize(pStubMsg
, pFormat
);
1975 if (fMustAlloc
|| !*ppMemory
)
1976 *ppMemory
= NdrAllocate(pStubMsg
, size
*esize
);
1978 pMemory
= *ppMemory
;
1979 for (count
=0; count
<size
; count
++)
1980 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
1985 /***********************************************************************
1986 * NdrComplexArrayBufferSize [RPCRT4.@]
1988 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1989 unsigned char *pMemory
,
1990 PFORMAT_STRING pFormat
)
1992 DWORD size
= 0, count
, def
;
1993 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1995 def
= *(const WORD
*)&pFormat
[2];
1998 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1999 size
= pStubMsg
->MaxCount
;
2000 TRACE("conformance=%ld\n", size
);
2002 if (*(const DWORD
*)pFormat
!= 0xffffffff)
2003 FIXME("compute variance\n");
2006 for (count
=0; count
<size
; count
++)
2007 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
2010 /***********************************************************************
2011 * NdrComplexArrayMemorySize [RPCRT4.@]
2013 unsigned long WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2014 PFORMAT_STRING pFormat
)
2017 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
2021 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2022 size
= pStubMsg
->MaxCount
;
2023 TRACE("conformance=%ld\n", size
);
2030 /***********************************************************************
2031 * NdrComplexArrayFree [RPCRT4.@]
2033 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2034 unsigned char *pMemory
,
2035 PFORMAT_STRING pFormat
)
2037 DWORD size
= 0, count
, def
;
2038 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2040 def
= *(const WORD
*)&pFormat
[2];
2043 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2044 size
= pStubMsg
->MaxCount
;
2045 TRACE("conformance=%ld\n", size
);
2047 if (*(const DWORD
*)pFormat
!= 0xffffffff)
2048 FIXME("compute variance\n");
2051 for (count
=0; count
<size
; count
++)
2052 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2055 unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg
)
2057 return MAKELONG(pStubMsg
->dwDestContext
,
2058 pStubMsg
->RpcMsg
->DataRepresentation
);
2061 /***********************************************************************
2062 * NdrUserMarshalMarshall [RPCRT4.@]
2064 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2065 unsigned char *pMemory
,
2066 PFORMAT_STRING pFormat
)
2068 /* unsigned flags = pFormat[1]; */
2069 unsigned index
= *(const WORD
*)&pFormat
[2];
2070 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2071 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2072 TRACE("index=%d\n", index
);
2075 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
2076 &uflag
, pStubMsg
->Buffer
, pMemory
);
2078 STD_OVERFLOW_CHECK(pStubMsg
);
2083 /***********************************************************************
2084 * NdrUserMarshalUnmarshall [RPCRT4.@]
2086 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2087 unsigned char **ppMemory
,
2088 PFORMAT_STRING pFormat
,
2089 unsigned char fMustAlloc
)
2091 /* unsigned flags = pFormat[1];*/
2092 unsigned index
= *(const WORD
*)&pFormat
[2];
2093 DWORD memsize
= *(const WORD
*)&pFormat
[4];
2094 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2095 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2096 TRACE("index=%d\n", index
);
2098 if (fMustAlloc
|| !*ppMemory
)
2099 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2102 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
2103 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
2108 /***********************************************************************
2109 * NdrUserMarshalBufferSize [RPCRT4.@]
2111 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2112 unsigned char *pMemory
,
2113 PFORMAT_STRING pFormat
)
2115 /* unsigned flags = pFormat[1];*/
2116 unsigned index
= *(const WORD
*)&pFormat
[2];
2117 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
2118 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2119 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2120 TRACE("index=%d\n", index
);
2123 TRACE("size=%ld\n", bufsize
);
2124 pStubMsg
->BufferLength
+= bufsize
;
2128 pStubMsg
->BufferLength
=
2129 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
2130 &uflag
, pStubMsg
->BufferLength
, pMemory
);
2133 /***********************************************************************
2134 * NdrUserMarshalMemorySize [RPCRT4.@]
2136 unsigned long WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2137 PFORMAT_STRING pFormat
)
2139 unsigned index
= *(const WORD
*)&pFormat
[2];
2140 /* DWORD memsize = *(const WORD*)&pFormat[4]; */
2141 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
2142 TRACE("index=%d\n", index
);
2147 /***********************************************************************
2148 * NdrUserMarshalFree [RPCRT4.@]
2150 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
2151 unsigned char *pMemory
,
2152 PFORMAT_STRING pFormat
)
2154 /* unsigned flags = pFormat[1]; */
2155 unsigned index
= *(const WORD
*)&pFormat
[2];
2156 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2157 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2158 TRACE("index=%d\n", index
);
2160 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
2164 /***********************************************************************
2165 * NdrClearOutParameters [RPCRT4.@]
2167 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
2168 PFORMAT_STRING pFormat
,
2171 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
2174 /***********************************************************************
2175 * NdrConvert [RPCRT4.@]
2177 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2179 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
2180 /* FIXME: since this stub doesn't do any converting, the proper behavior
2181 is to raise an exception */
2184 /***********************************************************************
2185 * NdrConvert2 [RPCRT4.@]
2187 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, long NumberParams
)
2189 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2190 pStubMsg
, pFormat
, NumberParams
);
2191 /* FIXME: since this stub doesn't do any converting, the proper behavior
2192 is to raise an exception */