4 * Copyright 2002 Greg Turner
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * - figure out whether we *really* got this right
22 * - check for errors and throw exceptions
38 #include "wine/unicode.h"
39 #include "wine/rpcfc.h"
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
45 #define BUFFER_PARANOIA 20
48 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
49 (*((UINT32 *)(pchar)) = (uint32))
51 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
52 (*((UINT32 *)(pchar)))
54 /* these would work for i386 too, but less efficient */
55 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
56 (*(pchar) = LOBYTE(LOWORD(uint32)), \
57 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
58 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
59 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
60 (uint32)) /* allow as r-value */
62 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
64 MAKEWORD(*(pchar), *((pchar)+1)), \
65 MAKEWORD(*((pchar)+2), *((pchar)+3))))
68 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
69 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
70 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
71 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
72 *(pchar) = HIBYTE(HIWORD(uint32)), \
73 (uint32)) /* allow as r-value */
75 #define BIG_ENDIAN_UINT32_READ(pchar) \
77 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
78 MAKEWORD(*((pchar)+1), *(pchar))))
80 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
81 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
82 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
83 # define NDR_LOCAL_UINT32_READ(pchar) \
84 BIG_ENDIAN_UINT32_READ(pchar)
86 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
87 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
88 # define NDR_LOCAL_UINT32_READ(pchar) \
89 LITTLE_ENDIAN_UINT32_READ(pchar)
92 /* _Align must be the desired alignment minus 1,
93 * e.g. ALIGN_LENGTH(len, 3) to align on a dword boundary. */
94 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
95 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
96 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
97 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
99 #define STD_OVERFLOW_CHECK(_Msg) do { \
100 TRACE("buffer=%d/%ld\n", _Msg->Buffer - _Msg->BufferStart, _Msg->BufferLength); \
101 if (_Msg->Buffer > _Msg->BufferEnd) ERR("buffer overflow %d bytes\n", _Msg->Buffer - _Msg->BufferEnd); \
104 #define NDR_TABLE_SIZE 128
105 #define NDR_TABLE_MASK 127
107 NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
108 0, 0, 0, 0, 0, 0, 0, 0,
109 0, 0, 0, 0, 0, 0, 0, 0,
113 NdrPointerMarshall
, NdrPointerMarshall
,
114 NdrPointerMarshall
, NdrPointerMarshall
,
116 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
118 NdrComplexStructMarshall
,
120 NdrConformantArrayMarshall
, 0, 0, 0, 0, 0,
121 NdrComplexArrayMarshall
,
123 NdrConformantStringMarshall
, 0, 0,
124 NdrConformantStringMarshall
, 0, 0, 0, 0,
128 NdrInterfacePointerMarshall
,
131 NdrUserMarshalMarshall
133 NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
134 0, 0, 0, 0, 0, 0, 0, 0,
135 0, 0, 0, 0, 0, 0, 0, 0,
139 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
140 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
142 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
144 NdrComplexStructUnmarshall
,
146 NdrConformantArrayUnmarshall
, 0, 0, 0, 0, 0,
147 NdrComplexArrayUnmarshall
,
149 NdrConformantStringUnmarshall
, 0, 0,
150 NdrConformantStringUnmarshall
, 0, 0, 0, 0,
154 NdrInterfacePointerUnmarshall
,
157 NdrUserMarshalUnmarshall
159 NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
160 0, 0, 0, 0, 0, 0, 0, 0,
161 0, 0, 0, 0, 0, 0, 0, 0,
165 NdrPointerBufferSize
, NdrPointerBufferSize
,
166 NdrPointerBufferSize
, NdrPointerBufferSize
,
168 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
170 NdrComplexStructBufferSize
,
172 NdrConformantArrayBufferSize
, 0, 0, 0, 0, 0,
173 NdrComplexArrayBufferSize
,
175 NdrConformantStringBufferSize
, 0, 0,
176 NdrConformantStringBufferSize
, 0, 0, 0, 0,
180 NdrInterfacePointerBufferSize
,
183 NdrUserMarshalBufferSize
185 NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
186 0, 0, 0, 0, 0, 0, 0, 0,
187 0, 0, 0, 0, 0, 0, 0, 0,
191 NdrPointerMemorySize
, NdrPointerMemorySize
,
192 NdrPointerMemorySize
, NdrPointerMemorySize
,
194 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
196 NdrComplexStructMemorySize
,
198 NdrConformantArrayMemorySize
, 0, 0, 0, 0, 0,
199 NdrComplexArrayMemorySize
,
201 NdrConformantStringMemorySize
, 0, 0,
202 NdrConformantStringMemorySize
, 0, 0, 0, 0,
206 NdrInterfacePointerMemorySize
,
209 NdrUserMarshalMemorySize
211 NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
212 0, 0, 0, 0, 0, 0, 0, 0,
213 0, 0, 0, 0, 0, 0, 0, 0,
217 NdrPointerFree
, NdrPointerFree
,
218 NdrPointerFree
, NdrPointerFree
,
220 NdrSimpleStructFree
, NdrSimpleStructFree
,
222 NdrComplexStructFree
,
224 NdrConformantArrayFree
, 0, 0, 0, 0, 0,
227 0, 0, 0, 0, 0, 0, 0, 0,
231 NdrInterfacePointerFree
,
237 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
239 /* hmm, this is probably supposed to do more? */
240 return pStubMsg
->pfnAllocate(len
);
243 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
245 pStubMsg
->pfnFree(Pointer
);
248 PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
250 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
251 pStubMsg
->Buffer
+= 4;
252 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
256 PFORMAT_STRING
ComputeConformance(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
257 PFORMAT_STRING pFormat
, ULONG_PTR def
)
259 BYTE dtype
= pFormat
[0] & 0xf;
260 DWORD ofs
= (DWORD
)pFormat
[2] | ((DWORD
)pFormat
[3] << 8);
264 if (pFormat
[0] == 0xff) {
265 /* null descriptor */
266 pStubMsg
->MaxCount
= def
;
270 switch (pFormat
[0] & 0xf0) {
271 case RPC_FC_NORMAL_CONFORMANCE
:
272 TRACE("normal conformance, ofs=%ld\n", ofs
);
275 case RPC_FC_POINTER_CONFORMANCE
:
276 TRACE("pointer conformance, ofs=%ld\n", ofs
);
277 ptr
= pStubMsg
->Memory
+ ofs
;
279 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
280 TRACE("toplevel conformance, ofs=%ld\n", ofs
);
281 if (pStubMsg
->StackTop
) {
282 ptr
= pStubMsg
->StackTop
+ ofs
;
285 /* -Os mode, MaxCount is already set */
289 case RPC_FC_CONSTANT_CONFORMANCE
:
290 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
291 TRACE("constant conformance, val=%ld\n", data
);
292 pStubMsg
->MaxCount
= data
;
294 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
295 FIXME("toplevel multidimensional conformance, ofs=%ld\n", ofs
);
296 if (pStubMsg
->StackTop
) {
297 ptr
= pStubMsg
->StackTop
+ ofs
;
305 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
308 switch (pFormat
[1]) {
309 case RPC_FC_DEREFERENCE
:
312 case RPC_FC_CALLBACK
:
313 /* ofs is index into StubDesc->apfnExprEval */
314 FIXME("handle callback\n");
329 data
= *(USHORT
*)ptr
;
338 FIXME("unknown conformance data type %x\n", dtype
);
341 TRACE("dereferenced data type %x at %p, got %ld\n", dtype
, ptr
, data
);
344 switch (pFormat
[1]) {
346 pStubMsg
->MaxCount
= data
;
348 case RPC_FC_DEREFERENCE
:
349 /* already handled */
352 FIXME("unknown conformance op %d\n", pFormat
[1]);
357 TRACE("resulting conformance is %ld\n", pStubMsg
->MaxCount
);
363 * NdrConformantString:
365 * What MS calls a ConformantString is, in DCE terminology,
366 * a Varying-Conformant String.
368 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
369 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
370 * into unmarshalled string)
371 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
373 * data: CHARTYPE[maxlen]
375 * ], where CHARTYPE is the appropriate character type (specified externally)
379 /***********************************************************************
380 * NdrConformantStringMarshall [RPCRT4.@]
382 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
383 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
385 unsigned long len
, esize
;
388 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
391 if (*pFormat
== RPC_FC_C_CSTRING
) {
392 TRACE("string=%s\n", debugstr_a(pszMessage
));
393 len
= strlen(pszMessage
)+1;
396 else if (*pFormat
== RPC_FC_C_WSTRING
) {
397 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
398 len
= strlenW((LPWSTR
)pszMessage
)+1;
402 ERR("Unhandled string type: %#x\n", *pFormat
);
403 /* FIXME: raise an exception. */
407 if (pFormat
[1] != RPC_FC_PAD
) {
408 FIXME("sized string format=%d\n", pFormat
[1]);
411 assert( (pStubMsg
->BufferLength
>= (len
*esize
+ 13)) && (pStubMsg
->Buffer
!= NULL
) );
413 c
= pStubMsg
->Buffer
;
415 NDR_LOCAL_UINT32_WRITE(c
, len
); /* max length: strlen + 1 (for '\0') */
416 c
+= 8; /* offset: 0 */
417 NDR_LOCAL_UINT32_WRITE(c
, len
); /* actual length: (same) */
419 memcpy(c
, pszMessage
, len
*esize
); /* the string itself */
421 pStubMsg
->Buffer
= c
;
423 STD_OVERFLOW_CHECK(pStubMsg
);
426 return NULL
; /* is this always right? */
429 /***********************************************************************
430 * NdrConformantStringBufferSize [RPCRT4.@]
432 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
433 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
435 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
438 if (*pFormat
== RPC_FC_C_CSTRING
) {
439 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 1 octet for '\0' */
440 TRACE("string=%s\n", debugstr_a(pMemory
));
441 pStubMsg
->BufferLength
+= strlen(pMemory
) + 13 + BUFFER_PARANOIA
;
443 else if (*pFormat
== RPC_FC_C_WSTRING
) {
444 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 2 octets for L'\0' */
445 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
446 pStubMsg
->BufferLength
+= strlenW((LPWSTR
)pMemory
)*2 + 14 + BUFFER_PARANOIA
;
449 ERR("Unhandled string type: %#x\n", *pFormat
);
450 /* FIXME: raise an exception */
453 if (pFormat
[1] != RPC_FC_PAD
) {
454 FIXME("sized string format=%d\n", pFormat
[1]);
458 /************************************************************************
459 * NdrConformantStringMemorySize [RPCRT4.@]
461 unsigned long WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
462 PFORMAT_STRING pFormat
)
464 unsigned long rslt
= 0;
466 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
468 assert(pStubMsg
&& pFormat
);
470 if (*pFormat
== RPC_FC_C_CSTRING
) {
471 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
); /* maxlen */
473 else if (*pFormat
== RPC_FC_C_WSTRING
) {
474 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
)*2; /* maxlen */
477 ERR("Unhandled string type: %#x\n", *pFormat
);
478 /* FIXME: raise an exception */
481 if (pFormat
[1] != RPC_FC_PAD
) {
482 FIXME("sized string format=%d\n", pFormat
[1]);
485 TRACE(" --> %lu\n", rslt
);
489 /************************************************************************
490 * NdrConformantStringUnmarshall [RPCRT4.@]
492 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
493 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
495 unsigned long len
, esize
, ofs
;
498 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
499 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
501 assert(pFormat
&& ppMemory
&& pStubMsg
);
503 pStubMsg
->Buffer
+= 4;
504 ofs
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
505 pStubMsg
->Buffer
+= 4;
506 len
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
507 pStubMsg
->Buffer
+= 4;
509 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
510 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
512 ERR("Unhandled string type: %#x\n", *pFormat
);
513 /* FIXME: raise an exception */
517 if (pFormat
[1] != RPC_FC_PAD
) {
518 FIXME("sized string format=%d\n", pFormat
[1]);
522 *ppMemory
= NdrAllocate(pStubMsg
, len
*esize
+ BUFFER_PARANOIA
);
524 if (pStubMsg
->ReuseBuffer
&& !*ppMemory
)
525 /* for servers, we may just point straight into the RPC buffer, I think
526 * (I guess that's what MS does since MIDL code doesn't try to free) */
527 *ppMemory
= pStubMsg
->Buffer
- ofs
*esize
;
528 /* for clients, memory should be provided by caller */
531 pMem
= *ppMemory
+ ofs
*esize
;
533 if (pMem
!= pStubMsg
->Buffer
)
534 memcpy(pMem
, pStubMsg
->Buffer
, len
*esize
);
536 pStubMsg
->Buffer
+= len
*esize
;
538 if (*pFormat
== RPC_FC_C_CSTRING
) {
539 TRACE("string=%s\n", debugstr_a(pMem
));
541 else if (*pFormat
== RPC_FC_C_WSTRING
) {
542 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMem
));
545 return NULL
; /* FIXME: is this always right? */
548 static inline void dump_pointer_attr(unsigned char attr
)
550 if (attr
& RPC_FC_P_ALLOCALLNODES
)
551 TRACE(" RPC_FC_P_ALLOCALLNODES");
552 if (attr
& RPC_FC_P_DONTFREE
)
553 TRACE(" RPC_FC_P_DONTFREE");
554 if (attr
& RPC_FC_P_ONSTACK
)
555 TRACE(" RPC_FC_P_ONSTACK");
556 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
557 TRACE(" RPC_FC_P_SIMPLEPOINTER");
558 if (attr
& RPC_FC_P_DEREF
)
559 TRACE(" RPC_FC_P_DEREF");
563 /***********************************************************************
566 void WINAPI
PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
567 unsigned char *Buffer
,
568 unsigned char *Pointer
,
569 PFORMAT_STRING pFormat
)
571 unsigned type
= pFormat
[0], attr
= pFormat
[1];
575 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
576 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
578 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
579 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
580 if (attr
& RPC_FC_P_DEREF
) {
581 Pointer
= *(unsigned char**)Pointer
;
582 TRACE("deref => %p\n", Pointer
);
586 case RPC_FC_RP
: /* ref pointer (always non-null) */
587 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
589 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
592 case RPC_FC_UP
: /* unique pointer */
593 case RPC_FC_OP
: /* object pointer - same as unique here */
594 TRACE("writing %p to buffer\n", Pointer
);
595 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, (unsigned long)Pointer
);
596 pStubMsg
->Buffer
+= 4;
600 FIXME("unhandled ptr type=%02x\n", type
);
601 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
604 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
607 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
608 if (m
) m(pStubMsg
, Pointer
, desc
);
609 else FIXME("no marshaller for data type=%02x\n", *desc
);
612 STD_OVERFLOW_CHECK(pStubMsg
);
615 /***********************************************************************
618 void WINAPI
PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
619 unsigned char *Buffer
,
620 unsigned char **pPointer
,
621 PFORMAT_STRING pFormat
,
622 unsigned char fMustAlloc
)
624 unsigned type
= pFormat
[0], attr
= pFormat
[1];
627 DWORD pointer_id
= 0;
629 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pFormat
, fMustAlloc
);
630 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
632 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
633 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
634 if (attr
& RPC_FC_P_DEREF
) {
635 pPointer
= *(unsigned char***)pPointer
;
636 TRACE("deref => %p\n", pPointer
);
640 case RPC_FC_RP
: /* ref pointer (always non-null) */
643 case RPC_FC_UP
: /* unique pointer */
644 pointer_id
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
645 pStubMsg
->Buffer
+= 4;
647 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
650 FIXME("unhandled ptr type=%02x\n", type
);
651 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
657 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
658 if (m
) m(pStubMsg
, pPointer
, desc
, fMustAlloc
);
659 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
662 TRACE("pointer=%p\n", *pPointer
);
665 /***********************************************************************
668 void WINAPI
PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
669 unsigned char *Pointer
,
670 PFORMAT_STRING pFormat
)
672 unsigned type
= pFormat
[0], attr
= pFormat
[1];
676 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
677 TRACE("type=%d, attr=%d\n", type
, attr
);
679 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
680 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
681 if (attr
& RPC_FC_P_DEREF
) {
682 Pointer
= *(unsigned char**)Pointer
;
683 TRACE("deref => %p\n", Pointer
);
687 case RPC_FC_RP
: /* ref pointer (always non-null) */
691 pStubMsg
->BufferLength
+= 4;
692 /* NULL pointer has no further representation */
698 FIXME("unhandled ptr type=%02x\n", type
);
699 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
702 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
703 if (m
) m(pStubMsg
, Pointer
, desc
);
704 else FIXME("no buffersizer for data type=%02x\n", *desc
);
707 /***********************************************************************
708 * PointerMemorySize [RPCRT4.@]
710 unsigned long WINAPI
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
711 unsigned char *Buffer
,
712 PFORMAT_STRING pFormat
)
714 unsigned type
= pFormat
[0], attr
= pFormat
[1];
718 FIXME("(%p,%p,%p): stub\n", pStubMsg
, Buffer
, pFormat
);
719 TRACE("type=%d, attr=", type
); dump_pointer_attr(attr
);
721 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
722 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
723 if (attr
& RPC_FC_P_DEREF
) {
728 case RPC_FC_RP
: /* ref pointer (always non-null) */
731 FIXME("unhandled ptr type=%02x\n", type
);
732 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
735 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
736 if (m
) m(pStubMsg
, desc
);
737 else FIXME("no memorysizer for data type=%02x\n", *desc
);
742 /***********************************************************************
743 * PointerFree [RPCRT4.@]
745 void WINAPI
PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
746 unsigned char *Pointer
,
747 PFORMAT_STRING pFormat
)
749 unsigned type
= pFormat
[0], attr
= pFormat
[1];
753 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
754 TRACE("type=%d, attr=", type
); dump_pointer_attr(attr
);
755 if (attr
& RPC_FC_P_DONTFREE
) return;
757 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
758 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
759 if (attr
& RPC_FC_P_DEREF
) {
760 Pointer
= *(unsigned char**)Pointer
;
761 TRACE("deref => %p\n", Pointer
);
764 if (!Pointer
) return;
766 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
767 if (m
) m(pStubMsg
, Pointer
, desc
);
769 /* hmm... is this sensible?
770 * perhaps we should check if the memory comes from NdrAllocate,
771 * and deallocate only if so - checking if the pointer is between
772 * BufferStart and BufferEnd is probably no good since the buffer
773 * may be reallocated when the server wants to marshal the reply */
775 case RPC_FC_BOGUS_STRUCT
:
776 case RPC_FC_BOGUS_ARRAY
:
777 case RPC_FC_USER_MARSHAL
:
780 FIXME("unhandled data type=%02x\n", *desc
);
782 case RPC_FC_C_CSTRING
:
783 case RPC_FC_C_WSTRING
:
784 if (pStubMsg
->ReuseBuffer
) goto notfree
;
790 if (attr
& RPC_FC_P_ONSTACK
) {
791 TRACE("not freeing stack ptr %p\n", Pointer
);
794 TRACE("freeing %p\n", Pointer
);
795 NdrFree(pStubMsg
, Pointer
);
798 TRACE("not freeing %p\n", Pointer
);
801 /***********************************************************************
802 * EmbeddedPointerMarshall
804 unsigned char * WINAPI
EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
805 unsigned char *pMemory
,
806 PFORMAT_STRING pFormat
)
808 unsigned char *Mark
= pStubMsg
->BufferMark
;
809 unsigned long Offset
= pStubMsg
->Offset
;
810 unsigned ofs
, rep
, count
, stride
, xofs
;
812 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
814 if (*pFormat
!= RPC_FC_PP
) return NULL
;
817 while (pFormat
[0] != RPC_FC_END
) {
818 switch (pFormat
[0]) {
820 FIXME("unknown repeat type %d\n", pFormat
[0]);
821 case RPC_FC_NO_REPEAT
:
829 case RPC_FC_FIXED_REPEAT
:
830 rep
= *(const WORD
*)&pFormat
[2];
831 stride
= *(const WORD
*)&pFormat
[4];
832 ofs
= *(const WORD
*)&pFormat
[6];
833 count
= *(const WORD
*)&pFormat
[8];
837 case RPC_FC_VARIABLE_REPEAT
:
838 rep
= pStubMsg
->MaxCount
;
839 stride
= *(const WORD
*)&pFormat
[2];
840 ofs
= *(const WORD
*)&pFormat
[4];
841 count
= *(const WORD
*)&pFormat
[6];
842 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
846 /* ofs doesn't seem to matter in this context */
848 PFORMAT_STRING info
= pFormat
;
849 unsigned char *membase
= pMemory
+ xofs
;
851 for (u
=0; u
<count
; u
++,info
+=8) {
852 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
853 unsigned char *bufptr
= Mark
+ *(const SHORT
*)&info
[2];
854 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
858 pFormat
+= 8 * count
;
861 STD_OVERFLOW_CHECK(pStubMsg
);
866 /***********************************************************************
867 * EmbeddedPointerUnmarshall
869 unsigned char * WINAPI
EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
870 unsigned char **ppMemory
,
871 PFORMAT_STRING pFormat
,
872 unsigned char fMustAlloc
)
874 unsigned char *Mark
= pStubMsg
->BufferMark
;
875 unsigned long Offset
= pStubMsg
->Offset
;
876 unsigned ofs
, rep
, count
, stride
, xofs
;
878 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
880 if (*pFormat
!= RPC_FC_PP
) return NULL
;
883 while (pFormat
[0] != RPC_FC_END
) {
884 switch (pFormat
[0]) {
886 FIXME("unknown repeat type %d\n", pFormat
[0]);
887 case RPC_FC_NO_REPEAT
:
895 case RPC_FC_FIXED_REPEAT
:
896 rep
= *(const WORD
*)&pFormat
[2];
897 stride
= *(const WORD
*)&pFormat
[4];
898 ofs
= *(const WORD
*)&pFormat
[6];
899 count
= *(const WORD
*)&pFormat
[8];
903 case RPC_FC_VARIABLE_REPEAT
:
904 rep
= pStubMsg
->MaxCount
;
905 stride
= *(const WORD
*)&pFormat
[2];
906 ofs
= *(const WORD
*)&pFormat
[4];
907 count
= *(const WORD
*)&pFormat
[6];
908 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
912 /* ofs doesn't seem to matter in this context */
914 PFORMAT_STRING info
= pFormat
;
915 unsigned char *membase
= *ppMemory
+ xofs
;
917 for (u
=0; u
<count
; u
++,info
+=8) {
918 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
919 unsigned char *bufptr
= Mark
+ *(const SHORT
*)&info
[2];
920 PointerUnmarshall(pStubMsg
, bufptr
, (unsigned char**)memptr
, info
+4, fMustAlloc
);
924 pFormat
+= 8 * count
;
930 /***********************************************************************
931 * EmbeddedPointerBufferSize
933 void WINAPI
EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
934 unsigned char *pMemory
,
935 PFORMAT_STRING pFormat
)
937 unsigned long Offset
= pStubMsg
->Offset
;
938 unsigned ofs
, rep
, count
, stride
, xofs
;
940 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
941 if (*pFormat
!= RPC_FC_PP
) return;
944 while (pFormat
[0] != RPC_FC_END
) {
945 switch (pFormat
[0]) {
947 FIXME("unknown repeat type %d\n", pFormat
[0]);
948 case RPC_FC_NO_REPEAT
:
956 case RPC_FC_FIXED_REPEAT
:
957 rep
= *(const WORD
*)&pFormat
[2];
958 stride
= *(const WORD
*)&pFormat
[4];
959 ofs
= *(const WORD
*)&pFormat
[6];
960 count
= *(const WORD
*)&pFormat
[8];
964 case RPC_FC_VARIABLE_REPEAT
:
965 rep
= pStubMsg
->MaxCount
;
966 stride
= *(const WORD
*)&pFormat
[2];
967 ofs
= *(const WORD
*)&pFormat
[4];
968 count
= *(const WORD
*)&pFormat
[6];
969 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
973 /* ofs doesn't seem to matter in this context */
975 PFORMAT_STRING info
= pFormat
;
976 unsigned char *membase
= pMemory
+ xofs
;
978 for (u
=0; u
<count
; u
++,info
+=8) {
979 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
980 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
984 pFormat
+= 8 * count
;
988 /***********************************************************************
989 * EmbeddedPointerMemorySize
991 unsigned long WINAPI
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
992 PFORMAT_STRING pFormat
)
994 unsigned long Offset
= pStubMsg
->Offset
;
995 unsigned char *Mark
= pStubMsg
->BufferMark
;
996 unsigned ofs
, rep
, count
, stride
, xofs
;
998 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
999 if (*pFormat
!= RPC_FC_PP
) return 0;
1002 while (pFormat
[0] != RPC_FC_END
) {
1003 switch (pFormat
[0]) {
1005 FIXME("unknown repeat type %d\n", pFormat
[0]);
1006 case RPC_FC_NO_REPEAT
:
1014 case RPC_FC_FIXED_REPEAT
:
1015 rep
= *(const WORD
*)&pFormat
[2];
1016 stride
= *(const WORD
*)&pFormat
[4];
1017 ofs
= *(const WORD
*)&pFormat
[6];
1018 count
= *(const WORD
*)&pFormat
[8];
1022 case RPC_FC_VARIABLE_REPEAT
:
1023 rep
= pStubMsg
->MaxCount
;
1024 stride
= *(const WORD
*)&pFormat
[2];
1025 ofs
= *(const WORD
*)&pFormat
[4];
1026 count
= *(const WORD
*)&pFormat
[6];
1027 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1031 /* ofs doesn't seem to matter in this context */
1033 PFORMAT_STRING info
= pFormat
;
1035 for (u
=0; u
<count
; u
++,info
+=8) {
1036 unsigned char *bufptr
= Mark
+ *(const SHORT
*)&info
[2];
1037 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1041 pFormat
+= 8 * count
;
1047 /***********************************************************************
1048 * EmbeddedPointerFree
1050 void WINAPI
EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1051 unsigned char *pMemory
,
1052 PFORMAT_STRING pFormat
)
1054 unsigned long Offset
= pStubMsg
->Offset
;
1055 unsigned ofs
, rep
, count
, stride
, xofs
;
1057 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1058 if (*pFormat
!= RPC_FC_PP
) return;
1061 while (pFormat
[0] != RPC_FC_END
) {
1062 switch (pFormat
[0]) {
1064 FIXME("unknown repeat type %d\n", pFormat
[0]);
1065 case RPC_FC_NO_REPEAT
:
1073 case RPC_FC_FIXED_REPEAT
:
1074 rep
= *(const WORD
*)&pFormat
[2];
1075 stride
= *(const WORD
*)&pFormat
[4];
1076 ofs
= *(const WORD
*)&pFormat
[6];
1077 count
= *(const WORD
*)&pFormat
[8];
1081 case RPC_FC_VARIABLE_REPEAT
:
1082 rep
= pStubMsg
->MaxCount
;
1083 stride
= *(const WORD
*)&pFormat
[2];
1084 ofs
= *(const WORD
*)&pFormat
[4];
1085 count
= *(const WORD
*)&pFormat
[6];
1086 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1090 /* ofs doesn't seem to matter in this context */
1092 PFORMAT_STRING info
= pFormat
;
1093 unsigned char *membase
= pMemory
+ xofs
;
1095 for (u
=0; u
<count
; u
++,info
+=8) {
1096 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1097 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1101 pFormat
+= 8 * count
;
1105 /***********************************************************************
1106 * NdrPointerMarshall [RPCRT4.@]
1108 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1109 unsigned char *pMemory
,
1110 PFORMAT_STRING pFormat
)
1112 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1114 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1115 PointerMarshall(pStubMsg
, pStubMsg
->Buffer
, pMemory
, pFormat
);
1117 STD_OVERFLOW_CHECK(pStubMsg
);
1122 /***********************************************************************
1123 * NdrPointerUnmarshall [RPCRT4.@]
1125 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1126 unsigned char **ppMemory
,
1127 PFORMAT_STRING pFormat
,
1128 unsigned char fMustAlloc
)
1130 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1132 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1133 PointerUnmarshall(pStubMsg
, pStubMsg
->Buffer
, ppMemory
, pFormat
, fMustAlloc
);
1138 /***********************************************************************
1139 * NdrPointerBufferSize [RPCRT4.@]
1141 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1142 unsigned char *pMemory
,
1143 PFORMAT_STRING pFormat
)
1145 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1146 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1149 /***********************************************************************
1150 * NdrPointerMemorySize [RPCRT4.@]
1152 unsigned long WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1153 PFORMAT_STRING pFormat
)
1155 /* unsigned size = *(LPWORD)(pFormat+2); */
1156 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1157 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1161 /***********************************************************************
1162 * NdrPointerFree [RPCRT4.@]
1164 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1165 unsigned char *pMemory
,
1166 PFORMAT_STRING pFormat
)
1168 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1169 PointerFree(pStubMsg
, pMemory
, pFormat
);
1172 /***********************************************************************
1173 * NdrSimpleStructMarshall [RPCRT4.@]
1175 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1176 unsigned char *pMemory
,
1177 PFORMAT_STRING pFormat
)
1179 unsigned size
= *(const WORD
*)(pFormat
+2);
1180 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1182 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
1183 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1184 pStubMsg
->Buffer
+= size
;
1186 if (pFormat
[0] != RPC_FC_STRUCT
)
1187 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1189 STD_OVERFLOW_CHECK(pStubMsg
);
1194 /***********************************************************************
1195 * NdrSimpleStructUnmarshall [RPCRT4.@]
1197 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1198 unsigned char **ppMemory
,
1199 PFORMAT_STRING pFormat
,
1200 unsigned char fMustAlloc
)
1202 unsigned size
= *(const WORD
*)(pFormat
+2);
1203 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1206 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1207 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1209 if (pStubMsg
->ReuseBuffer
&& !*ppMemory
)
1210 /* for servers, we may just point straight into the RPC buffer, I think
1211 * (I guess that's what MS does since MIDL code doesn't try to free) */
1212 *ppMemory
= pStubMsg
->Buffer
;
1214 /* for clients, memory should be provided by caller */
1215 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1218 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1219 pStubMsg
->Buffer
+= size
;
1221 if (pFormat
[0] != RPC_FC_STRUCT
)
1222 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
+4, fMustAlloc
);
1228 /***********************************************************************
1229 * NdrSimpleStructUnmarshall [RPCRT4.@]
1231 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1232 unsigned char FormatChar
)
1238 /***********************************************************************
1239 * NdrSimpleStructUnmarshall [RPCRT4.@]
1241 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1242 unsigned char FormatChar
)
1248 /***********************************************************************
1249 * NdrSimpleStructBufferSize [RPCRT4.@]
1251 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1252 unsigned char *pMemory
,
1253 PFORMAT_STRING pFormat
)
1255 unsigned size
= *(const WORD
*)(pFormat
+2);
1256 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1257 pStubMsg
->BufferLength
+= size
;
1258 if (pFormat
[0] != RPC_FC_STRUCT
)
1259 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1262 /***********************************************************************
1263 * NdrSimpleStructMemorySize [RPCRT4.@]
1265 unsigned long WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1266 PFORMAT_STRING pFormat
)
1268 /* unsigned size = *(LPWORD)(pFormat+2); */
1269 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1270 if (pFormat
[0] != RPC_FC_STRUCT
)
1271 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1275 /***********************************************************************
1276 * NdrSimpleStructFree [RPCRT4.@]
1278 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1279 unsigned char *pMemory
,
1280 PFORMAT_STRING pFormat
)
1282 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1283 if (pFormat
[0] != RPC_FC_STRUCT
)
1284 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1288 unsigned long WINAPI
EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg
,
1289 PFORMAT_STRING pFormat
)
1293 case RPC_FC_PSTRUCT
:
1294 case RPC_FC_CSTRUCT
:
1295 case RPC_FC_BOGUS_STRUCT
:
1296 return *(const WORD
*)&pFormat
[2];
1297 case RPC_FC_USER_MARSHAL
:
1298 return *(const WORD
*)&pFormat
[4];
1300 FIXME("unhandled embedded type %02x\n", *pFormat
);
1306 unsigned char * WINAPI
ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1307 unsigned char *pMemory
,
1308 PFORMAT_STRING pFormat
,
1309 PFORMAT_STRING pPointer
)
1311 PFORMAT_STRING desc
;
1315 while (*pFormat
!= RPC_FC_END
) {
1319 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1320 memcpy(pStubMsg
->Buffer
, pMemory
, 2);
1321 pStubMsg
->Buffer
+= 2;
1326 TRACE("long=%ld <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1327 memcpy(pStubMsg
->Buffer
, pMemory
, 4);
1328 pStubMsg
->Buffer
+= 4;
1331 case RPC_FC_POINTER
:
1332 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1333 NdrPointerMarshall(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1337 case RPC_FC_ALIGNM4
:
1338 ALIGN_POINTER(pMemory
, 3);
1340 case RPC_FC_ALIGNM8
:
1341 ALIGN_POINTER(pMemory
, 7);
1343 case RPC_FC_EMBEDDED_COMPLEX
:
1344 pMemory
+= pFormat
[1];
1346 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1347 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1348 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1349 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1350 if (m
) m(pStubMsg
, pMemory
, desc
);
1351 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1358 FIXME("unhandled format %02x\n", *pFormat
);
1366 unsigned char * WINAPI
ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1367 unsigned char *pMemory
,
1368 PFORMAT_STRING pFormat
,
1369 PFORMAT_STRING pPointer
,
1370 unsigned char fMustAlloc
)
1372 PFORMAT_STRING desc
;
1376 while (*pFormat
!= RPC_FC_END
) {
1380 memcpy(pMemory
, pStubMsg
->Buffer
, 2);
1381 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1382 pStubMsg
->Buffer
+= 2;
1387 memcpy(pMemory
, pStubMsg
->Buffer
, 4);
1388 TRACE("long=%ld => %p\n", *(DWORD
*)pMemory
, pMemory
);
1389 pStubMsg
->Buffer
+= 4;
1392 case RPC_FC_POINTER
:
1393 *(unsigned char**)pMemory
= NULL
;
1394 TRACE("pointer => %p\n", pMemory
);
1395 NdrPointerUnmarshall(pStubMsg
, (unsigned char**)pMemory
, pPointer
, fMustAlloc
);
1399 case RPC_FC_ALIGNM4
:
1400 ALIGN_POINTER(pMemory
, 3);
1402 case RPC_FC_ALIGNM8
:
1403 ALIGN_POINTER(pMemory
, 7);
1405 case RPC_FC_EMBEDDED_COMPLEX
:
1406 pMemory
+= pFormat
[1];
1408 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1409 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1410 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
1411 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1412 memset(pMemory
, 0, size
); /* just in case */
1413 if (m
) m(pStubMsg
, &pMemory
, desc
, fMustAlloc
);
1414 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
1421 FIXME("unhandled format %d\n", *pFormat
);
1429 unsigned char * WINAPI
ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1430 unsigned char *pMemory
,
1431 PFORMAT_STRING pFormat
,
1432 PFORMAT_STRING pPointer
)
1434 PFORMAT_STRING desc
;
1438 while (*pFormat
!= RPC_FC_END
) {
1442 pStubMsg
->BufferLength
+= 2;
1447 pStubMsg
->BufferLength
+= 4;
1450 case RPC_FC_POINTER
:
1451 NdrPointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1455 case RPC_FC_ALIGNM4
:
1456 ALIGN_POINTER(pMemory
, 3);
1458 case RPC_FC_ALIGNM8
:
1459 ALIGN_POINTER(pMemory
, 7);
1461 case RPC_FC_EMBEDDED_COMPLEX
:
1462 pMemory
+= pFormat
[1];
1464 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1465 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1466 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1467 if (m
) m(pStubMsg
, pMemory
, desc
);
1468 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
1475 FIXME("unhandled format %d\n", *pFormat
);
1483 unsigned char * WINAPI
ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
1484 unsigned char *pMemory
,
1485 PFORMAT_STRING pFormat
,
1486 PFORMAT_STRING pPointer
)
1488 PFORMAT_STRING desc
;
1492 while (*pFormat
!= RPC_FC_END
) {
1502 case RPC_FC_POINTER
:
1503 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1507 case RPC_FC_ALIGNM4
:
1508 ALIGN_POINTER(pMemory
, 3);
1510 case RPC_FC_ALIGNM8
:
1511 ALIGN_POINTER(pMemory
, 7);
1513 case RPC_FC_EMBEDDED_COMPLEX
:
1514 pMemory
+= pFormat
[1];
1516 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1517 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1518 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1519 if (m
) m(pStubMsg
, pMemory
, desc
);
1520 else FIXME("no freer for embedded type %02x\n", *desc
);
1527 FIXME("unhandled format %d\n", *pFormat
);
1535 unsigned long WINAPI
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
,
1536 PFORMAT_STRING pFormat
)
1538 PFORMAT_STRING desc
;
1539 unsigned long size
= 0;
1541 while (*pFormat
!= RPC_FC_END
) {
1551 case RPC_FC_POINTER
:
1554 case RPC_FC_ALIGNM4
:
1555 ALIGN_LENGTH(size
, 3);
1557 case RPC_FC_ALIGNM8
:
1558 ALIGN_LENGTH(size
, 7);
1560 case RPC_FC_EMBEDDED_COMPLEX
:
1563 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1564 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
1570 FIXME("unhandled format %d\n", *pFormat
);
1578 /***********************************************************************
1579 * NdrComplexStructMarshall [RPCRT4.@]
1581 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1582 unsigned char *pMemory
,
1583 PFORMAT_STRING pFormat
)
1585 PFORMAT_STRING conf_array
= NULL
;
1586 PFORMAT_STRING pointer_desc
= NULL
;
1587 unsigned char *OldMemory
= pStubMsg
->Memory
;
1589 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1592 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
1594 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
1597 pStubMsg
->Memory
= pMemory
;
1599 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
1602 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
1604 pStubMsg
->Memory
= OldMemory
;
1606 STD_OVERFLOW_CHECK(pStubMsg
);
1611 /***********************************************************************
1612 * NdrComplexStructUnmarshall [RPCRT4.@]
1614 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1615 unsigned char **ppMemory
,
1616 PFORMAT_STRING pFormat
,
1617 unsigned char fMustAlloc
)
1619 unsigned size
= *(const WORD
*)(pFormat
+2);
1620 PFORMAT_STRING conf_array
= NULL
;
1621 PFORMAT_STRING pointer_desc
= NULL
;
1622 unsigned char *pMemory
;
1624 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1626 if (fMustAlloc
|| !*ppMemory
)
1627 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1630 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
1632 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
1635 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
1638 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
1643 /***********************************************************************
1644 * NdrComplexStructBufferSize [RPCRT4.@]
1646 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1647 unsigned char *pMemory
,
1648 PFORMAT_STRING pFormat
)
1650 PFORMAT_STRING conf_array
= NULL
;
1651 PFORMAT_STRING pointer_desc
= NULL
;
1652 unsigned char *OldMemory
= pStubMsg
->Memory
;
1654 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1657 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
1659 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
1662 pStubMsg
->Memory
= pMemory
;
1664 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
1667 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
1669 pStubMsg
->Memory
= OldMemory
;
1672 /***********************************************************************
1673 * NdrComplexStructMemorySize [RPCRT4.@]
1675 unsigned long WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1676 PFORMAT_STRING pFormat
)
1678 /* unsigned size = *(LPWORD)(pFormat+2); */
1679 PFORMAT_STRING conf_array
= NULL
;
1680 PFORMAT_STRING pointer_desc
= NULL
;
1682 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1685 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
1687 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
1693 /***********************************************************************
1694 * NdrComplexStructFree [RPCRT4.@]
1696 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1697 unsigned char *pMemory
,
1698 PFORMAT_STRING pFormat
)
1700 PFORMAT_STRING conf_array
= NULL
;
1701 PFORMAT_STRING pointer_desc
= NULL
;
1702 unsigned char *OldMemory
= pStubMsg
->Memory
;
1704 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1707 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
1709 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
1712 pStubMsg
->Memory
= pMemory
;
1714 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
1717 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
1719 pStubMsg
->Memory
= OldMemory
;
1722 /***********************************************************************
1723 * NdrConformantArrayMarshall [RPCRT4.@]
1725 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1726 unsigned char *pMemory
,
1727 PFORMAT_STRING pFormat
)
1729 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
1730 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1731 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1733 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1734 size
= pStubMsg
->MaxCount
;
1736 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, size
);
1737 pStubMsg
->Buffer
+= 4;
1739 memcpy(pStubMsg
->Buffer
, pMemory
, size
*esize
);
1740 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1741 pStubMsg
->Buffer
+= size
*esize
;
1743 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1745 STD_OVERFLOW_CHECK(pStubMsg
);
1750 /***********************************************************************
1751 * NdrConformantArrayUnmarshall [RPCRT4.@]
1753 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1754 unsigned char **ppMemory
,
1755 PFORMAT_STRING pFormat
,
1756 unsigned char fMustAlloc
)
1758 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
1759 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1760 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1762 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1763 size
= pStubMsg
->MaxCount
;
1766 *ppMemory
= NdrAllocate(pStubMsg
, size
*esize
);
1767 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
*esize
);
1769 if (pStubMsg
->ReuseBuffer
&& !*ppMemory
)
1770 /* for servers, we may just point straight into the RPC buffer, I think
1771 * (I guess that's what MS does since MIDL code doesn't try to free) */
1772 *ppMemory
= pStubMsg
->Buffer
;
1774 /* for clients, memory should be provided by caller */
1775 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
*esize
);
1778 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1779 pStubMsg
->Buffer
+= size
*esize
;
1781 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1786 /***********************************************************************
1787 * NdrConformantArrayBufferSize [RPCRT4.@]
1789 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1790 unsigned char *pMemory
,
1791 PFORMAT_STRING pFormat
)
1793 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
1794 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1795 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1797 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1798 size
= pStubMsg
->MaxCount
;
1800 pStubMsg
->BufferLength
+= size
*esize
;
1802 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1805 /***********************************************************************
1806 * NdrConformantArrayMemorySize [RPCRT4.@]
1808 unsigned long WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1809 PFORMAT_STRING pFormat
)
1812 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1813 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1815 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1816 size
= pStubMsg
->MaxCount
;
1818 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
1823 /***********************************************************************
1824 * NdrConformantArrayFree [RPCRT4.@]
1826 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
1827 unsigned char *pMemory
,
1828 PFORMAT_STRING pFormat
)
1830 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1831 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
1833 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
1837 /***********************************************************************
1838 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
1840 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
1841 unsigned char* pMemory
,
1842 PFORMAT_STRING pFormat
)
1849 /***********************************************************************
1850 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
1852 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
1853 unsigned char** ppMemory
,
1854 PFORMAT_STRING pFormat
,
1855 unsigned char fMustAlloc
)
1862 /***********************************************************************
1863 * NdrConformantVaryingArrayFree [RPCRT4.@]
1865 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
1866 unsigned char* pMemory
,
1867 PFORMAT_STRING pFormat
)
1873 /***********************************************************************
1874 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
1876 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
1877 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
1883 /***********************************************************************
1884 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
1886 unsigned long WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
1887 PFORMAT_STRING pFormat
)
1894 /***********************************************************************
1895 * NdrComplexArrayMarshall [RPCRT4.@]
1897 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1898 unsigned char *pMemory
,
1899 PFORMAT_STRING pFormat
)
1901 DWORD size
= 0, count
, def
;
1902 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1904 def
= *(const WORD
*)&pFormat
[2];
1907 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1908 size
= pStubMsg
->MaxCount
;
1909 TRACE("conformance=%ld\n", size
);
1911 if (*(const DWORD
*)pFormat
!= 0xffffffff)
1912 FIXME("compute variance\n");
1915 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, size
);
1916 pStubMsg
->Buffer
+= 4;
1918 for (count
=0; count
<size
; count
++)
1919 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
1921 STD_OVERFLOW_CHECK(pStubMsg
);
1926 /***********************************************************************
1927 * NdrComplexArrayUnmarshall [RPCRT4.@]
1929 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1930 unsigned char **ppMemory
,
1931 PFORMAT_STRING pFormat
,
1932 unsigned char fMustAlloc
)
1934 DWORD size
= 0, count
, esize
;
1935 unsigned char *pMemory
;
1936 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1940 pFormat
= ReadConformance(pStubMsg
, pFormat
);
1941 size
= pStubMsg
->MaxCount
;
1942 TRACE("conformance=%ld\n", size
);
1946 esize
= ComplexStructSize(pStubMsg
, pFormat
);
1948 if (fMustAlloc
|| !*ppMemory
)
1949 *ppMemory
= NdrAllocate(pStubMsg
, size
*esize
);
1951 pMemory
= *ppMemory
;
1952 for (count
=0; count
<size
; count
++)
1953 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
1958 /***********************************************************************
1959 * NdrComplexArrayBufferSize [RPCRT4.@]
1961 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1962 unsigned char *pMemory
,
1963 PFORMAT_STRING pFormat
)
1965 DWORD size
= 0, count
, def
;
1966 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1968 def
= *(const WORD
*)&pFormat
[2];
1971 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1972 size
= pStubMsg
->MaxCount
;
1973 TRACE("conformance=%ld\n", size
);
1975 if (*(const DWORD
*)pFormat
!= 0xffffffff)
1976 FIXME("compute variance\n");
1979 for (count
=0; count
<size
; count
++)
1980 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
1983 /***********************************************************************
1984 * NdrComplexArrayMemorySize [RPCRT4.@]
1986 unsigned long WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1987 PFORMAT_STRING pFormat
)
1990 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1994 pFormat
= ReadConformance(pStubMsg
, pFormat
);
1995 size
= pStubMsg
->MaxCount
;
1996 TRACE("conformance=%ld\n", size
);
2003 /***********************************************************************
2004 * NdrComplexArrayFree [RPCRT4.@]
2006 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2007 unsigned char *pMemory
,
2008 PFORMAT_STRING pFormat
)
2010 DWORD size
= 0, count
, def
;
2011 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2013 def
= *(const WORD
*)&pFormat
[2];
2016 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2017 size
= pStubMsg
->MaxCount
;
2018 TRACE("conformance=%ld\n", size
);
2020 if (*(const DWORD
*)pFormat
!= 0xffffffff)
2021 FIXME("compute variance\n");
2024 for (count
=0; count
<size
; count
++)
2025 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2028 unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg
)
2030 return MAKELONG(pStubMsg
->dwDestContext
,
2031 pStubMsg
->RpcMsg
->DataRepresentation
);
2034 /***********************************************************************
2035 * NdrUserMarshalMarshall [RPCRT4.@]
2037 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2038 unsigned char *pMemory
,
2039 PFORMAT_STRING pFormat
)
2041 /* unsigned flags = pFormat[1]; */
2042 unsigned index
= *(const WORD
*)&pFormat
[2];
2043 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2044 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2045 TRACE("index=%d\n", index
);
2048 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
2049 &uflag
, pStubMsg
->Buffer
, pMemory
);
2051 STD_OVERFLOW_CHECK(pStubMsg
);
2056 /***********************************************************************
2057 * NdrUserMarshalUnmarshall [RPCRT4.@]
2059 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2060 unsigned char **ppMemory
,
2061 PFORMAT_STRING pFormat
,
2062 unsigned char fMustAlloc
)
2064 /* unsigned flags = pFormat[1];*/
2065 unsigned index
= *(const WORD
*)&pFormat
[2];
2066 DWORD memsize
= *(const WORD
*)&pFormat
[4];
2067 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2068 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2069 TRACE("index=%d\n", index
);
2071 if (fMustAlloc
|| !*ppMemory
)
2072 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2075 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
2076 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
2081 /***********************************************************************
2082 * NdrUserMarshalBufferSize [RPCRT4.@]
2084 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2085 unsigned char *pMemory
,
2086 PFORMAT_STRING pFormat
)
2088 /* unsigned flags = pFormat[1];*/
2089 unsigned index
= *(const WORD
*)&pFormat
[2];
2090 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
2091 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2092 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2093 TRACE("index=%d\n", index
);
2096 TRACE("size=%ld\n", bufsize
);
2097 pStubMsg
->BufferLength
+= bufsize
;
2101 pStubMsg
->BufferLength
=
2102 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
2103 &uflag
, pStubMsg
->BufferLength
, pMemory
);
2106 /***********************************************************************
2107 * NdrUserMarshalMemorySize [RPCRT4.@]
2109 unsigned long WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2110 PFORMAT_STRING pFormat
)
2112 unsigned index
= *(const WORD
*)&pFormat
[2];
2113 /* DWORD memsize = *(const WORD*)&pFormat[4]; */
2114 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
2115 TRACE("index=%d\n", index
);
2120 /***********************************************************************
2121 * NdrUserMarshalFree [RPCRT4.@]
2123 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
2124 unsigned char *pMemory
,
2125 PFORMAT_STRING pFormat
)
2127 /* unsigned flags = pFormat[1]; */
2128 unsigned index
= *(const WORD
*)&pFormat
[2];
2129 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2130 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2131 TRACE("index=%d\n", index
);
2133 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
2137 /***********************************************************************
2138 * NdrClearOutParameters [RPCRT4.@]
2140 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
2141 PFORMAT_STRING pFormat
,
2144 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
2147 /***********************************************************************
2148 * NdrConvert [RPCRT4.@]
2150 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2152 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
2153 /* FIXME: since this stub doesn't do any converting, the proper behavior
2154 is to raise an exception */
2157 /***********************************************************************
2158 * NdrConvert2 [RPCRT4.@]
2160 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, long NumberParams
)
2162 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2163 pStubMsg
, pFormat
, NumberParams
);
2164 /* FIXME: since this stub doesn't do any converting, the proper behavior
2165 is to raise an exception */