2377 lines
70 KiB
C++
2377 lines
70 KiB
C++
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|||
|
|
|||
|
Copyright (c) 1993-2000 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
pickle.cxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains pickling related ndr library routines.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Ryszard K. Kott (ryszardk) Oct 10, 1993
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
ryszardk Mar 17, 1994 Reworked for midl20
|
|||
|
|
|||
|
|
|||
|
------------------------------------------------------------------------*/
|
|||
|
|
|||
|
#include <ndrp.h>
|
|||
|
#include <rpcdcep.h>
|
|||
|
#include "ndrtypes.h"
|
|||
|
#include <midles.h>
|
|||
|
#include <stdarg.h>
|
|||
|
#include <malloc.h>
|
|||
|
#include "interp2.h"
|
|||
|
#include "mulsyntx.h"
|
|||
|
|
|||
|
#include "picklep.hxx"
|
|||
|
#include "util.hxx" // PerformRpcInitialization
|
|||
|
|
|||
|
extern const MIDL_FORMAT_STRING __MIDLFormatString;
|
|||
|
|
|||
|
// DCE puts endianness on the low nibble in the pickling header.
|
|||
|
|
|||
|
#define NDR_LOCAL_ENDIAN_LOW (NDR_LOCAL_ENDIAN >> 4)
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
NdrpPerformRpcInitialization (
|
|||
|
void
|
|||
|
)
|
|||
|
{
|
|||
|
return PerformRpcInitialization();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// =======================================================================
|
|||
|
// Handle validation
|
|||
|
// =======================================================================
|
|||
|
|
|||
|
void
|
|||
|
NdrpValidateMesHandle(
|
|||
|
PMIDL_ES_MESSAGE_EX pMesMsgEx )
|
|||
|
{
|
|||
|
RpcTryExcept
|
|||
|
{
|
|||
|
if ( pMesMsgEx == 0 || pMesMsgEx->Signature != MIDL_ES_SIGNATURE ||
|
|||
|
pMesMsgEx->MesMsg.MesVersion != MIDL_ES_VERSION )
|
|||
|
RpcRaiseException( RPC_S_INVALID_ARG );
|
|||
|
}
|
|||
|
RpcExcept( 1 )
|
|||
|
{
|
|||
|
RpcRaiseException( RPC_S_INVALID_ARG );
|
|||
|
}
|
|||
|
RpcEndExcept
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
NdrpValidateMesHandleReturnStatus(
|
|||
|
PMIDL_ES_MESSAGE_EX pMesMsgEx )
|
|||
|
{
|
|||
|
RPC_STATUS Status = RPC_S_OK;
|
|||
|
|
|||
|
RpcTryExcept
|
|||
|
{
|
|||
|
if ( pMesMsgEx == 0 || pMesMsgEx->Signature != MIDL_ES_SIGNATURE ||
|
|||
|
( pMesMsgEx->MesMsg.MesVersion != MIDL_ES_VERSION &&
|
|||
|
pMesMsgEx->MesMsg.MesVersion != MIDL_NDR64_ES_VERSION ) )
|
|||
|
Status = RPC_S_INVALID_ARG;
|
|||
|
}
|
|||
|
RpcExcept( 1 )
|
|||
|
{
|
|||
|
Status = RPC_S_INVALID_ARG;
|
|||
|
}
|
|||
|
RpcEndExcept
|
|||
|
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// =======================================================================
|
|||
|
// Handle allocation and freeing.
|
|||
|
// =======================================================================
|
|||
|
|
|||
|
RPC_STATUS
|
|||
|
NdrpHandleAllocate(
|
|||
|
handle_t * pHandle )
|
|||
|
/*++
|
|||
|
The reason for having this function here is that
|
|||
|
handle_t is a near pointer on win16 (but not on Dos),
|
|||
|
and we still compile the whole rpcndr20 large for that platform.
|
|||
|
So we need near malloc to be within the default segment.
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS RpcStatus;
|
|||
|
|
|||
|
if ( pHandle == NULL )
|
|||
|
return( RPC_S_INVALID_ARG );
|
|||
|
|
|||
|
// Rpc mtrt heap allocation initialization (any platform).
|
|||
|
// This is a macro that returns from NdrpHandleAllocate with
|
|||
|
// out of memory error when it fails.
|
|||
|
// It's under an if only to facilitate testing.
|
|||
|
|
|||
|
|
|||
|
RpcStatus = NdrpPerformRpcInitialization();
|
|||
|
if ( RpcStatus != RPC_S_OK )
|
|||
|
return(RpcStatus);
|
|||
|
|
|||
|
// Now allocate.
|
|||
|
// Mes handle includes stubmsg but we need to add rpcmsg to it.
|
|||
|
|
|||
|
*pHandle = new char[ sizeof(MIDL_ES_MESSAGE_EX) ];
|
|||
|
|
|||
|
if ( *pHandle == NULL )
|
|||
|
return( RPC_S_OUT_OF_MEMORY );
|
|||
|
return( RPC_S_OK );
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
MesHandleFree( handle_t Handle )
|
|||
|
/*++
|
|||
|
This routine frees a pickling handle.
|
|||
|
--*/
|
|||
|
{
|
|||
|
if ( Handle)
|
|||
|
{
|
|||
|
delete Handle;
|
|||
|
}
|
|||
|
return( RPC_S_OK );
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
I_NdrMesMessageInit(
|
|||
|
PMIDL_ES_MESSAGE_EX pMesMsgEx )
|
|||
|
{
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = & pMesMsgEx->MesMsg.StubMsg;
|
|||
|
PRPC_MESSAGE pRpcMsg = & pMesMsgEx->RpcMsg;
|
|||
|
|
|||
|
MIDL_memset( pStubMsg, 0, sizeof(MIDL_STUB_MESSAGE) );
|
|||
|
MIDL_memset( pRpcMsg, 0, sizeof(RPC_MESSAGE) );
|
|||
|
|
|||
|
pRpcMsg->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;
|
|||
|
|
|||
|
pStubMsg->RpcMsg = pRpcMsg;
|
|||
|
pStubMsg->IsClient = 1;
|
|||
|
|
|||
|
NdrSetupLowStackMark( pStubMsg );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// =======================================================================
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
MesEncodeIncrementalHandleCreate(
|
|||
|
void * UserState,
|
|||
|
MIDL_ES_ALLOC Alloc,
|
|||
|
MIDL_ES_WRITE Write,
|
|||
|
handle_t * pHandle )
|
|||
|
/*++
|
|||
|
This routine creates an encoding incremental pickling handle.
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
if ( (Status = NdrpHandleAllocate( pHandle )) == RPC_S_OK )
|
|||
|
{
|
|||
|
((PMIDL_ES_MESSAGE) *pHandle)->HandleStyle = MES_INCREMENTAL_HANDLE;
|
|||
|
((PMIDL_ES_MESSAGE) *pHandle)->MesVersion = MIDL_ES_VERSION;
|
|||
|
((PMIDL_ES_MESSAGE_EX)*pHandle)->Signature = MIDL_ES_SIGNATURE;
|
|||
|
|
|||
|
if ( (Status = MesIncrementalHandleReset( *pHandle,
|
|||
|
UserState,
|
|||
|
Alloc,
|
|||
|
Write,
|
|||
|
0,
|
|||
|
MES_ENCODE )) != RPC_S_OK )
|
|||
|
{
|
|||
|
MesHandleFree( *pHandle );
|
|||
|
*pHandle = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return( Status );
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
MesDecodeIncrementalHandleCreate(
|
|||
|
void * UserState,
|
|||
|
MIDL_ES_READ Read,
|
|||
|
handle_t * pHandle )
|
|||
|
/*++
|
|||
|
This routine creates a descoding incrementsl pickling handle.
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
if ( (Status = NdrpHandleAllocate( pHandle )) == RPC_S_OK )
|
|||
|
{
|
|||
|
((PMIDL_ES_MESSAGE) *pHandle)->HandleStyle = MES_INCREMENTAL_HANDLE;
|
|||
|
((PMIDL_ES_MESSAGE) *pHandle)->MesVersion = MIDL_ES_VERSION;
|
|||
|
((PMIDL_ES_MESSAGE_EX)*pHandle)->Signature = MIDL_ES_SIGNATURE;
|
|||
|
|
|||
|
if ( (Status = MesIncrementalHandleReset( *pHandle,
|
|||
|
UserState,
|
|||
|
0,
|
|||
|
0,
|
|||
|
Read,
|
|||
|
MES_DECODE )) != RPC_S_OK )
|
|||
|
{
|
|||
|
MesHandleFree( *pHandle );
|
|||
|
*pHandle = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return( Status );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
MesIncrementalHandleReset(
|
|||
|
handle_t Handle,
|
|||
|
void * UserState,
|
|||
|
MIDL_ES_ALLOC Alloc,
|
|||
|
MIDL_ES_WRITE Write,
|
|||
|
MIDL_ES_READ Read,
|
|||
|
MIDL_ES_CODE Operation )
|
|||
|
/*++
|
|||
|
This routine initializes a pickling handle with supplied arguments.
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
Status = NdrpValidateMesHandleReturnStatus( (PMIDL_ES_MESSAGE_EX)Handle );
|
|||
|
if ( Status != RPC_S_OK )
|
|||
|
return Status;
|
|||
|
|
|||
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|||
|
|
|||
|
// we support ndr64 pickling now.
|
|||
|
if ( Handle == NULL ||
|
|||
|
pMesMsg->HandleStyle != MES_INCREMENTAL_HANDLE ||
|
|||
|
( Operation != MES_ENCODE &&
|
|||
|
Operation != MES_DECODE &&
|
|||
|
Operation != MES_ENCODE_NDR64 &&
|
|||
|
Operation != MES_DECODE_NDR64 ) )
|
|||
|
return( RPC_S_INVALID_ARG );
|
|||
|
|
|||
|
I_NdrMesMessageInit( (PMIDL_ES_MESSAGE_EX) Handle );
|
|||
|
|
|||
|
pMesMsg->Operation = Operation;
|
|||
|
pMesMsg->HandleFlags = 0;
|
|||
|
pMesMsg->ByteCount = 0;
|
|||
|
if ( Operation == MES_ENCODE_NDR64 ||
|
|||
|
Operation == MES_DECODE_NDR64 )
|
|||
|
{
|
|||
|
pMesMsg->MesVersion = MIDL_NDR64_ES_VERSION;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pMesMsg->MesVersion = MIDL_ES_VERSION;
|
|||
|
}
|
|||
|
|
|||
|
if ( UserState )
|
|||
|
pMesMsg->UserState = UserState;
|
|||
|
if ( Alloc )
|
|||
|
pMesMsg->Alloc = Alloc;
|
|||
|
if ( Write )
|
|||
|
pMesMsg->Write = Write;
|
|||
|
if ( Read )
|
|||
|
pMesMsg->Read = Read;
|
|||
|
|
|||
|
if ( ( (Operation == MES_ENCODE || Operation == MES_ENCODE_NDR64 ) &&
|
|||
|
(pMesMsg->Alloc == NULL || pMesMsg->Write == NULL) ) ||
|
|||
|
( (Operation == MES_DECODE || Operation == MES_DECODE_NDR64 ) &&
|
|||
|
(pMesMsg->Read == NULL)) )
|
|||
|
return( RPC_S_INVALID_ARG );
|
|||
|
|
|||
|
return( RPC_S_OK );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
MesEncodeFixedBufferHandleCreate(
|
|||
|
char * Buffer,
|
|||
|
unsigned long BufferSize,
|
|||
|
unsigned long * pEncodedSize,
|
|||
|
handle_t * pHandle )
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
if( (LONG_PTR)Buffer & 0x7 )
|
|||
|
return( RPC_X_INVALID_BUFFER );
|
|||
|
|
|||
|
if ( (Status = NdrpHandleAllocate( pHandle )) == RPC_S_OK )
|
|||
|
{
|
|||
|
((PMIDL_ES_MESSAGE) *pHandle)->HandleStyle = MES_FIXED_BUFFER_HANDLE;
|
|||
|
((PMIDL_ES_MESSAGE) *pHandle)->MesVersion = MIDL_ES_VERSION;
|
|||
|
((PMIDL_ES_MESSAGE_EX)*pHandle)->Signature = MIDL_ES_SIGNATURE;
|
|||
|
|
|||
|
if ( (Status = MesBufferHandleReset( *pHandle,
|
|||
|
MES_FIXED_BUFFER_HANDLE,
|
|||
|
MES_ENCODE,
|
|||
|
& Buffer,
|
|||
|
BufferSize,
|
|||
|
pEncodedSize )) != RPC_S_OK )
|
|||
|
{
|
|||
|
MesHandleFree( *pHandle );
|
|||
|
*pHandle = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return( Status );
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
MesEncodeDynBufferHandleCreate(
|
|||
|
char ** pBuffer,
|
|||
|
unsigned long * pEncodedSize,
|
|||
|
handle_t * pHandle )
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
if ( (Status = NdrpHandleAllocate( pHandle )) == RPC_S_OK )
|
|||
|
{
|
|||
|
((PMIDL_ES_MESSAGE) *pHandle)->HandleStyle = MES_DYNAMIC_BUFFER_HANDLE;
|
|||
|
((PMIDL_ES_MESSAGE) *pHandle)->MesVersion = MIDL_ES_VERSION;
|
|||
|
((PMIDL_ES_MESSAGE_EX)*pHandle)->Signature = MIDL_ES_SIGNATURE;
|
|||
|
|
|||
|
if ( (Status = MesBufferHandleReset( *pHandle,
|
|||
|
MES_DYNAMIC_BUFFER_HANDLE,
|
|||
|
MES_ENCODE,
|
|||
|
pBuffer,
|
|||
|
0,
|
|||
|
pEncodedSize )) != RPC_S_OK )
|
|||
|
{
|
|||
|
MesHandleFree( *pHandle );
|
|||
|
*pHandle = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return( Status );
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
MesDecodeBufferHandleCreate(
|
|||
|
char * Buffer,
|
|||
|
unsigned long BufferSize,
|
|||
|
handle_t * pHandle )
|
|||
|
{
|
|||
|
if ( Buffer == NULL ||
|
|||
|
BufferSize < MES_CTYPE_HEADER_SIZE + 8 )
|
|||
|
return( RPC_S_INVALID_ARG );
|
|||
|
|
|||
|
if( (LONG_PTR)Buffer & 0x7 )
|
|||
|
return( RPC_X_INVALID_BUFFER );
|
|||
|
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
if ( (Status = NdrpHandleAllocate( pHandle )) == RPC_S_OK )
|
|||
|
{
|
|||
|
((PMIDL_ES_MESSAGE) *pHandle)->HandleStyle = MES_FIXED_BUFFER_HANDLE;
|
|||
|
((PMIDL_ES_MESSAGE) *pHandle)->MesVersion = MIDL_ES_VERSION;
|
|||
|
((PMIDL_ES_MESSAGE_EX)*pHandle)->Signature = MIDL_ES_SIGNATURE;
|
|||
|
|
|||
|
if ( (Status = MesBufferHandleReset( *pHandle,
|
|||
|
MES_FIXED_BUFFER_HANDLE,
|
|||
|
MES_DECODE,
|
|||
|
& Buffer,
|
|||
|
BufferSize,
|
|||
|
0 )) != RPC_S_OK )
|
|||
|
{
|
|||
|
MesHandleFree( *pHandle );
|
|||
|
*pHandle = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return( Status );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// reset a pickling handle.
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
MesBufferHandleReset(
|
|||
|
handle_t Handle,
|
|||
|
unsigned long HandleStyle,
|
|||
|
MIDL_ES_CODE Operation,
|
|||
|
char * * pBuffer,
|
|||
|
unsigned long BufferSize,
|
|||
|
unsigned long * pEncodedSize )
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
Status = NdrpValidateMesHandleReturnStatus( (PMIDL_ES_MESSAGE_EX)Handle );
|
|||
|
if ( Status != RPC_S_OK )
|
|||
|
return Status;
|
|||
|
|
|||
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|||
|
|
|||
|
if ( Handle == NULL || pBuffer == NULL ||
|
|||
|
( HandleStyle != MES_FIXED_BUFFER_HANDLE &&
|
|||
|
HandleStyle != MES_DYNAMIC_BUFFER_HANDLE ) ||
|
|||
|
(HandleStyle == MES_FIXED_BUFFER_HANDLE &&
|
|||
|
(*pBuffer == NULL || BufferSize < MES_MINIMAL_BUFFER_SIZE)) ||
|
|||
|
(Operation == MES_ENCODE && pEncodedSize == NULL) ||
|
|||
|
(Operation == MES_DECODE &&
|
|||
|
(*pBuffer == NULL || BufferSize < MES_MINIMAL_BUFFER_SIZE))
|
|||
|
)
|
|||
|
return( RPC_S_INVALID_ARG );
|
|||
|
|
|||
|
if ( (Operation == MES_ENCODE_NDR64 && pEncodedSize == NULL) ||
|
|||
|
(Operation == MES_DECODE_NDR64 &&
|
|||
|
(*pBuffer == NULL || BufferSize < MES_MINIMAL_NDR64_BUFFER_SIZE ) ) )
|
|||
|
return( RPC_S_INVALID_ARG );
|
|||
|
|
|||
|
I_NdrMesMessageInit( (PMIDL_ES_MESSAGE_EX) Handle );
|
|||
|
|
|||
|
pMesMsg->Operation = Operation;
|
|||
|
pMesMsg->HandleFlags = 0;
|
|||
|
pMesMsg->HandleStyle = HandleStyle;
|
|||
|
pMesMsg->ByteCount = 0;
|
|||
|
if ( Operation == MES_ENCODE_NDR64 ||
|
|||
|
Operation == MES_DECODE_NDR64 )
|
|||
|
{
|
|||
|
pMesMsg->MesVersion = MIDL_NDR64_ES_VERSION;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pMesMsg->MesVersion = MIDL_ES_VERSION;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = & pMesMsg->StubMsg;
|
|||
|
PRPC_MESSAGE pRpcMsg = pMesMsg->StubMsg.RpcMsg;
|
|||
|
|
|||
|
if ( HandleStyle == MES_FIXED_BUFFER_HANDLE)
|
|||
|
{
|
|||
|
pMesMsg->Buffer = (uchar *)*pBuffer;
|
|||
|
|
|||
|
pRpcMsg->BufferLength = BufferSize;
|
|||
|
pRpcMsg->Buffer = *pBuffer;
|
|||
|
|
|||
|
pStubMsg->Buffer = (uchar *)*pBuffer;
|
|||
|
pStubMsg->BufferStart = (uchar *)*pBuffer;
|
|||
|
pStubMsg->BufferEnd = (uchar *)*pBuffer + BufferSize;
|
|||
|
}
|
|||
|
if ( HandleStyle == MES_DYNAMIC_BUFFER_HANDLE)
|
|||
|
{
|
|||
|
pMesMsg->pDynBuffer = (uchar **)pBuffer;
|
|||
|
if (Operation == MES_DECODE || Operation == MES_DECODE_NDR64 )
|
|||
|
{
|
|||
|
pMesMsg->Buffer = (uchar *)*pBuffer;
|
|||
|
|
|||
|
pRpcMsg->BufferLength = BufferSize;
|
|||
|
pRpcMsg->Buffer = *pBuffer;
|
|||
|
|
|||
|
pStubMsg->Buffer = (uchar *)*pBuffer;
|
|||
|
pStubMsg->BufferStart = (uchar *)*pBuffer;
|
|||
|
pStubMsg->BufferEnd = (uchar *)*pBuffer + BufferSize;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
*pBuffer = NULL;
|
|||
|
|
|||
|
pRpcMsg->BufferLength = 0;
|
|||
|
pRpcMsg->Buffer = 0;
|
|||
|
|
|||
|
pStubMsg->Buffer = 0;
|
|||
|
pStubMsg->BufferStart = 0;
|
|||
|
pStubMsg->BufferEnd = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
pMesMsg->BufferSize = BufferSize;
|
|||
|
pMesMsg->pEncodedSize = pEncodedSize;
|
|||
|
|
|||
|
return( RPC_S_OK );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
MesInqProcEncodingId(
|
|||
|
handle_t Handle,
|
|||
|
PRPC_SYNTAX_IDENTIFIER pInterfaceId,
|
|||
|
unsigned long * pProcNumber )
|
|||
|
/*++
|
|||
|
|
|||
|
The routine returns an informantion about the last proc encoding.
|
|||
|
Called before an encode, it should return RPC_X_INVALID_ES_ACTION.
|
|||
|
Called after an encode, it should return the last encoding info.
|
|||
|
Called before a decode, it should return the same encoding info.
|
|||
|
Called after a decode, it should return the just decoded encode info.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
Status = NdrpValidateMesHandleReturnStatus( (PMIDL_ES_MESSAGE_EX)Handle );
|
|||
|
if ( Status != RPC_S_OK )
|
|||
|
return Status;
|
|||
|
|
|||
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|||
|
|
|||
|
Status = RPC_X_INVALID_ES_ACTION;
|
|||
|
|
|||
|
if ( Handle == NULL || pInterfaceId == NULL || pProcNumber == NULL )
|
|||
|
return( RPC_S_INVALID_ARG );
|
|||
|
|
|||
|
RpcTryExcept
|
|||
|
{
|
|||
|
// Note: because we allow to pickle several procs into the same buffer
|
|||
|
// (using the same handle without resetting), the PEEKED bit may be
|
|||
|
// cleared and the info may still be available.
|
|||
|
// On the other hand, the info bit is always set if we unmarshaled
|
|||
|
// a header. So check the info bit first.
|
|||
|
|
|||
|
if ( pMesMsg->Operation == MES_DECODE &&
|
|||
|
! GET_MES_INFO_AVAILABLE( pMesMsg ) &&
|
|||
|
! GET_MES_HEADER_PEEKED( pMesMsg ) )
|
|||
|
{
|
|||
|
NdrpProcHeaderUnmarshallAll( pMesMsg );
|
|||
|
SET_MES_HEADER_PEEKED( pMesMsg );
|
|||
|
}
|
|||
|
|
|||
|
if ( GET_MES_INFO_AVAILABLE( pMesMsg ) )
|
|||
|
{
|
|||
|
RpcpMemoryCopy( pInterfaceId,
|
|||
|
& pMesMsg->InterfaceId,
|
|||
|
sizeof( RPC_SYNTAX_IDENTIFIER ) );
|
|||
|
*pProcNumber = pMesMsg->ProcNumber;
|
|||
|
Status = RPC_S_OK;
|
|||
|
}
|
|||
|
// else Status = RPC_X_INVALID_ES_ACTION;
|
|||
|
}
|
|||
|
RpcExcept(1)
|
|||
|
{
|
|||
|
Status = RpcExceptionCode();
|
|||
|
}
|
|||
|
RpcEndExcept
|
|||
|
|
|||
|
return( Status );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// =======================================================================
|
|||
|
//
|
|||
|
// Private Alloc, Read, Write helper routines
|
|||
|
//
|
|||
|
// =======================================================================
|
|||
|
|
|||
|
void
|
|||
|
NdrpAllocPicklingBuffer(
|
|||
|
PMIDL_ES_MESSAGE pMesMsg,
|
|||
|
unsigned int RequiredLen
|
|||
|
)
|
|||
|
{
|
|||
|
unsigned int ActualLen;
|
|||
|
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
|
|||
|
// Get the marshalling buffer.
|
|||
|
|
|||
|
// alert: assuming the return buffer is aligned at 16 in 64bit platform.
|
|||
|
// ndr64 buffer needs to be aligned at 16.
|
|||
|
switch ( pMesMsg->HandleStyle )
|
|||
|
{
|
|||
|
case MES_INCREMENTAL_HANDLE:
|
|||
|
// Allocating the pickling buffer.
|
|||
|
|
|||
|
ActualLen = RequiredLen;
|
|||
|
(pMesMsg->Alloc)( pMesMsg->UserState,
|
|||
|
(char * *) & pStubMsg->Buffer,
|
|||
|
& ActualLen );
|
|||
|
if ( ActualLen < RequiredLen )
|
|||
|
RpcRaiseException( RPC_S_OUT_OF_MEMORY );
|
|||
|
|
|||
|
pStubMsg->RpcMsg->BufferLength = ActualLen;
|
|||
|
pStubMsg->RpcMsg->Buffer = pStubMsg->Buffer;
|
|||
|
|
|||
|
pStubMsg->BufferStart = pStubMsg->Buffer;
|
|||
|
pStubMsg->BufferEnd = pStubMsg->Buffer + ActualLen;
|
|||
|
break;
|
|||
|
|
|||
|
case MES_FIXED_BUFFER_HANDLE:
|
|||
|
break;
|
|||
|
|
|||
|
case MES_DYNAMIC_BUFFER_HANDLE:
|
|||
|
{
|
|||
|
// We have to return one buffer for multiple encodings,
|
|||
|
// and a cumulative size along with it.
|
|||
|
// So, we check if we have to copy data to a new buffer.
|
|||
|
|
|||
|
uchar * pOldBufferToCopy = NULL;
|
|||
|
|
|||
|
if ( pMesMsg->ByteCount )
|
|||
|
{
|
|||
|
RequiredLen += pMesMsg->ByteCount;
|
|||
|
pOldBufferToCopy = *pMesMsg->pDynBuffer;
|
|||
|
}
|
|||
|
|
|||
|
pStubMsg->Buffer = (uchar *) pStubMsg->pfnAllocate( RequiredLen );
|
|||
|
if ( pStubMsg->Buffer == NULL )
|
|||
|
RpcRaiseException( RPC_S_OUT_OF_MEMORY );
|
|||
|
|
|||
|
if ( pOldBufferToCopy )
|
|||
|
{
|
|||
|
RpcpMemoryCopy( pStubMsg->Buffer,
|
|||
|
pOldBufferToCopy,
|
|||
|
pMesMsg->ByteCount );
|
|||
|
|
|||
|
pStubMsg->pfnFree( pOldBufferToCopy );
|
|||
|
}
|
|||
|
|
|||
|
pStubMsg->RpcMsg->BufferLength = RequiredLen;
|
|||
|
pStubMsg->RpcMsg->Buffer = pStubMsg->Buffer;
|
|||
|
|
|||
|
pStubMsg->BufferStart = pStubMsg->Buffer;
|
|||
|
pStubMsg->BufferEnd = pStubMsg->Buffer + RequiredLen;
|
|||
|
|
|||
|
* pMesMsg->pDynBuffer = pStubMsg->Buffer;
|
|||
|
pMesMsg->BufferSize = RequiredLen;
|
|||
|
|
|||
|
// We write after the previously written buffer.
|
|||
|
|
|||
|
pStubMsg->Buffer += pMesMsg->ByteCount;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if( (LONG_PTR)pStubMsg->Buffer & 0x7 )
|
|||
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
NdrpReadPicklingBuffer(
|
|||
|
PMIDL_ES_MESSAGE pMesMsg,
|
|||
|
unsigned int RequiredLen
|
|||
|
)
|
|||
|
{
|
|||
|
unsigned int ActualLen;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
|
|||
|
// Read the marshalling buffer.
|
|||
|
|
|||
|
if ( pMesMsg->HandleStyle == MES_INCREMENTAL_HANDLE )
|
|||
|
{
|
|||
|
// Allocating the pickling buffer.
|
|||
|
|
|||
|
ActualLen = RequiredLen;
|
|||
|
(pMesMsg->Read)( pMesMsg->UserState,
|
|||
|
(char **) & pStubMsg->Buffer,
|
|||
|
& ActualLen );
|
|||
|
if ( ActualLen < RequiredLen )
|
|||
|
RpcRaiseException( RPC_S_OUT_OF_MEMORY );
|
|||
|
|
|||
|
pStubMsg->RpcMsg->BufferLength = ActualLen;
|
|||
|
pStubMsg->RpcMsg->Buffer = pStubMsg->Buffer;
|
|||
|
|
|||
|
pStubMsg->BufferStart = pStubMsg->Buffer;
|
|||
|
pStubMsg->BufferEnd = pStubMsg->Buffer + ActualLen;
|
|||
|
}
|
|||
|
|
|||
|
if( (LONG_PTR)pStubMsg->Buffer & 0x7 )
|
|||
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
NdrpWritePicklingBuffer(
|
|||
|
PMIDL_ES_MESSAGE pMesMsg,
|
|||
|
uchar * pBuffer,
|
|||
|
size_t WriteLength
|
|||
|
)
|
|||
|
{
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
|
|||
|
NDR_ASSERT( ! ((LONG_PTR)pStubMsg->Buffer & 0x7), "Misaligned buffer" );
|
|||
|
NDR_ASSERT( ! (WriteLength & 0x7 ), "Length should be multiple of 8" );
|
|||
|
|
|||
|
// Write the marshalling buffer.
|
|||
|
|
|||
|
if ( pMesMsg->HandleStyle == MES_INCREMENTAL_HANDLE )
|
|||
|
{
|
|||
|
(pMesMsg->Write)( pMesMsg->UserState,
|
|||
|
(char * ) pBuffer,
|
|||
|
WriteLength );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// We return the cumulative length both for the fixed buffer
|
|||
|
// and for the dynamic buffer style.
|
|||
|
|
|||
|
pMesMsg->ByteCount += WriteLength;
|
|||
|
* pMesMsg->pEncodedSize = pMesMsg->ByteCount;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// =======================================================================
|
|||
|
//
|
|||
|
// One call generic routine pickling.
|
|||
|
//
|
|||
|
// =======================================================================
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
NdrpProcHeaderMarshall(
|
|||
|
PMIDL_ES_MESSAGE pMesMsg
|
|||
|
)
|
|||
|
{
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
|
|||
|
// Marshall DCE pickle header.
|
|||
|
|
|||
|
if( (LONG_PTR)pStubMsg->Buffer & 0x7 )
|
|||
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|||
|
|
|||
|
* pStubMsg->Buffer++ = MIDL_ES_VERSION;
|
|||
|
* pStubMsg->Buffer++ = NDR_LOCAL_ENDIAN_LOW;
|
|||
|
*( PSHORT_LV_CAST pStubMsg->Buffer)++ = (short)0xcccc; // filler
|
|||
|
|
|||
|
// Marshall transfer syntax from the stub.
|
|||
|
|
|||
|
RpcpMemoryCopy( pStubMsg->Buffer,
|
|||
|
& ((PRPC_CLIENT_INTERFACE)(pStubMsg->
|
|||
|
StubDesc->RpcInterfaceInformation))->TransferSyntax,
|
|||
|
sizeof(RPC_SYNTAX_IDENTIFIER) );
|
|||
|
|
|||
|
// We need to remember InterfaceId for inquiries.
|
|||
|
|
|||
|
RpcpMemoryCopy( & pMesMsg->InterfaceId,
|
|||
|
& ((PRPC_CLIENT_INTERFACE)(pStubMsg->
|
|||
|
StubDesc->RpcInterfaceInformation))->InterfaceId,
|
|||
|
sizeof(RPC_SYNTAX_IDENTIFIER) );
|
|||
|
|
|||
|
// Marshall InterfaceId and ProcNumber from the handle.
|
|||
|
|
|||
|
RpcpMemoryCopy( pStubMsg->Buffer + sizeof(RPC_SYNTAX_IDENTIFIER),
|
|||
|
& pMesMsg->InterfaceId,
|
|||
|
sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(long) );
|
|||
|
|
|||
|
SET_MES_INFO_AVAILABLE( pMesMsg );
|
|||
|
|
|||
|
pStubMsg->Buffer += 2 * sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(long);
|
|||
|
|
|||
|
* pStubMsg->Buffer++ = NDR_LOCAL_ENDIAN_LOW;
|
|||
|
* pStubMsg->Buffer++ = NDR_ASCII_CHAR;
|
|||
|
* pStubMsg->Buffer++ = (char) (NDR_IEEE_FLOAT >> 8);
|
|||
|
* pStubMsg->Buffer++ = 0; // filler
|
|||
|
|
|||
|
// This is non-DCE element as they have just 4 more bytes of filler here.
|
|||
|
// This field is used only when unmarshalling in our incremental style.
|
|||
|
|
|||
|
*( PLONG_LV_CAST pStubMsg->Buffer)++ = pStubMsg->BufferLength -
|
|||
|
MES_PROC_HEADER_SIZE;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
NdrpProcHeaderUnmarshall(
|
|||
|
PMIDL_ES_MESSAGE pMesMsg
|
|||
|
)
|
|||
|
{
|
|||
|
unsigned char * BufferToRestore;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
|
|||
|
if ( GET_MES_HEADER_PEEKED( pMesMsg ) )
|
|||
|
return;
|
|||
|
|
|||
|
NdrpReadPicklingBuffer( pMesMsg, MES_PROC_HEADER_SIZE );
|
|||
|
|
|||
|
// Unmarshalling the header
|
|||
|
|
|||
|
if ( *pStubMsg->Buffer != MIDL_ES_VERSION )
|
|||
|
RpcRaiseException( RPC_X_WRONG_ES_VERSION );
|
|||
|
|
|||
|
BufferToRestore = pStubMsg->Buffer + 4;
|
|||
|
|
|||
|
if ( pStubMsg->Buffer[1] != NDR_LOCAL_ENDIAN_LOW )
|
|||
|
{
|
|||
|
// The DCE header has the endianness on the low nibble, while
|
|||
|
// our DataRep has it on the high nibble.
|
|||
|
// We need only endianess to convert the proc header.
|
|||
|
|
|||
|
byte Endianness = (pStubMsg->Buffer[1] << 4 );
|
|||
|
|
|||
|
pStubMsg->RpcMsg->DataRepresentation = Endianness;
|
|||
|
|
|||
|
pStubMsg->Buffer += 4;
|
|||
|
NdrSimpleStructConvert( pStubMsg,
|
|||
|
&__MIDLFormatString.Format[32],
|
|||
|
FALSE );
|
|||
|
}
|
|||
|
|
|||
|
pStubMsg->Buffer = BufferToRestore;
|
|||
|
|
|||
|
// Verify the transfer syntax
|
|||
|
|
|||
|
if ( NULL != pStubMsg->StubDesc )
|
|||
|
{
|
|||
|
if (0 != RpcpMemoryCompare(
|
|||
|
pStubMsg->Buffer,
|
|||
|
& ((PRPC_CLIENT_INTERFACE)(pStubMsg->
|
|||
|
StubDesc->RpcInterfaceInformation))->
|
|||
|
TransferSyntax,
|
|||
|
sizeof(RPC_SYNTAX_IDENTIFIER) ) )
|
|||
|
{
|
|||
|
RpcRaiseException( RPC_S_UNSUPPORTED_TRANS_SYN );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
RpcpMemoryCopy( &((PMIDL_ES_MESSAGE_EX)pMesMsg)->TransferSyntax,
|
|||
|
pStubMsg->Buffer,
|
|||
|
sizeof( RPC_SYNTAX_IDENTIFIER ) );
|
|||
|
|
|||
|
pStubMsg->Buffer += sizeof(RPC_SYNTAX_IDENTIFIER);
|
|||
|
|
|||
|
// We need to remember the last InterfaceId and ProcNumber for inquiries.
|
|||
|
|
|||
|
RpcpMemoryCopy( & pMesMsg->InterfaceId,
|
|||
|
pStubMsg->Buffer,
|
|||
|
sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(long) );
|
|||
|
|
|||
|
pStubMsg->Buffer += sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(long);
|
|||
|
|
|||
|
SET_MES_INFO_AVAILABLE( pMesMsg );
|
|||
|
|
|||
|
unsigned long AlienDataRepresentation =
|
|||
|
( (pStubMsg->Buffer[0] << 4) | // endianness
|
|||
|
pStubMsg->Buffer[1] | // chars
|
|||
|
((unsigned long)(pStubMsg->Buffer[2]) << 8) ); // float
|
|||
|
pMesMsg->AlienDataRep = AlienDataRepresentation;
|
|||
|
pMesMsg->IncrDataSize = (size_t) *(unsigned long *)
|
|||
|
(pStubMsg->Buffer + 4);
|
|||
|
pStubMsg->Buffer += 8;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
NdrpDataBufferInit(
|
|||
|
PMIDL_ES_MESSAGE pMesMsg,
|
|||
|
PFORMAT_STRING pProcFormat
|
|||
|
)
|
|||
|
{
|
|||
|
size_t RequiredLen;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
|
|||
|
if ( pMesMsg->AlienDataRep != NDR_LOCAL_DATA_REPRESENTATION )
|
|||
|
{
|
|||
|
pStubMsg->RpcMsg->DataRepresentation = pMesMsg->AlienDataRep;
|
|||
|
NdrConvert( pStubMsg, pProcFormat );
|
|||
|
}
|
|||
|
|
|||
|
// When incremental, this is the non-DCE buffer size.
|
|||
|
// For non incremental RequiredLen will be ignored.
|
|||
|
|
|||
|
RequiredLen = pMesMsg->IncrDataSize;
|
|||
|
|
|||
|
NdrpReadPicklingBuffer( pMesMsg, RequiredLen );
|
|||
|
|
|||
|
pStubMsg->pfnAllocate = pStubMsg->StubDesc->pfnAllocate;
|
|||
|
pStubMsg->pfnFree = pStubMsg->StubDesc->pfnFree;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void RPC_VAR_ENTRY
|
|||
|
NdrMesProcEncodeDecode(
|
|||
|
handle_t Handle,
|
|||
|
const MIDL_STUB_DESC * pStubDesc,
|
|||
|
PFORMAT_STRING pFormat,
|
|||
|
...
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine description:
|
|||
|
|
|||
|
Sizes and marshalls [in] arguments, unmarshalls [out] arguments.
|
|||
|
Includes a routine header.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Handle - a pickling handle
|
|||
|
pStubDesc - a pointer to the stub descriptor,
|
|||
|
pFormat - a pointer to the format code describing the object type.
|
|||
|
|
|||
|
Note:
|
|||
|
|
|||
|
Please note that all the ... arguments here are pointers.
|
|||
|
We will handle them appropriately to access the original arguments.
|
|||
|
|
|||
|
The pickling header for the routine is included in the sizing.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BOOL fMoreParams;
|
|||
|
PFORMAT_STRING pProcFormat;
|
|||
|
void * pArg;
|
|||
|
va_list ArgList;
|
|||
|
unsigned char * BufferSaved;
|
|||
|
size_t WriteLength;
|
|||
|
|
|||
|
NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|||
|
|
|||
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = & pMesMsg->StubMsg;
|
|||
|
|
|||
|
NDR_ASSERT( *pFormat == FC_BIND_PRIMITIVE || *pFormat == 0,
|
|||
|
"Pickling handle expected" );
|
|||
|
|
|||
|
pStubMsg->StubDesc = pStubDesc;
|
|||
|
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
|||
|
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
|||
|
|
|||
|
BOOL fEncodeUsed = (pFormat[1] & ENCODE_IS_USED) &&
|
|||
|
pMesMsg->Operation == MES_ENCODE;
|
|||
|
BOOL fDecodeUsed = (pFormat[1] & DECODE_IS_USED) &&
|
|||
|
pMesMsg->Operation == MES_DECODE;
|
|||
|
|
|||
|
NDR_ASSERT( !( fEncodeUsed && fDecodeUsed ),
|
|||
|
"Both encode & decode at the same time" );
|
|||
|
|
|||
|
if ( !fEncodeUsed && !fDecodeUsed )
|
|||
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|||
|
|
|||
|
pStubMsg->FullPtrXlatTables = ( (pFormat[1] & Oi_FULL_PTR_USED)
|
|||
|
? NdrFullPointerXlatInit( 0, XLAT_CLIENT )
|
|||
|
: 0 );
|
|||
|
|
|||
|
pFormat += HAS_RPCFLAGS(pFormat[1]) ? 6
|
|||
|
: 2;
|
|||
|
|
|||
|
// We use the proc number only to support MesInqEncodingId. So, set it for
|
|||
|
// encoding only. When decoding it will get picked up from the header.
|
|||
|
//
|
|||
|
if ( fEncodeUsed )
|
|||
|
pMesMsg->ProcNumber = * (unsigned short *) pFormat;
|
|||
|
|
|||
|
pFormat +=4;
|
|||
|
|
|||
|
if ( *pFormat == FC_BIND_PRIMITIVE )
|
|||
|
pFormat += 4;
|
|||
|
|
|||
|
if ( fEncodeUsed )
|
|||
|
{
|
|||
|
//
|
|||
|
// The sizing walk.
|
|||
|
//
|
|||
|
|
|||
|
pStubMsg->BufferLength = MES_PROC_HEADER_SIZE;
|
|||
|
|
|||
|
// We will be walking this routine's stack.
|
|||
|
// However, for the engine to be able to calculate conformant arrays
|
|||
|
// and such, top of the original routine's stack has to be available
|
|||
|
// via the stub message.
|
|||
|
|
|||
|
INIT_ARG( ArgList, pFormat );
|
|||
|
GET_FIRST_ARG( pArg, ArgList );
|
|||
|
|
|||
|
pStubMsg->StackTop = *(uchar * *)pArg;
|
|||
|
pProcFormat = pFormat;
|
|||
|
fMoreParams = TRUE;
|
|||
|
|
|||
|
for ( ; fMoreParams ; pProcFormat += 2 )
|
|||
|
{
|
|||
|
switch ( *pProcFormat )
|
|||
|
{
|
|||
|
case FC_OUT_PARAM:
|
|||
|
break;
|
|||
|
|
|||
|
case FC_RETURN_PARAM:
|
|||
|
fMoreParams = FALSE;
|
|||
|
break;
|
|||
|
default:
|
|||
|
fMoreParams = FALSE;
|
|||
|
break;
|
|||
|
|
|||
|
case FC_IN_PARAM_BASETYPE :
|
|||
|
|
|||
|
LENGTH_ALIGN( pStubMsg->BufferLength,
|
|||
|
SIMPLE_TYPE_ALIGNMENT( pProcFormat[1] ));
|
|||
|
pStubMsg->BufferLength +=
|
|||
|
SIMPLE_TYPE_BUFSIZE( pProcFormat[1] );
|
|||
|
break;
|
|||
|
|
|||
|
case FC_IN_PARAM:
|
|||
|
case FC_IN_PARAM_NO_FREE_INST:
|
|||
|
|
|||
|
// Other [in] types than simple or ignore
|
|||
|
// fall through to [in,out].
|
|||
|
|
|||
|
case FC_IN_OUT_PARAM:
|
|||
|
{
|
|||
|
uchar * pOrigArg = *(uchar * *)pArg;
|
|||
|
PFORMAT_STRING pTypeFormat;
|
|||
|
unsigned char FcType;
|
|||
|
|
|||
|
|
|||
|
pProcFormat += 2;
|
|||
|
pTypeFormat = pStubDesc->pFormatTypes +
|
|||
|
*(signed short *) pProcFormat;
|
|||
|
FcType = *pTypeFormat;
|
|||
|
|
|||
|
if ( ! IS_BY_VALUE( FcType ) )
|
|||
|
pOrigArg = *(uchar * *)pOrigArg;
|
|||
|
|
|||
|
(*pfnSizeRoutines[ ROUTINE_INDEX( FcType ) ])( pStubMsg,
|
|||
|
pOrigArg,
|
|||
|
pTypeFormat );
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
GET_NEXT_ARG( pArg, ArgList );
|
|||
|
} // for
|
|||
|
|
|||
|
LENGTH_ALIGN( pStubMsg->BufferLength, 7 );
|
|||
|
|
|||
|
size_t LengthSaved;
|
|||
|
|
|||
|
NdrpAllocPicklingBuffer( pMesMsg, pStubMsg->BufferLength );
|
|||
|
BufferSaved = pStubMsg->Buffer;
|
|||
|
LengthSaved = pStubMsg->BufferLength;
|
|||
|
|
|||
|
//
|
|||
|
// Marshalling.
|
|||
|
//
|
|||
|
|
|||
|
NdrpProcHeaderMarshall( pMesMsg );
|
|||
|
|
|||
|
INIT_ARG( ArgList, pFormat );
|
|||
|
GET_FIRST_ARG( pArg, ArgList );
|
|||
|
|
|||
|
pProcFormat = pFormat;
|
|||
|
fMoreParams = TRUE;
|
|||
|
|
|||
|
for ( ; fMoreParams ; pProcFormat += 2 )
|
|||
|
{
|
|||
|
switch ( *pProcFormat )
|
|||
|
{
|
|||
|
case FC_OUT_PARAM:
|
|||
|
break;
|
|||
|
|
|||
|
case FC_RETURN_PARAM:
|
|||
|
default:
|
|||
|
fMoreParams = FALSE;
|
|||
|
break;
|
|||
|
|
|||
|
case FC_IN_PARAM_BASETYPE :
|
|||
|
|
|||
|
NdrSimpleTypeMarshall( pStubMsg,
|
|||
|
*(uchar * *)pArg,
|
|||
|
pProcFormat[1] );
|
|||
|
break;
|
|||
|
|
|||
|
case FC_IN_PARAM:
|
|||
|
case FC_IN_PARAM_NO_FREE_INST:
|
|||
|
case FC_IN_OUT_PARAM:
|
|||
|
{
|
|||
|
uchar * pOrigArg = *(uchar * *)pArg;
|
|||
|
PFORMAT_STRING pTypeFormat;
|
|||
|
unsigned char FcType;
|
|||
|
|
|||
|
pProcFormat += 2;
|
|||
|
pTypeFormat = pStubDesc->pFormatTypes +
|
|||
|
*(signed short *) pProcFormat;
|
|||
|
FcType = *pTypeFormat;
|
|||
|
|
|||
|
if ( ! IS_BY_VALUE( FcType ) )
|
|||
|
pOrigArg = *(uchar * *)pOrigArg;
|
|||
|
|
|||
|
(*pfnMarshallRoutines[ ROUTINE_INDEX( FcType )])( pStubMsg,
|
|||
|
pOrigArg,
|
|||
|
pTypeFormat );
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
GET_NEXT_ARG( pArg, ArgList );
|
|||
|
}
|
|||
|
|
|||
|
// Next encoding (if any) starts at aligned to 8.
|
|||
|
|
|||
|
ALIGN( pStubMsg->Buffer, 7 );
|
|||
|
|
|||
|
// Now manage the actual size of encoded data.
|
|||
|
|
|||
|
WriteLength = (size_t)(pStubMsg->Buffer - BufferSaved);
|
|||
|
* (unsigned long *)
|
|||
|
( BufferSaved + MES_PROC_HEADER_SIZE - 4) =
|
|||
|
WriteLength - MES_PROC_HEADER_SIZE;
|
|||
|
|
|||
|
if ( LengthSaved < WriteLength )
|
|||
|
{
|
|||
|
NDR_ASSERT( 0, "NdrMesProcEncodeDecode: encode buffer overflow" );
|
|||
|
RpcRaiseException( RPC_S_INTERNAL_ERROR );
|
|||
|
}
|
|||
|
|
|||
|
NdrpWritePicklingBuffer( pMesMsg, BufferSaved, WriteLength );
|
|||
|
}
|
|||
|
|
|||
|
if ( fDecodeUsed )
|
|||
|
{
|
|||
|
//
|
|||
|
// Unmarshalling.
|
|||
|
//
|
|||
|
|
|||
|
if ( GET_MES_HEADER_PEEKED( pMesMsg ) )
|
|||
|
{
|
|||
|
// This makes it possible to encode/decode several procs one after
|
|||
|
// another with the same pickling handle (using the same buffer).
|
|||
|
|
|||
|
CLEAR_MES_HEADER_PEEKED( pMesMsg );
|
|||
|
}
|
|||
|
else
|
|||
|
NdrpProcHeaderUnmarshall( pMesMsg );
|
|||
|
|
|||
|
NdrpDataBufferInit( pMesMsg, pFormat );
|
|||
|
|
|||
|
INIT_ARG( ArgList, pFormat );
|
|||
|
GET_FIRST_ARG( pArg, ArgList );
|
|||
|
|
|||
|
pStubMsg->StackTop = *(uchar * *)pArg;
|
|||
|
pProcFormat = pFormat;
|
|||
|
fMoreParams = TRUE;
|
|||
|
|
|||
|
for ( ; fMoreParams ; pProcFormat += 2 )
|
|||
|
{
|
|||
|
switch ( *pProcFormat )
|
|||
|
{
|
|||
|
case FC_IN_PARAM_BASETYPE :
|
|||
|
case FC_IN_PARAM:
|
|||
|
case FC_IN_PARAM_NO_FREE_INST:
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
fMoreParams = FALSE;
|
|||
|
break;
|
|||
|
|
|||
|
case FC_RETURN_PARAM_BASETYPE :
|
|||
|
|
|||
|
NdrSimpleTypeUnmarshall( pStubMsg,
|
|||
|
*(uchar * *)pArg,
|
|||
|
pProcFormat[1] );
|
|||
|
fMoreParams = FALSE;
|
|||
|
break;
|
|||
|
|
|||
|
case FC_RETURN_PARAM:
|
|||
|
fMoreParams = FALSE;
|
|||
|
|
|||
|
// fall through to out params.
|
|||
|
|
|||
|
case FC_IN_OUT_PARAM:
|
|||
|
case FC_OUT_PARAM:
|
|||
|
{
|
|||
|
uchar * pOrigArg = *(uchar * *)pArg;
|
|||
|
PFORMAT_STRING pTypeFormat;
|
|||
|
unsigned char FcType;
|
|||
|
|
|||
|
pProcFormat += 2;
|
|||
|
pTypeFormat = pStubDesc->pFormatTypes +
|
|||
|
*(signed short *) pProcFormat;
|
|||
|
FcType = *pTypeFormat;
|
|||
|
|
|||
|
if ( IS_STRUCT( FcType ) || IS_UNION( FcType) ||
|
|||
|
IS_XMIT_AS( FcType ) )
|
|||
|
{
|
|||
|
// All these are possible only as a return value.
|
|||
|
pOrigArg = (uchar *) &pOrigArg;
|
|||
|
}
|
|||
|
else
|
|||
|
pOrigArg = (uchar *)pOrigArg;
|
|||
|
|
|||
|
(*pfnUnmarshallRoutines[ ROUTINE_INDEX( FcType )])(
|
|||
|
pStubMsg,
|
|||
|
(uchar * *)pOrigArg,
|
|||
|
pTypeFormat,
|
|||
|
FALSE );
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
GET_NEXT_ARG( pArg, ArgList );
|
|||
|
} // for
|
|||
|
|
|||
|
// Next decoding (if any) starts at aligned to 8.
|
|||
|
|
|||
|
ALIGN( pStubMsg->Buffer, 7 );
|
|||
|
|
|||
|
} // if decode
|
|||
|
|
|||
|
NdrFullPointerXlatFree( pStubMsg->FullPtrXlatTables );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
CLIENT_CALL_RETURN RPC_VAR_ENTRY
|
|||
|
NdrMesProcEncodeDecode2(
|
|||
|
handle_t Handle,
|
|||
|
const MIDL_STUB_DESC * pStubDescriptor,
|
|||
|
PFORMAT_STRING pFormat,
|
|||
|
...
|
|||
|
)
|
|||
|
{
|
|||
|
va_list ArgList;
|
|||
|
uchar * StartofStack;
|
|||
|
PFORMAT_STRING pFormatParam;
|
|||
|
CLIENT_CALL_RETURN ReturnValue;
|
|||
|
ulong ProcNum;
|
|||
|
uchar * pArg;
|
|||
|
void * pThis;
|
|||
|
PFORMAT_STRING pProcFormat = pFormat;
|
|||
|
unsigned char * BufferSaved;
|
|||
|
size_t WriteLength;
|
|||
|
NDR_PROC_CONTEXT ProcContext;
|
|||
|
PNDR_PROC_HEADER_EXTS pHeaderExts = 0;
|
|||
|
|
|||
|
ReturnValue.Pointer = 0;
|
|||
|
|
|||
|
//
|
|||
|
// Get address of argument to this function following pFormat. This
|
|||
|
// is the address of the address of the first argument of the function
|
|||
|
// calling this function.
|
|||
|
//
|
|||
|
INIT_ARG( ArgList, pFormat);
|
|||
|
|
|||
|
//
|
|||
|
// Get the address of the stack where the parameters are.
|
|||
|
//
|
|||
|
GET_FIRST_IN_ARG(ArgList);
|
|||
|
StartofStack = (uchar *) GET_STACK_START(ArgList);
|
|||
|
|
|||
|
// StartofStack points to the virtual stack at this point.
|
|||
|
|
|||
|
NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|||
|
|
|||
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = & pMesMsg->StubMsg;
|
|||
|
|
|||
|
NDR_ASSERT( *pFormat == FC_BIND_PRIMITIVE || *pFormat == 0,
|
|||
|
"Pickling handle expected" );
|
|||
|
|
|||
|
pStubMsg->StubDesc = pStubDescriptor;
|
|||
|
pStubMsg->pfnAllocate = pStubDescriptor->pfnAllocate;
|
|||
|
pStubMsg->pfnFree = pStubDescriptor->pfnFree;
|
|||
|
|
|||
|
ProcNum = MulNdrpInitializeContextFromProc( XFER_SYNTAX_DCE, pFormat, &ProcContext, StartofStack );
|
|||
|
|
|||
|
BOOL fEncodeUsed = ( * ( ( uchar *)&ProcContext.NdrInfo.InterpreterFlags ) & ENCODE_IS_USED ) &&
|
|||
|
pMesMsg->Operation == MES_ENCODE;
|
|||
|
BOOL fDecodeUsed = ( * ( ( uchar *)&ProcContext.NdrInfo.InterpreterFlags ) & DECODE_IS_USED ) &&
|
|||
|
pMesMsg->Operation == MES_DECODE;
|
|||
|
|
|||
|
NDR_ASSERT( !( fEncodeUsed && fDecodeUsed ),
|
|||
|
"Both encode & decode at the same time" );
|
|||
|
|
|||
|
if ( !fEncodeUsed && !fDecodeUsed )
|
|||
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|||
|
|
|||
|
if ( fEncodeUsed )
|
|||
|
pMesMsg->ProcNumber = ProcNum;
|
|||
|
|
|||
|
|
|||
|
// Must do this before the sizing pass!
|
|||
|
pStubMsg->StackTop = StartofStack;
|
|||
|
pStubMsg->pContext = &ProcContext;
|
|||
|
|
|||
|
RpcTryFinally
|
|||
|
{
|
|||
|
|
|||
|
// We don't really need to zeroout here, but code is much more cleaner this way,
|
|||
|
// and ObjectProc is the first check anyhow.
|
|||
|
NdrpClientInit( pStubMsg, &ReturnValue );
|
|||
|
if (fEncodeUsed)
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// ----------------------------------------------------------------
|
|||
|
// Sizing Pass.
|
|||
|
// ----------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
pStubMsg->BufferLength += MES_PROC_HEADER_SIZE;
|
|||
|
|
|||
|
//
|
|||
|
// Skip buffer size pass if possible.
|
|||
|
//
|
|||
|
if ( ProcContext.NdrInfo.pProcDesc->Oi2Flags.ClientMustSize )
|
|||
|
{
|
|||
|
NdrpSizing( pStubMsg,
|
|||
|
TRUE ); // IsClient
|
|||
|
}
|
|||
|
|
|||
|
LENGTH_ALIGN( pStubMsg->BufferLength, 7 );
|
|||
|
|
|||
|
size_t LengthSaved;
|
|||
|
|
|||
|
NdrpAllocPicklingBuffer( pMesMsg, pStubMsg->BufferLength );
|
|||
|
BufferSaved = pStubMsg->Buffer;
|
|||
|
LengthSaved = pStubMsg->BufferLength;
|
|||
|
|
|||
|
NdrpProcHeaderMarshall( pMesMsg );
|
|||
|
|
|||
|
//
|
|||
|
// ----------------------------------------------------------
|
|||
|
// Marshall Pass.
|
|||
|
// ----------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
NdrpClientMarshal( pStubMsg,
|
|||
|
FALSE ); // IsObject
|
|||
|
|
|||
|
|
|||
|
// Next encoding (if any) starts at aligned to 8.
|
|||
|
|
|||
|
ALIGN( pStubMsg->Buffer, 7 );
|
|||
|
|
|||
|
// Now manage the actual size of encoded data.
|
|||
|
|
|||
|
WriteLength = (size_t)(pStubMsg->Buffer - BufferSaved);
|
|||
|
* (unsigned long *) ( BufferSaved + MES_PROC_HEADER_SIZE - 4) =
|
|||
|
WriteLength - MES_PROC_HEADER_SIZE;
|
|||
|
|
|||
|
if ( LengthSaved < WriteLength )
|
|||
|
{
|
|||
|
NDR_ASSERT( 0, "NdrMesProcEncodeDecode: encode buffer overflow" );
|
|||
|
RpcRaiseException( RPC_S_INTERNAL_ERROR );
|
|||
|
}
|
|||
|
|
|||
|
NdrpWritePicklingBuffer( pMesMsg, BufferSaved, WriteLength );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (fDecodeUsed)
|
|||
|
{
|
|||
|
//
|
|||
|
// ----------------------------------------------------------
|
|||
|
// Unmarshall Pass.
|
|||
|
// ----------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
if ( GET_MES_HEADER_PEEKED( pMesMsg ) )
|
|||
|
{
|
|||
|
// This makes it possible to encode/decode several procs one after
|
|||
|
// another with the same pickling handle (using the same buffer).
|
|||
|
|
|||
|
CLEAR_MES_HEADER_PEEKED( pMesMsg );
|
|||
|
}
|
|||
|
else
|
|||
|
NdrpProcHeaderUnmarshall( pMesMsg );
|
|||
|
|
|||
|
NdrpDataBufferInit( pMesMsg, pFormat );
|
|||
|
|
|||
|
NdrpClientUnMarshal( pStubMsg,
|
|||
|
&ReturnValue );
|
|||
|
|
|||
|
// Next decoding (if any) starts at aligned to 8.
|
|||
|
|
|||
|
ALIGN( pStubMsg->Buffer, 7 );
|
|||
|
|
|||
|
} // if decode
|
|||
|
|
|||
|
}
|
|||
|
RpcFinally
|
|||
|
{
|
|||
|
|
|||
|
NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables);
|
|||
|
|
|||
|
NdrCorrelationFree( pStubMsg );
|
|||
|
}
|
|||
|
RpcEndFinally
|
|||
|
|
|||
|
return ReturnValue;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// =======================================================================
|
|||
|
//
|
|||
|
// Generic type pickling routines (for non-simple types).
|
|||
|
//
|
|||
|
// =======================================================================
|
|||
|
|
|||
|
void
|
|||
|
NdrpCommonTypeHeaderSize(
|
|||
|
PMIDL_ES_MESSAGE pMesMsg
|
|||
|
)
|
|||
|
{
|
|||
|
// This check is to prevent a decoding handle from being used
|
|||
|
// for both encoding and sizing of types.
|
|||
|
|
|||
|
if ( pMesMsg->Operation != MES_ENCODE )
|
|||
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|||
|
|
|||
|
if ( ! GET_COMMON_TYPE_HEADER_SIZED( pMesMsg ) )
|
|||
|
{
|
|||
|
pMesMsg->StubMsg.BufferLength += MES_CTYPE_HEADER_SIZE;
|
|||
|
|
|||
|
SET_COMMON_TYPE_HEADER_SIZED( pMesMsg );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
size_t RPC_ENTRY
|
|||
|
NdrMesTypeAlignSize2(
|
|||
|
handle_t Handle,
|
|||
|
const MIDL_TYPE_PICKLING_INFO * pxPicklingInfo,
|
|||
|
const MIDL_STUB_DESC * pStubDesc,
|
|||
|
PFORMAT_STRING pFormat,
|
|||
|
const void * pObject
|
|||
|
)
|
|||
|
{
|
|||
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
PMIDL_TYPE_PICKLING_INFOp pPicklingInfo;
|
|||
|
|
|||
|
pPicklingInfo = (PMIDL_TYPE_PICKLING_INFOp) pxPicklingInfo;
|
|||
|
|
|||
|
NDR_ASSERT( pPicklingInfo->Flags.Oicf, "Oicf should always be on" )
|
|||
|
|
|||
|
pStubMsg->fHasExtensions = 1;
|
|||
|
|
|||
|
if ( pPicklingInfo->Flags.HasNewCorrDesc )
|
|||
|
{
|
|||
|
void * pCorrInfo = alloca( NDR_DEFAULT_CORR_CACHE_SIZE );
|
|||
|
|
|||
|
NdrCorrelationInitialize( pStubMsg,
|
|||
|
(unsigned long *) pCorrInfo,
|
|||
|
NDR_DEFAULT_CORR_CACHE_SIZE,
|
|||
|
0 /* flags */ );
|
|||
|
}
|
|||
|
|
|||
|
return NdrMesTypeAlignSize(Handle, pStubDesc, pFormat, pObject);
|
|||
|
}
|
|||
|
|
|||
|
size_t RPC_ENTRY
|
|||
|
NdrMesTypeAlignSize(
|
|||
|
handle_t Handle,
|
|||
|
const MIDL_STUB_DESC * pStubDesc,
|
|||
|
PFORMAT_STRING pFormat,
|
|||
|
const void * pObject
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine description:
|
|||
|
|
|||
|
Calculates the buffer size of the object relative to the current state
|
|||
|
of the pickling handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Handle - a pickling handle,
|
|||
|
pStubDesc - a pointer to the stub descriptor,
|
|||
|
pFormat - a pointer to the format code describing the object type
|
|||
|
pObject - a pointer to the object being sized.
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
The size.
|
|||
|
|
|||
|
Note:
|
|||
|
|
|||
|
The pickling header is included in the sizing.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|||
|
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &((PMIDL_ES_MESSAGE)Handle)->StubMsg;
|
|||
|
size_t OldLength = pStubMsg->BufferLength;
|
|||
|
|
|||
|
if ( ! pObject )
|
|||
|
RpcRaiseException( RPC_X_NULL_REF_POINTER );
|
|||
|
|
|||
|
if( (long)pStubMsg->BufferLength & 0x7 )
|
|||
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|||
|
|
|||
|
pStubMsg->StubDesc = pStubDesc;
|
|||
|
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
|||
|
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
|||
|
|
|||
|
// See if we need to size the common type header.
|
|||
|
|
|||
|
NdrpCommonTypeHeaderSize( (PMIDL_ES_MESSAGE)Handle );
|
|||
|
|
|||
|
// Now the individual type object.
|
|||
|
|
|||
|
pStubMsg->BufferLength += MES_HEADER_SIZE;
|
|||
|
|
|||
|
if ( IS_POINTER_TYPE(*pFormat) )
|
|||
|
{
|
|||
|
// We have to dereference the pointer once.
|
|||
|
pObject = *(void * *)pObject;
|
|||
|
}
|
|||
|
|
|||
|
(*pfnSizeRoutines[ ROUTINE_INDEX(*pFormat) ])
|
|||
|
( pStubMsg,
|
|||
|
(uchar *)pObject,
|
|||
|
pFormat );
|
|||
|
|
|||
|
LENGTH_ALIGN( pStubMsg->BufferLength, 7 );
|
|||
|
|
|||
|
return( pStubMsg->BufferLength - OldLength );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
size_t
|
|||
|
NdrpCommonTypeHeaderMarshall(
|
|||
|
PMIDL_ES_MESSAGE pMesMsg
|
|||
|
)
|
|||
|
/*++
|
|||
|
Returns the space used by the common header.
|
|||
|
--*/
|
|||
|
{
|
|||
|
if ( ! GET_COMMON_TYPE_HEADER_IN( pMesMsg ) )
|
|||
|
{
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
|
|||
|
MIDL_memset( pStubMsg->Buffer, 0xcc, MES_CTYPE_HEADER_SIZE );
|
|||
|
|
|||
|
*pStubMsg->Buffer++ = MIDL_ES_VERSION;
|
|||
|
*pStubMsg->Buffer++ = NDR_LOCAL_ENDIAN;
|
|||
|
* PSHORT_CAST pStubMsg->Buffer = MES_CTYPE_HEADER_SIZE;
|
|||
|
|
|||
|
pStubMsg->Buffer += MES_CTYPE_HEADER_SIZE - 2;
|
|||
|
|
|||
|
SET_COMMON_TYPE_HEADER_IN( pMesMsg );
|
|||
|
return( MES_CTYPE_HEADER_SIZE );
|
|||
|
}
|
|||
|
|
|||
|
return( 0 );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrMesTypeEncode2(
|
|||
|
handle_t Handle,
|
|||
|
const MIDL_TYPE_PICKLING_INFO * pxPicklingInfo,
|
|||
|
const MIDL_STUB_DESC * pStubDesc,
|
|||
|
PFORMAT_STRING pFormat,
|
|||
|
const void * pObject
|
|||
|
)
|
|||
|
{
|
|||
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
PMIDL_TYPE_PICKLING_INFOp pPicklingInfo;
|
|||
|
|
|||
|
pPicklingInfo = (PMIDL_TYPE_PICKLING_INFOp) pxPicklingInfo;
|
|||
|
|
|||
|
NDR_ASSERT( pPicklingInfo->Flags.Oicf, "Oicf should always be on" )
|
|||
|
|
|||
|
pStubMsg->fHasExtensions = 1;
|
|||
|
|
|||
|
if ( pPicklingInfo->Flags.HasNewCorrDesc )
|
|||
|
{
|
|||
|
void * pCorrInfo = alloca( NDR_DEFAULT_CORR_CACHE_SIZE );
|
|||
|
|
|||
|
NdrCorrelationInitialize( pStubMsg,
|
|||
|
(unsigned long *) pCorrInfo,
|
|||
|
NDR_DEFAULT_CORR_CACHE_SIZE,
|
|||
|
0 /* flags */ );
|
|||
|
}
|
|||
|
RpcTryFinally
|
|||
|
{
|
|||
|
NdrMesTypeEncode(Handle, pStubDesc, pFormat, pObject);
|
|||
|
if ( pStubMsg->pCorrInfo )
|
|||
|
NdrCorrelationPass( pStubMsg );
|
|||
|
}
|
|||
|
RpcFinally
|
|||
|
{
|
|||
|
// while currently we are not using corrinfo in marshalling pass, we need this
|
|||
|
// in case we are using corrinfo later (like info for free)
|
|||
|
NdrCorrelationFree( pStubMsg );
|
|||
|
}
|
|||
|
RpcEndFinally
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrMesTypeEncode(
|
|||
|
handle_t Handle,
|
|||
|
const MIDL_STUB_DESC * pStubDesc,
|
|||
|
PFORMAT_STRING pFormat,
|
|||
|
const void * pObject
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine description:
|
|||
|
|
|||
|
Encodes the object to the buffer depending on the state of the handle.
|
|||
|
This means: sizing, allocating buffer, marshalling, writing buffer.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Handle - a pickling handle
|
|||
|
pStubDesc - a pointer to the stub descriptor,
|
|||
|
pFormat - a pointer to the format code describing the object type,
|
|||
|
pObject - a pointer to the object being sized.
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
The size.
|
|||
|
|
|||
|
Note:
|
|||
|
|
|||
|
The pickling header is included in the sizing.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|||
|
|
|||
|
uchar * pBufferSaved;
|
|||
|
size_t RequiredLen, CommonHeaderSize, LengthSaved;
|
|||
|
|
|||
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
|
|||
|
if ( ! pObject )
|
|||
|
RpcRaiseException( RPC_X_NULL_REF_POINTER );
|
|||
|
|
|||
|
if( (LONG_PTR)pStubMsg->Buffer & 0x7 )
|
|||
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|||
|
|
|||
|
pStubMsg->StubDesc = pStubDesc;
|
|||
|
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
|||
|
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
|||
|
|
|||
|
// Size and allocate the buffer.
|
|||
|
// The req len includes: (the common header), the header and the data
|
|||
|
|
|||
|
// Take the pointer alignment to come up with the right size.
|
|||
|
|
|||
|
pStubMsg->BufferLength = 0xf & PtrToUlong( pStubMsg->Buffer );
|
|||
|
|
|||
|
RequiredLen = NdrMesTypeAlignSize( Handle,
|
|||
|
pStubDesc,
|
|||
|
pFormat,
|
|||
|
pObject );
|
|||
|
|
|||
|
NdrpAllocPicklingBuffer( pMesMsg, RequiredLen );
|
|||
|
|
|||
|
pBufferSaved = pStubMsg->Buffer;
|
|||
|
LengthSaved = RequiredLen;
|
|||
|
|
|||
|
// See if we need to marshall the common type header
|
|||
|
|
|||
|
CommonHeaderSize = NdrpCommonTypeHeaderMarshall( pMesMsg );
|
|||
|
|
|||
|
// Marshall the header and the object.
|
|||
|
|
|||
|
// zero out the type header (will contain type buffer length after
|
|||
|
// encoding is done )
|
|||
|
memset( pStubMsg->Buffer, 0, MES_HEADER_SIZE );
|
|||
|
pStubMsg->Buffer += MES_HEADER_SIZE;
|
|||
|
|
|||
|
if ( IS_POINTER_TYPE(*pFormat) )
|
|||
|
{
|
|||
|
// We have to dereference the pointer once.
|
|||
|
pObject = *(void * *)pObject;
|
|||
|
}
|
|||
|
|
|||
|
(*pfnMarshallRoutines[ ROUTINE_INDEX(*pFormat) ])
|
|||
|
( pStubMsg,
|
|||
|
(uchar *)pObject,
|
|||
|
pFormat );
|
|||
|
|
|||
|
// We adjust the buffer to the next align by 8 and
|
|||
|
// so, we tell the user that we've written out till next mod 8.
|
|||
|
|
|||
|
ALIGN( pStubMsg->Buffer, 7 );
|
|||
|
size_t WriteLength = (size_t)(pStubMsg->Buffer - pBufferSaved);
|
|||
|
|
|||
|
// We always save the rounded up object length in the type header.
|
|||
|
|
|||
|
*(unsigned long *)(pBufferSaved + CommonHeaderSize) =
|
|||
|
WriteLength - CommonHeaderSize - MES_HEADER_SIZE;
|
|||
|
|
|||
|
if ( LengthSaved < WriteLength )
|
|||
|
{
|
|||
|
NDR_ASSERT( 0, "NdrMesTypeEncode: encode buffer overflow" );
|
|||
|
RpcRaiseException( RPC_S_INTERNAL_ERROR );
|
|||
|
}
|
|||
|
|
|||
|
NdrpWritePicklingBuffer( pMesMsg, pBufferSaved, WriteLength );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
NdrpCommonTypeHeaderUnmarshall(
|
|||
|
PMIDL_ES_MESSAGE pMesMsg
|
|||
|
)
|
|||
|
{
|
|||
|
if ( pMesMsg->Operation != MES_DECODE )
|
|||
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|||
|
|
|||
|
if ( ! GET_COMMON_TYPE_HEADER_IN( pMesMsg ) )
|
|||
|
{
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
|
|||
|
NdrpReadPicklingBuffer( pMesMsg, MES_CTYPE_HEADER_SIZE );
|
|||
|
|
|||
|
// Check the version number, endianness.
|
|||
|
|
|||
|
if ( *pStubMsg->Buffer != MIDL_ES_VERSION )
|
|||
|
RpcRaiseException( RPC_X_WRONG_ES_VERSION );
|
|||
|
|
|||
|
if ( pStubMsg->Buffer[1] == NDR_LOCAL_ENDIAN )
|
|||
|
{
|
|||
|
// Read the note about endianess at NdrMesTypeDecode.
|
|||
|
//
|
|||
|
pMesMsg->AlienDataRep = NDR_LOCAL_DATA_REPRESENTATION;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
unsigned char temp = pStubMsg->Buffer[2];
|
|||
|
pStubMsg->Buffer[2] = pStubMsg->Buffer[3];
|
|||
|
pStubMsg->Buffer[3] = temp;
|
|||
|
|
|||
|
pMesMsg->AlienDataRep = ( NDR_ASCII_CHAR | // chars
|
|||
|
pStubMsg->Buffer[1] | // endianness
|
|||
|
NDR_IEEE_FLOAT ); // float
|
|||
|
}
|
|||
|
|
|||
|
pStubMsg->Buffer += MES_CTYPE_HEADER_SIZE;
|
|||
|
|
|||
|
SET_COMMON_TYPE_HEADER_IN( pMesMsg );
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrMesTypeDecode2(
|
|||
|
handle_t Handle,
|
|||
|
const MIDL_TYPE_PICKLING_INFO * pxPicklingInfo,
|
|||
|
const MIDL_STUB_DESC * pStubDesc,
|
|||
|
PFORMAT_STRING pFormat,
|
|||
|
void * pObject
|
|||
|
)
|
|||
|
{
|
|||
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
PMIDL_TYPE_PICKLING_INFOp pPicklingInfo;
|
|||
|
|
|||
|
pPicklingInfo = (PMIDL_TYPE_PICKLING_INFOp) pxPicklingInfo;
|
|||
|
|
|||
|
NDR_ASSERT( pPicklingInfo->Flags.Oicf, "Oicf should always be on" )
|
|||
|
|
|||
|
pStubMsg->fHasExtensions = 1;
|
|||
|
RpcTryFinally
|
|||
|
{
|
|||
|
|
|||
|
if ( pPicklingInfo->Flags.HasNewCorrDesc )
|
|||
|
{
|
|||
|
void * pCorrInfo = alloca( NDR_DEFAULT_CORR_CACHE_SIZE );
|
|||
|
|
|||
|
NdrCorrelationInitialize( pStubMsg,
|
|||
|
(unsigned long *) pCorrInfo,
|
|||
|
NDR_DEFAULT_CORR_CACHE_SIZE,
|
|||
|
0 /* flags */ );
|
|||
|
}
|
|||
|
|
|||
|
NdrMesTypeDecode(Handle, pStubDesc, pFormat, pObject);
|
|||
|
if ( pStubMsg->pCorrInfo )
|
|||
|
NdrCorrelationPass( pStubMsg );
|
|||
|
}
|
|||
|
RpcFinally
|
|||
|
{
|
|||
|
NdrCorrelationFree( pStubMsg );
|
|||
|
}
|
|||
|
RpcEndFinally
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrMesTypeDecode(
|
|||
|
handle_t Handle,
|
|||
|
const MIDL_STUB_DESC * pStubDesc,
|
|||
|
PFORMAT_STRING pFormat,
|
|||
|
void * pObject
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine description:
|
|||
|
|
|||
|
Decodes the object to the buffer depending on the state of the handle.
|
|||
|
This means: reads the header, reads the buffer, unmarshalls.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Handle - a pickling handle
|
|||
|
pStubDesc - a pointer to the stub descriptor,
|
|||
|
pFormat - a pointer to the format code describing the object type,
|
|||
|
pObject - a pointer to the object being sized.
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
The size.
|
|||
|
|
|||
|
Note:
|
|||
|
|
|||
|
Endianness and other conversions when decoding *types*.
|
|||
|
Starting with Mac implementation, types have a conversion that
|
|||
|
takes care of different endianness. ASCII and VAX_FLOAT are still
|
|||
|
assummed for types.
|
|||
|
Common header conveys the endianness information. The handle gets the
|
|||
|
endian info from the common header and so when decoding types, the
|
|||
|
handle is used to check if the conversion is needed.
|
|||
|
|
|||
|
We cannot convert the whole buffer at the time of processing the common
|
|||
|
header as the buffer may not be there yet (for incremental handle).
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|||
|
|
|||
|
size_t RequiredLen;
|
|||
|
|
|||
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
uchar * BufferSaved;
|
|||
|
|
|||
|
if ( ! pObject )
|
|||
|
RpcRaiseException( RPC_X_NULL_REF_POINTER );
|
|||
|
|
|||
|
pStubMsg->StubDesc = pStubDesc;
|
|||
|
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
|||
|
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
|||
|
|
|||
|
// See if we need to unmarshall the common type header.
|
|||
|
|
|||
|
NdrpCommonTypeHeaderUnmarshall( pMesMsg );
|
|||
|
|
|||
|
// Now the individual data object.
|
|||
|
|
|||
|
NdrpReadPicklingBuffer( pMesMsg, MES_HEADER_SIZE );
|
|||
|
|
|||
|
// Reading the object. Get the length of the buffer first.
|
|||
|
|
|||
|
if ( pMesMsg->AlienDataRep != NDR_LOCAL_DATA_REPRESENTATION )
|
|||
|
{
|
|||
|
pStubMsg->RpcMsg->DataRepresentation = pMesMsg->AlienDataRep;
|
|||
|
|
|||
|
BufferSaved = pStubMsg->Buffer;
|
|||
|
NdrSimpleTypeConvert( pStubMsg, FC_LONG );
|
|||
|
pStubMsg->Buffer = BufferSaved;
|
|||
|
}
|
|||
|
|
|||
|
RequiredLen = (size_t) *(unsigned long *)pStubMsg->Buffer;
|
|||
|
pStubMsg->Buffer += MES_HEADER_SIZE;
|
|||
|
|
|||
|
NdrpReadPicklingBuffer( pMesMsg, RequiredLen );
|
|||
|
|
|||
|
// Now the conversion of the object, if needed.
|
|||
|
|
|||
|
if ( pMesMsg->AlienDataRep != NDR_LOCAL_DATA_REPRESENTATION )
|
|||
|
{
|
|||
|
BufferSaved = pStubMsg->Buffer;
|
|||
|
(*pfnConvertRoutines[ ROUTINE_INDEX( *pFormat) ])
|
|||
|
( pStubMsg,
|
|||
|
pFormat,
|
|||
|
FALSE );
|
|||
|
pStubMsg->Buffer = BufferSaved;
|
|||
|
}
|
|||
|
|
|||
|
// Unmarshalling.
|
|||
|
|
|||
|
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
|||
|
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
|||
|
|
|||
|
void * pArg = pObject;
|
|||
|
|
|||
|
if ( IS_POINTER_TYPE(*pFormat) )
|
|||
|
{
|
|||
|
// We have to dereference the pointer once.
|
|||
|
//
|
|||
|
pArg = *(void **)pArg;
|
|||
|
}
|
|||
|
|
|||
|
(*pfnUnmarshallRoutines[ ROUTINE_INDEX( *pFormat )])
|
|||
|
( pStubMsg,
|
|||
|
(uchar * *)&pArg,
|
|||
|
pFormat,
|
|||
|
FALSE );
|
|||
|
|
|||
|
if ( IS_POINTER_TYPE(*pFormat) )
|
|||
|
{
|
|||
|
// Don't drop the pointee, if it was allocated.
|
|||
|
|
|||
|
*(void **)pObject = pArg;
|
|||
|
}
|
|||
|
|
|||
|
// Next decoding needs to start at aligned to 8.
|
|||
|
|
|||
|
ALIGN( pStubMsg->Buffer, 7 );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrMesTypeFree(
|
|||
|
handle_t Handle,
|
|||
|
const MIDL_STUB_DESC * pStubDesc,
|
|||
|
PFORMAT_STRING pFormat,
|
|||
|
void * pObject
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine description:
|
|||
|
|
|||
|
Free the object.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Handle - a pickling handle,
|
|||
|
pStubDesc - a pointer to the stub descriptor,
|
|||
|
pFormat - a pointer to the format code describing the object type
|
|||
|
pObject - a pointer to the object being freed.
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Note:
|
|||
|
|
|||
|
The pickling header is included in the sizing.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|||
|
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &((PMIDL_ES_MESSAGE)Handle)->StubMsg;
|
|||
|
|
|||
|
if ( ! pObject )
|
|||
|
RpcRaiseException( RPC_X_NULL_REF_POINTER );
|
|||
|
|
|||
|
if( (LONG_PTR)pStubMsg->Buffer & 0x7 )
|
|||
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|||
|
|
|||
|
pStubMsg->StubDesc = pStubDesc;
|
|||
|
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
|||
|
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
|||
|
|
|||
|
// Now the individual type object.
|
|||
|
|
|||
|
if ( IS_POINTER_TYPE(*pFormat) )
|
|||
|
{
|
|||
|
// We have to dereference the pointer once.
|
|||
|
pObject = *(void * *)pObject;
|
|||
|
}
|
|||
|
|
|||
|
(*pfnFreeRoutines[ ROUTINE_INDEX(*pFormat) ])
|
|||
|
( pStubMsg,
|
|||
|
(uchar *)pObject,
|
|||
|
pFormat );
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrMesTypeFree2(
|
|||
|
handle_t Handle,
|
|||
|
const MIDL_TYPE_PICKLING_INFO * pxPicklingInfo,
|
|||
|
const MIDL_STUB_DESC * pStubDesc,
|
|||
|
PFORMAT_STRING pFormat,
|
|||
|
void * pObject
|
|||
|
)
|
|||
|
{
|
|||
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
PMIDL_TYPE_PICKLING_INFOp pPicklingInfo;
|
|||
|
|
|||
|
pPicklingInfo = (PMIDL_TYPE_PICKLING_INFOp) pxPicklingInfo;
|
|||
|
|
|||
|
NDR_ASSERT( pPicklingInfo->Flags.Oicf, "Oicf should always be on" )
|
|||
|
|
|||
|
pStubMsg->fHasExtensions = 1;
|
|||
|
|
|||
|
if ( pPicklingInfo->Flags.HasNewCorrDesc )
|
|||
|
{
|
|||
|
void * pCorrInfo = alloca( NDR_DEFAULT_CORR_CACHE_SIZE );
|
|||
|
|
|||
|
NdrCorrelationInitialize( pStubMsg,
|
|||
|
(unsigned long *) pCorrInfo,
|
|||
|
NDR_DEFAULT_CORR_CACHE_SIZE,
|
|||
|
0 /* flags */ );
|
|||
|
}
|
|||
|
|
|||
|
NdrMesTypeFree(Handle, pStubDesc, pFormat, pObject);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// =======================================================================
|
|||
|
//
|
|||
|
// Ready to use AlignSize routines for simple types
|
|||
|
//
|
|||
|
// =======================================================================
|
|||
|
|
|||
|
size_t RPC_ENTRY
|
|||
|
NdrMesSimpleTypeAlignSize(
|
|||
|
handle_t Handle )
|
|||
|
/*++
|
|||
|
Size is always 8 bytes for data and there is no header here per data.
|
|||
|
However, the common header gets included for the first object.
|
|||
|
--*/
|
|||
|
{
|
|||
|
NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|||
|
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &((PMIDL_ES_MESSAGE) Handle)->StubMsg;
|
|||
|
|
|||
|
if( (long)( pStubMsg->BufferLength & 0x7 ) )
|
|||
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|||
|
|
|||
|
unsigned long OldLength = pStubMsg->BufferLength;
|
|||
|
|
|||
|
NdrpCommonTypeHeaderSize( (PMIDL_ES_MESSAGE)Handle );
|
|||
|
pStubMsg->BufferLength += 8;
|
|||
|
|
|||
|
return( (size_t)(pStubMsg->BufferLength - OldLength) );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// =======================================================================
|
|||
|
//
|
|||
|
// Ready to use Encode routines for simple types
|
|||
|
//
|
|||
|
// =======================================================================
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrMesSimpleTypeEncode(
|
|||
|
handle_t Handle,
|
|||
|
const MIDL_STUB_DESC * pStubDesc,
|
|||
|
const void * pData,
|
|||
|
short Size )
|
|||
|
/*++
|
|||
|
Marshall a simple type entity. There is no header here per data.
|
|||
|
However, the common header gets included for the first object.
|
|||
|
--*/
|
|||
|
{
|
|||
|
NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|||
|
|
|||
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
|||
|
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
|||
|
size_t RequiredLen;
|
|||
|
|
|||
|
// Size and allocate the buffer.
|
|||
|
// The req len includes: (the common header) and the data
|
|||
|
|
|||
|
// Take the pointer alignment to come up with the right size.
|
|||
|
|
|||
|
pStubMsg->BufferLength = 0xf & PtrToUlong( pStubMsg->Buffer );
|
|||
|
|
|||
|
RequiredLen = NdrMesSimpleTypeAlignSize( Handle );
|
|||
|
NdrpAllocPicklingBuffer( pMesMsg, RequiredLen );
|
|||
|
|
|||
|
// See if we need to marshall the common type header
|
|||
|
|
|||
|
uchar * pBufferSaved = pStubMsg->Buffer;
|
|||
|
|
|||
|
NdrpCommonTypeHeaderMarshall( pMesMsg );
|
|||
|
|
|||
|
switch ( Size )
|
|||
|
{
|
|||
|
case 1:
|
|||
|
* PCHAR_CAST pStubMsg->Buffer = * PCHAR_CAST pData;
|
|||
|
break;
|
|||
|
|
|||
|
case 2:
|
|||
|
* PSHORT_CAST pStubMsg->Buffer = * PSHORT_CAST pData;
|
|||
|
break;
|
|||
|
|
|||
|
case 4:
|
|||
|
* PLONG_CAST pStubMsg->Buffer = * PLONG_CAST pData;
|
|||
|
break;
|
|||
|
|
|||
|
case 8:
|
|||
|
* PHYPER_CAST pStubMsg->Buffer = * PHYPER_CAST pData;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
NDR_ASSERT( 0, " Size generation problem" );
|
|||
|
}
|
|||
|
pStubMsg->Buffer += 8;
|
|||
|
|
|||
|
NdrpWritePicklingBuffer( pMesMsg, pBufferSaved, RequiredLen );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// =======================================================================
|
|||
|
//
|
|||
|
// Ready to use Decode routines for simple types
|
|||
|
//
|
|||
|
// =======================================================================
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrMesSimpleTypeDecode(
|
|||
|
handle_t Handle,
|
|||
|
void * pData,
|
|||
|
short FormatChar )
|
|||
|
/*++
|
|||
|
Does not include the header for the data.
|
|||
|
However, the common header gets included for the first object.
|
|||
|
|
|||
|
Note. Endianness and other conversions for decode.
|
|||
|
This has been deemed as not worthy doing in the Daytona time frame.
|
|||
|
However, to be able to add it in future without backward compatibility
|
|||
|
problems, we have the last argument to be the format character as
|
|||
|
opposed to the size.
|
|||
|
This makes it possible to call NdrSimpleTypeConvert, if needed.
|
|||
|
--*/
|
|||
|
{
|
|||
|
NdrpValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|||
|
|
|||
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &((PMIDL_ES_MESSAGE)Handle)->StubMsg;
|
|||
|
uchar * BufferSaved;
|
|||
|
|
|||
|
// See if we need to unmarshall the common type header.
|
|||
|
|
|||
|
NdrpCommonTypeHeaderUnmarshall( (PMIDL_ES_MESSAGE) Handle );
|
|||
|
|
|||
|
// Now the data.
|
|||
|
|
|||
|
NdrpReadPicklingBuffer( (PMIDL_ES_MESSAGE) Handle, 8);
|
|||
|
|
|||
|
if ( pMesMsg->AlienDataRep != NDR_LOCAL_DATA_REPRESENTATION )
|
|||
|
{
|
|||
|
pStubMsg->RpcMsg->DataRepresentation = pMesMsg->AlienDataRep;
|
|||
|
|
|||
|
BufferSaved = pStubMsg->Buffer;
|
|||
|
NdrSimpleTypeConvert( pStubMsg, (unsigned char)FormatChar );
|
|||
|
pStubMsg->Buffer = BufferSaved;
|
|||
|
}
|
|||
|
|
|||
|
switch ( FormatChar )
|
|||
|
{
|
|||
|
case FC_BYTE:
|
|||
|
case FC_CHAR:
|
|||
|
case FC_SMALL:
|
|||
|
case FC_USMALL:
|
|||
|
* PCHAR_CAST pData = * PCHAR_CAST pStubMsg->Buffer;
|
|||
|
break;
|
|||
|
|
|||
|
case FC_WCHAR:
|
|||
|
case FC_SHORT:
|
|||
|
case FC_USHORT:
|
|||
|
case FC_ENUM16:
|
|||
|
* PSHORT_CAST pData = * PSHORT_CAST pStubMsg->Buffer;
|
|||
|
break;
|
|||
|
|
|||
|
case FC_LONG:
|
|||
|
case FC_ULONG:
|
|||
|
case FC_FLOAT:
|
|||
|
case FC_ENUM32:
|
|||
|
case FC_ERROR_STATUS_T:
|
|||
|
* PLONG_CAST pData = * PLONG_CAST pStubMsg->Buffer;
|
|||
|
break;
|
|||
|
|
|||
|
case FC_HYPER:
|
|||
|
case FC_DOUBLE:
|
|||
|
* PHYPER_CAST pData = * PHYPER_CAST pStubMsg->Buffer;
|
|||
|
break;
|
|||
|
|
|||
|
#if defined(__RPC_WIN64__)
|
|||
|
case FC_INT3264:
|
|||
|
*((INT64 *)pData) = *((long *) pStubMsg->Buffer);
|
|||
|
break;
|
|||
|
|
|||
|
case FC_UINT3264:
|
|||
|
*((UINT64 *)pData) = *((ulong *)pStubMsg->Buffer);
|
|||
|
break;
|
|||
|
#endif
|
|||
|
|
|||
|
default:
|
|||
|
NDR_ASSERT( 0, " Size generation problem for simple types" );
|
|||
|
}
|
|||
|
|
|||
|
pStubMsg->Buffer += 8;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
NdrpProcHeaderMarshallAll(
|
|||
|
PMIDL_ES_MESSAGE pMesMsg
|
|||
|
)
|
|||
|
{
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
|
|||
|
// Marshall DCE pickle header.
|
|||
|
|
|||
|
if( (LONG_PTR)pStubMsg->Buffer & 0x7 )
|
|||
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|||
|
|
|||
|
if ( pMesMsg->Operation == MES_ENCODE )
|
|||
|
* pStubMsg->Buffer++ = MIDL_ES_VERSION;
|
|||
|
else
|
|||
|
* pStubMsg->Buffer++ = MIDL_NDR64_ES_VERSION;
|
|||
|
|
|||
|
* pStubMsg->Buffer++ = NDR_LOCAL_ENDIAN_LOW;
|
|||
|
*( PSHORT_LV_CAST pStubMsg->Buffer)++ = (short)0xcccc; // filler
|
|||
|
|
|||
|
// Marshall transfer syntax from the stub.
|
|||
|
|
|||
|
RpcpMemoryCopy( pStubMsg->Buffer,
|
|||
|
&( ( PMIDL_ES_MESSAGE_EX)pMesMsg )->TransferSyntax,
|
|||
|
sizeof(RPC_SYNTAX_IDENTIFIER) );
|
|||
|
|
|||
|
// We need to remember InterfaceId for inquiries.
|
|||
|
|
|||
|
RpcpMemoryCopy( & pMesMsg->InterfaceId,
|
|||
|
& ((PRPC_CLIENT_INTERFACE)(pStubMsg->
|
|||
|
StubDesc->RpcInterfaceInformation))->InterfaceId,
|
|||
|
sizeof(RPC_SYNTAX_IDENTIFIER) );
|
|||
|
|
|||
|
// Marshall InterfaceId and ProcNumber from the handle.
|
|||
|
|
|||
|
RpcpMemoryCopy( pStubMsg->Buffer + sizeof(RPC_SYNTAX_IDENTIFIER),
|
|||
|
& pMesMsg->InterfaceId,
|
|||
|
sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(long) );
|
|||
|
|
|||
|
SET_MES_INFO_AVAILABLE( pMesMsg );
|
|||
|
|
|||
|
pStubMsg->Buffer += 2 * sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(long);
|
|||
|
|
|||
|
* pStubMsg->Buffer++ = NDR_LOCAL_ENDIAN_LOW;
|
|||
|
* pStubMsg->Buffer++ = NDR_ASCII_CHAR;
|
|||
|
* pStubMsg->Buffer++ = (char) (NDR_IEEE_FLOAT >> 8);
|
|||
|
* pStubMsg->Buffer++ = 0; // filler
|
|||
|
|
|||
|
// This is non-DCE element as they have just 4 more bytes of filler here.
|
|||
|
// This field is used only when unmarshalling in our incremental style.
|
|||
|
|
|||
|
*( PLONG_LV_CAST pStubMsg->Buffer)++ = pStubMsg->BufferLength -
|
|||
|
MES_PROC_HEADER_SIZE;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
NdrpProcHeaderUnmarshallAll(
|
|||
|
PMIDL_ES_MESSAGE pMesMsg
|
|||
|
)
|
|||
|
{
|
|||
|
unsigned char * BufferToRestore;
|
|||
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|||
|
|
|||
|
if ( GET_MES_HEADER_PEEKED( pMesMsg ) )
|
|||
|
return;
|
|||
|
|
|||
|
NdrpReadPicklingBuffer( pMesMsg, MES_PROC_HEADER_SIZE );
|
|||
|
|
|||
|
// Unmarshalling the header
|
|||
|
|
|||
|
if ( *pStubMsg->Buffer != MIDL_ES_VERSION &&
|
|||
|
*pStubMsg->Buffer != MIDL_NDR64_ES_VERSION)
|
|||
|
RpcRaiseException( RPC_X_WRONG_ES_VERSION );
|
|||
|
|
|||
|
BufferToRestore = pStubMsg->Buffer + 4;
|
|||
|
|
|||
|
if ( pStubMsg->Buffer[1] != NDR_LOCAL_ENDIAN_LOW )
|
|||
|
{
|
|||
|
// The DCE header has the endianness on the low nibble, while
|
|||
|
// our DataRep has it on the high nibble.
|
|||
|
// We need only endianess to convert the proc header.
|
|||
|
|
|||
|
byte Endianness = (pStubMsg->Buffer[1] << 4 );
|
|||
|
|
|||
|
pStubMsg->RpcMsg->DataRepresentation = Endianness;
|
|||
|
|
|||
|
pStubMsg->Buffer += 4;
|
|||
|
NdrSimpleStructConvert( pStubMsg,
|
|||
|
&__MIDLFormatString.Format[32],
|
|||
|
FALSE );
|
|||
|
}
|
|||
|
|
|||
|
pStubMsg->Buffer = BufferToRestore;
|
|||
|
|
|||
|
// Verify the transfer syntax
|
|||
|
|
|||
|
RpcpMemoryCopy( &((PMIDL_ES_MESSAGE_EX)pMesMsg)->TransferSyntax,
|
|||
|
pStubMsg->Buffer,
|
|||
|
sizeof( RPC_SYNTAX_IDENTIFIER ) );
|
|||
|
|
|||
|
pStubMsg->Buffer += sizeof(RPC_SYNTAX_IDENTIFIER);
|
|||
|
|
|||
|
// We need to remember the last InterfaceId and ProcNumber for inquiries.
|
|||
|
|
|||
|
RpcpMemoryCopy( & pMesMsg->InterfaceId,
|
|||
|
pStubMsg->Buffer,
|
|||
|
sizeof(RPC_SYNTAX_IDENTIFIER) );
|
|||
|
|
|||
|
pStubMsg->Buffer += sizeof(RPC_SYNTAX_IDENTIFIER);
|
|||
|
|
|||
|
pMesMsg->ProcNumber = *(ulong *)pStubMsg->Buffer;
|
|||
|
|
|||
|
pStubMsg->Buffer += 4;
|
|||
|
|
|||
|
SET_MES_INFO_AVAILABLE( pMesMsg );
|
|||
|
|
|||
|
unsigned long AlienDataRepresentation =
|
|||
|
( (pStubMsg->Buffer[0] << 4) | // endianness
|
|||
|
pStubMsg->Buffer[1] | // chars
|
|||
|
((unsigned long)(pStubMsg->Buffer[2]) << 8) ); // float
|
|||
|
pMesMsg->AlienDataRep = AlienDataRepresentation;
|
|||
|
pMesMsg->IncrDataSize = (size_t) *(unsigned long __RPC_FAR *)
|
|||
|
(pStubMsg->Buffer + 4);
|
|||
|
pStubMsg->Buffer += 8;
|
|||
|
}
|
|||
|
|
|||
|
extern const MIDL_FORMAT_STRING __MIDLFormatString =
|
|||
|
{
|
|||
|
0,
|
|||
|
{
|
|||
|
|
|||
|
0x1d, /* FC_SMFARRAY */
|
|||
|
0x0, /* 0 */
|
|||
|
/* 2 */ 0x6, 0x0, /* 6 */
|
|||
|
/* 4 */ 0x1, /* FC_BYTE */
|
|||
|
0x5b, /* FC_END */
|
|||
|
/* 6 */
|
|||
|
0x15, /* FC_STRUCT */
|
|||
|
0x3, /* 3 */
|
|||
|
/* 8 */ 0x10, 0x0, /* 16 */
|
|||
|
/* 10 */ 0x8, /* FC_LONG */
|
|||
|
0x6, /* FC_SHORT */
|
|||
|
/* 12 */ 0x6, /* FC_SHORT */
|
|||
|
0x3, /* FC_SMALL */
|
|||
|
/* 14 */ 0x3, /* FC_SMALL */
|
|||
|
0x4c, /* FC_EMBEDDED_COMPLEX */
|
|||
|
/* 16 */ 0x0, /* 0 */
|
|||
|
0xef, 0xff, /* Offset= -17 (0) */
|
|||
|
0x5b, /* FC_END */
|
|||
|
/* 20 */
|
|||
|
0x15, /* FC_STRUCT */
|
|||
|
0x3, /* 3 */
|
|||
|
/* 22 */ 0x14, 0x0, /* 20 */
|
|||
|
/* 24 */ 0x4c, /* FC_EMBEDDED_COMPLEX */
|
|||
|
0x0, /* 0 */
|
|||
|
/* 26 */ 0xec, 0xff, /* Offset= -20 (6) */
|
|||
|
/* 28 */ 0x6, /* FC_SHORT */
|
|||
|
0x6, /* FC_SHORT */
|
|||
|
/* 30 */ 0x5c, /* FC_PAD */
|
|||
|
0x5b, /* FC_END */
|
|||
|
/* 32 */
|
|||
|
0x15, /* FC_STRUCT */
|
|||
|
0x3, /* 3 */
|
|||
|
/* 34 */ 0x34, 0x0, /* 52 */
|
|||
|
/* 36 */ 0x4c, /* FC_EMBEDDED_COMPLEX */
|
|||
|
0x0, /* 0 */
|
|||
|
/* 38 */ 0xee, 0xff, /* Offset= -18 (20) */
|
|||
|
/* 40 */ 0x4c, /* FC_EMBEDDED_COMPLEX */
|
|||
|
0x0, /* 0 */
|
|||
|
/* 42 */ 0xea, 0xff, /* Offset= -22 (20) */
|
|||
|
/* 44 */ 0x8, /* FC_LONG */
|
|||
|
0x1, /* FC_BYTE */
|
|||
|
/* 46 */ 0x1, /* FC_BYTE */
|
|||
|
0x1, /* FC_BYTE */
|
|||
|
/* 48 */ 0x1, /* FC_BYTE */
|
|||
|
0x38, /* FC_ALIGNM4 */
|
|||
|
/* 50 */ 0x8, /* FC_LONG */
|
|||
|
0x5b, /* FC_END */
|
|||
|
|
|||
|
0x0
|
|||
|
}
|
|||
|
};
|
|||
|
|