You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1321 lines
43 KiB
1321 lines
43 KiB
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
pickle64.cxx
|
|
|
|
Abstract:
|
|
|
|
This module contains ndr64 related pickling ndr library routines.
|
|
|
|
Notes:
|
|
|
|
Author:
|
|
|
|
Yong Qu Nov, 1993
|
|
|
|
Revision History:
|
|
|
|
|
|
------------------------------------------------------------------------*/
|
|
#include "precomp.hxx"
|
|
|
|
#include <midles.h>
|
|
#include "endianp.h"
|
|
|
|
#include "picklep.hxx"
|
|
|
|
extern "C"
|
|
{
|
|
void RPC_ENTRY
|
|
NdrpPicklingClientFinally( PMIDL_STUB_MESSAGE pStubMsg,
|
|
void * pThis );
|
|
|
|
void RPC_ENTRY
|
|
Ndr64pPicklingClientFinally( PMIDL_STUB_MESSAGE pStubMsg,
|
|
void * pThis );
|
|
}
|
|
|
|
const SYNTAX_DISPATCH_TABLE SyncDcePicklingClient =
|
|
{
|
|
NdrpClientInit,
|
|
NdrpSizing,
|
|
NdrpClientMarshal,
|
|
NdrpClientUnMarshal,
|
|
NdrpClientExceptionHandling,
|
|
NdrpPicklingClientFinally
|
|
};
|
|
|
|
const SYNTAX_DISPATCH_TABLE SyncNdr64PicklingClient =
|
|
{
|
|
Ndr64pClientInit,
|
|
Ndr64pSizing,
|
|
Ndr64pClientMarshal,
|
|
Ndr64pClientUnMarshal,
|
|
Ndr64pClientExceptionHandling,
|
|
Ndr64pPicklingClientFinally
|
|
};
|
|
|
|
|
|
extern const MIDL_FORMAT_STRING __MIDLFormatString;
|
|
|
|
__inline
|
|
void Ndr64pMesTypeInit( PMIDL_STUB_MESSAGE pStubMsg,
|
|
NDR_PROC_CONTEXT * pContext,
|
|
PMIDL_STUB_DESC pStubDesc )
|
|
{
|
|
|
|
// we need this for correlation cache.
|
|
NdrpInitializeProcContext( pContext );
|
|
pStubMsg->pContext = pContext;
|
|
|
|
pStubMsg->fHasExtensions = 1;
|
|
pStubMsg->StubDesc = pStubDesc;
|
|
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
|
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
|
pStubMsg->pCorrInfo = NULL;
|
|
}
|
|
|
|
#define NdrpSetupMesTypeCommon( pfnName, pfnDCE, pfnNDR64 ) \
|
|
\
|
|
if ( pMesMsg->Operation == MES_ENCODE || pMesMsg->Operation == MES_DECODE ) \
|
|
{ \
|
|
SyntaxType = XFER_SYNTAX_DCE; \
|
|
pfnName = &pfnDCE; \
|
|
} \
|
|
else \
|
|
{ \
|
|
SyntaxType = XFER_SYNTAX_NDR64; \
|
|
pfnName = &pfnNDR64; \
|
|
} \
|
|
\
|
|
for ( long i = 0; i < (long) pProxyInfo->nCount; i ++ ) \
|
|
if ( NdrpGetSyntaxType( &pProxyInfo->pSyntaxInfo[i].TransferSyntax ) == SyntaxType ) \
|
|
{ \
|
|
pSyntaxInfo = &pProxyInfo->pSyntaxInfo[i]; \
|
|
break; \
|
|
} \
|
|
\
|
|
if (NULL == pSyntaxInfo ) \
|
|
RpcRaiseException( RPC_S_UNSUPPORTED_TRANS_SYN ); \
|
|
\
|
|
if ( XFER_SYNTAX_DCE == SyntaxType ) \
|
|
{ \
|
|
ulong nFormatOffset = ArrTypeOffset[i][nTypeIndex]; \
|
|
pTypeFormat = &pSyntaxInfo->TypeString[nFormatOffset]; \
|
|
} \
|
|
else \
|
|
{ \
|
|
if ( SyntaxType == XFER_SYNTAX_NDR64 ) \
|
|
Ndr64pMesTypeInit( &pMesMsg->StubMsg, &ProcContext, pProxyInfo->pStubDesc ); \
|
|
\
|
|
pTypeFormat = (PFORMAT_STRING)(((const FormatInfoRef **) ArrTypeOffset)[i][nTypeIndex]); \
|
|
} \
|
|
\
|
|
ProcContext.pSyntaxInfo = pSyntaxInfo;
|
|
|
|
|
|
void
|
|
Ndr64pValidateMesHandle(
|
|
PMIDL_ES_MESSAGE_EX pMesMsgEx )
|
|
{
|
|
RpcTryExcept
|
|
{
|
|
if ( pMesMsgEx == 0 ||
|
|
pMesMsgEx->Signature != MIDL_ES_SIGNATURE ||
|
|
( pMesMsgEx->MesMsg.MesVersion != MIDL_NDR64_ES_VERSION &&
|
|
pMesMsgEx->MesMsg.MesVersion != MIDL_ES_VERSION ) )
|
|
RpcRaiseException( RPC_S_INVALID_ARG );
|
|
}
|
|
RpcExcept( NdrServerUnmarshallExceptionFlag(GetExceptionInformation()) )
|
|
{
|
|
RpcRaiseException( RPC_S_INVALID_ARG );
|
|
}
|
|
RpcEndExcept
|
|
}
|
|
|
|
RPC_STATUS
|
|
Ndr64pValidateMesHandleReturnStatus(
|
|
PMIDL_ES_MESSAGE_EX pMesMsgEx )
|
|
{
|
|
RPC_STATUS Status = RPC_S_OK;
|
|
|
|
RpcTryExcept
|
|
{
|
|
if ( pMesMsgEx == 0 || pMesMsgEx->Signature != MIDL_NDR64_ES_SIGNATURE ||
|
|
pMesMsgEx->MesMsg.MesVersion != MIDL_NDR64_ES_VERSION )
|
|
Status = RPC_S_INVALID_ARG;
|
|
}
|
|
RpcExcept( NdrServerUnmarshallExceptionFlag(GetExceptionInformation()) )
|
|
{
|
|
Status = RPC_S_INVALID_ARG;
|
|
}
|
|
RpcEndExcept
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
void
|
|
Ndr64pCommonTypeHeaderSize(
|
|
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_NDR64 )
|
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|
|
|
if ( ! GET_COMMON_TYPE_HEADER_SIZED( pMesMsg ) )
|
|
{
|
|
pMesMsg->StubMsg.BufferLength += MES_NDR64_CTYPE_HEADER_SIZE;
|
|
|
|
SET_COMMON_TYPE_HEADER_SIZED( pMesMsg );
|
|
}
|
|
}
|
|
|
|
|
|
size_t RPC_ENTRY
|
|
Ndr64MesTypeAlignSize(
|
|
handle_t Handle,
|
|
const MIDL_TYPE_PICKLING_INFO * pxPicklingInfo,
|
|
const MIDL_STUB_DESC * pStubDesc,
|
|
PFORMAT_STRING pFormat,
|
|
const void __RPC_FAR * pObject
|
|
)
|
|
{
|
|
PMIDL_ES_MESSAGE pMesMsg = ( PMIDL_ES_MESSAGE )Handle;
|
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|
size_t OldLength = pStubMsg->BufferLength;
|
|
PMIDL_TYPE_PICKLING_INFOp pPicklingInfo;
|
|
|
|
Ndr64pValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|
|
|
if ( ! pObject )
|
|
RpcRaiseException( RPC_X_NULL_REF_POINTER );
|
|
|
|
if( (long)pStubMsg->BufferLength & 0xf )
|
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|
|
|
pPicklingInfo = (PMIDL_TYPE_PICKLING_INFOp) pxPicklingInfo;
|
|
|
|
NDR_ASSERT( pPicklingInfo->Flags.Oicf, "Oicf should always be on" );
|
|
|
|
|
|
// See if we need to size the common type header.
|
|
|
|
Ndr64pCommonTypeHeaderSize( (PMIDL_ES_MESSAGE)Handle );
|
|
|
|
// Now the individual type object.
|
|
|
|
pStubMsg->BufferLength += MES_NDR64_HEADER_SIZE;
|
|
|
|
if ( NDR64_IS_POINTER_TYPE(*pFormat) )
|
|
{
|
|
// We have to dereference the pointer once.
|
|
pObject = *(void __RPC_FAR * __RPC_FAR *)pObject;
|
|
}
|
|
|
|
(Ndr64SizeRoutinesTable[ NDR64_ROUTINE_INDEX(*pFormat) ])
|
|
( pStubMsg,
|
|
(uchar __RPC_FAR *)pObject,
|
|
pFormat );
|
|
|
|
LENGTH_ALIGN( pStubMsg->BufferLength, 0xf );
|
|
|
|
Ndr64pPicklingClientFinally( pStubMsg, NULL ); // object
|
|
return( pStubMsg->BufferLength - OldLength );
|
|
|
|
|
|
}
|
|
|
|
|
|
// ndr64 entries.
|
|
|
|
size_t RPC_ENTRY
|
|
NdrMesTypeAlignSize3(
|
|
handle_t Handle,
|
|
const MIDL_TYPE_PICKLING_INFO * pPicklingInfo,
|
|
const MIDL_STUBLESS_PROXY_INFO* pProxyInfo,
|
|
const unsigned long ** ArrTypeOffset,
|
|
unsigned long nTypeIndex,
|
|
const void __RPC_FAR * pObject )
|
|
{
|
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|
PFORMAT_STRING pTypeFormat;
|
|
MIDL_SYNTAX_INFO * pSyntaxInfo = NULL;
|
|
PFNMESTYPEALIGNSIZE pfnSize;
|
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|
SYNTAX_TYPE SyntaxType;
|
|
NDR_PROC_CONTEXT ProcContext;
|
|
if ( (( PMIDL_ES_MESSAGE)Handle )->Operation != MES_ENCODE &&
|
|
(( PMIDL_ES_MESSAGE)Handle )->Operation != MES_ENCODE_NDR64 )
|
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|
|
|
NdrpSetupMesTypeCommon( pfnSize, NdrMesTypeAlignSize2, Ndr64MesTypeAlignSize );
|
|
|
|
return
|
|
( *pfnSize )( Handle, pPicklingInfo, pProxyInfo->pStubDesc, pTypeFormat, pObject );
|
|
}
|
|
|
|
|
|
// common type header for type pickling is longer than before:
|
|
// if version is 1, the header size is 8,
|
|
// if version is higher than 1, the header size is 24+2*sizeof(RPC_SYNTAX_IDENTIFIER)
|
|
// starting 8 bytes is still the same as old one:
|
|
// <version:1><endian:1><header_size:2><endian info: 4>
|
|
// addtional header:
|
|
// <reserved: 16> <transfer_syntax><iid>
|
|
//
|
|
size_t
|
|
Ndr64pCommonTypeHeaderMarshall(
|
|
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;
|
|
|
|
if ( (ULONG_PTR)pStubMsg->Buffer & 15 )
|
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|
|
|
MIDL_memset( pStubMsg->Buffer, 0xcc, MES_NDR64_CTYPE_HEADER_SIZE );
|
|
|
|
*pStubMsg->Buffer++ = MIDL_NDR64_ES_VERSION;
|
|
*pStubMsg->Buffer++ = NDR_LOCAL_ENDIAN;
|
|
* PSHORT_CAST pStubMsg->Buffer = MES_NDR64_CTYPE_HEADER_SIZE;
|
|
|
|
pStubMsg->Buffer += MES_CTYPE_HEADER_SIZE + 16 -2 ; // skip over reserved, make header size 64bytes
|
|
|
|
RpcpMemoryCopy( pStubMsg->Buffer,
|
|
& NDR64_TRANSFER_SYNTAX,
|
|
sizeof(RPC_SYNTAX_IDENTIFIER) );
|
|
|
|
pStubMsg->Buffer += sizeof( RPC_SYNTAX_IDENTIFIER );
|
|
RpcpMemoryCopy( pStubMsg->Buffer ,
|
|
& pMesMsg->InterfaceId,
|
|
sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(long) );
|
|
pStubMsg->Buffer += sizeof( RPC_SYNTAX_IDENTIFIER );
|
|
|
|
|
|
SET_COMMON_TYPE_HEADER_IN( pMesMsg );
|
|
return( MES_NDR64_CTYPE_HEADER_SIZE );
|
|
}
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
|
|
void RPC_ENTRY
|
|
Ndr64MesTypeEncode(
|
|
handle_t Handle,
|
|
const MIDL_TYPE_PICKLING_INFO * pxPicklingInfo,
|
|
const MIDL_STUB_DESC * pStubDesc,
|
|
PFORMAT_STRING pFormat,
|
|
const void __RPC_FAR * pObject
|
|
)
|
|
{
|
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|
PMIDL_TYPE_PICKLING_INFOp pPicklingInfo;
|
|
uchar __RPC_FAR * pBufferSaved, *pTypeHeader;
|
|
size_t RequiredLen, CommonHeaderSize, LengthSaved;
|
|
|
|
|
|
pPicklingInfo = (PMIDL_TYPE_PICKLING_INFOp) pxPicklingInfo;
|
|
NDR_ASSERT( pPicklingInfo->Flags.Oicf, "Oicf should always be on" )
|
|
|
|
Ndr64pValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|
|
|
if ( ! pObject )
|
|
RpcRaiseException( RPC_X_NULL_REF_POINTER );
|
|
|
|
if( (LONG_PTR)pStubMsg->Buffer & 0xf )
|
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|
|
|
|
|
pStubMsg->BufferLength = 0xf & PtrToUlong( pStubMsg->Buffer );
|
|
|
|
RequiredLen = Ndr64MesTypeAlignSize( Handle,
|
|
pxPicklingInfo,
|
|
pStubDesc,
|
|
pFormat,
|
|
pObject );
|
|
|
|
NdrpAllocPicklingBuffer( pMesMsg, RequiredLen );
|
|
|
|
pBufferSaved = pStubMsg->Buffer;
|
|
LengthSaved = RequiredLen;
|
|
|
|
// See if we need to marshall the common type header
|
|
|
|
CommonHeaderSize = Ndr64pCommonTypeHeaderMarshall( pMesMsg );
|
|
|
|
// Marshall the header and the object.
|
|
|
|
memset( pStubMsg->Buffer, 0, MES_NDR64_HEADER_SIZE );
|
|
pStubMsg->Buffer += MES_NDR64_HEADER_SIZE;
|
|
|
|
if ( NDR64_IS_POINTER_TYPE(*pFormat) )
|
|
{
|
|
// We have to dereference the pointer once.
|
|
pObject = *(void __RPC_FAR * __RPC_FAR *)pObject;
|
|
}
|
|
|
|
RpcTryFinally
|
|
{
|
|
ALIGN( pStubMsg->Buffer, 0xf );
|
|
(Ndr64MarshallRoutinesTable[ NDR64_ROUTINE_INDEX(*pFormat) ])
|
|
( pStubMsg,
|
|
(uchar __RPC_FAR *)pObject,
|
|
pFormat );
|
|
|
|
// We adjust the buffer to the next align by 16 and
|
|
// so, we tell the user that we've written out till next mod 16.
|
|
|
|
|
|
// cleanup possible leaks before raising exception.
|
|
}
|
|
RpcFinally
|
|
{
|
|
Ndr64pPicklingClientFinally( pStubMsg, NULL ); // object
|
|
}
|
|
RpcEndFinally
|
|
|
|
ALIGN( pStubMsg->Buffer, 0xf );
|
|
size_t WriteLength = (size_t)(pStubMsg->Buffer - pBufferSaved);
|
|
|
|
// We always save the rounded up object length in the type header.
|
|
|
|
*(unsigned long __RPC_FAR *)(pBufferSaved + CommonHeaderSize) =
|
|
WriteLength - CommonHeaderSize - MES_NDR64_HEADER_SIZE;
|
|
|
|
if ( LengthSaved < WriteLength )
|
|
{
|
|
NDR_ASSERT( 0, "NdrMesTypeEncode: encode buffer overflow" );
|
|
RpcRaiseException( RPC_S_INTERNAL_ERROR );
|
|
}
|
|
|
|
NdrpWritePicklingBuffer( pMesMsg, pBufferSaved, WriteLength );
|
|
|
|
|
|
}
|
|
|
|
void RPC_ENTRY
|
|
NdrMesTypeEncode3(
|
|
handle_t Handle,
|
|
const MIDL_TYPE_PICKLING_INFO * pPicklingInfo,
|
|
const MIDL_STUBLESS_PROXY_INFO* pProxyInfo,
|
|
const unsigned long ** ArrTypeOffset,
|
|
unsigned long nTypeIndex,
|
|
const void __RPC_FAR * pObject )
|
|
{
|
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|
PFORMAT_STRING pTypeFormat;
|
|
MIDL_SYNTAX_INFO * pSyntaxInfo = NULL;
|
|
PFNMESTYPEENCODE pfnEncode;
|
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|
SYNTAX_TYPE SyntaxType;
|
|
NDR_PROC_CONTEXT ProcContext;
|
|
if ( (( PMIDL_ES_MESSAGE)Handle )->Operation != MES_ENCODE &&
|
|
(( PMIDL_ES_MESSAGE)Handle )->Operation != MES_ENCODE_NDR64 )
|
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|
|
|
NdrpSetupMesTypeCommon( pfnEncode, NdrMesTypeEncode2, Ndr64MesTypeEncode );
|
|
|
|
( *pfnEncode )( Handle, pPicklingInfo, pProxyInfo->pStubDesc, pTypeFormat, pObject );
|
|
}
|
|
|
|
// read the type header, and determine if the buffer is marshalled
|
|
// using ndr or ndr64
|
|
// for future extension, we can allow other transfer syntaxes.
|
|
void RPC_ENTRY
|
|
Ndr64pCommonTypeHeaderUnmarshall(
|
|
PMIDL_ES_MESSAGE pMesMsg
|
|
)
|
|
{
|
|
BOOL IsNewPickling = FALSE;
|
|
|
|
if ( pMesMsg->Operation != MES_DECODE &&
|
|
pMesMsg->Operation != MES_DECODE_NDR64 )
|
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|
|
|
if ( ! GET_COMMON_TYPE_HEADER_IN( pMesMsg ) )
|
|
{
|
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|
|
|
// read the common header first.
|
|
NdrpReadPicklingBuffer( pMesMsg, MES_CTYPE_HEADER_SIZE );
|
|
|
|
// Check the version number, endianness.
|
|
|
|
if ( *pStubMsg->Buffer == MIDL_ES_VERSION )
|
|
{
|
|
IsNewPickling = FALSE;
|
|
pMesMsg->Operation = MES_DECODE;
|
|
}
|
|
else
|
|
{
|
|
IsNewPickling = TRUE;
|
|
}
|
|
|
|
if ( pStubMsg->Buffer[1] == NDR_LOCAL_ENDIAN )
|
|
{
|
|
// Read the note about endianess at NdrMesTypeDecode.
|
|
//
|
|
pMesMsg->AlienDataRep = NDR_LOCAL_DATA_REPRESENTATION;
|
|
}
|
|
else
|
|
{
|
|
NDR_ASSERT( pMesMsg->Operation != MES_DECODE_NDR64,
|
|
"endian convertion is not supported in ndr64" );
|
|
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;
|
|
if ( IsNewPickling )
|
|
{
|
|
SYNTAX_TYPE SyntaxType;
|
|
// read the remaining header.
|
|
NdrpReadPicklingBuffer( pMesMsg, MES_NDR64_CTYPE_HEADER_SIZE - MES_CTYPE_HEADER_SIZE );
|
|
pStubMsg->Buffer += 16; // skip over Reserved;
|
|
SyntaxType = NdrpGetSyntaxType( (RPC_SYNTAX_IDENTIFIER *)pStubMsg->Buffer );
|
|
if ( SyntaxType == XFER_SYNTAX_DCE )
|
|
{
|
|
pMesMsg->Operation = MES_DECODE;
|
|
}
|
|
else if ( SyntaxType == XFER_SYNTAX_NDR64 )
|
|
{
|
|
pMesMsg->Operation = ( MIDL_ES_CODE )MES_DECODE_NDR64;
|
|
}
|
|
else
|
|
{
|
|
RpcRaiseException( RPC_S_UNSUPPORTED_TRANS_SYN );
|
|
}
|
|
|
|
// skip over iid: we don't need it for now. might be used for verification.
|
|
pStubMsg->Buffer += 2*sizeof( RPC_SYNTAX_IDENTIFIER );
|
|
}
|
|
|
|
SET_COMMON_TYPE_HEADER_IN( pMesMsg );
|
|
}
|
|
|
|
}
|
|
|
|
void RPC_ENTRY
|
|
Ndr64MesTypeDecode(
|
|
handle_t Handle,
|
|
const MIDL_TYPE_PICKLING_INFO * pxPicklingInfo,
|
|
const MIDL_STUB_DESC * pStubDesc,
|
|
PFORMAT_STRING pFormat,
|
|
void __RPC_FAR * pObject
|
|
)
|
|
{
|
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|
PMIDL_TYPE_PICKLING_INFOp pPicklingInfo;
|
|
uchar __RPC_FAR * pBufferSaved, pTypeHeader;
|
|
size_t RequiredLen, CommonHeaderSize, LengthSaved;
|
|
|
|
|
|
pPicklingInfo = (PMIDL_TYPE_PICKLING_INFOp) pxPicklingInfo;
|
|
NDR_ASSERT( pPicklingInfo->Flags.Oicf, "Oicf should always be on" )
|
|
|
|
Ndr64pValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|
|
|
if( (LONG_PTR)pStubMsg->Buffer & 0xf )
|
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|
|
|
|
|
pStubMsg->BufferLength = 0xf & PtrToUlong( pStubMsg->Buffer );
|
|
|
|
NdrpReadPicklingBuffer( pMesMsg, MES_NDR64_HEADER_SIZE );
|
|
|
|
RequiredLen = (size_t) *(unsigned long __RPC_FAR *)pStubMsg->Buffer;
|
|
pStubMsg->Buffer += MES_NDR64_HEADER_SIZE;
|
|
|
|
NdrpReadPicklingBuffer( pMesMsg, RequiredLen );
|
|
|
|
void * pArg = pObject;
|
|
|
|
if ( NDR64_IS_POINTER_TYPE(*pFormat) )
|
|
{
|
|
// We have to dereference the pointer once.
|
|
//
|
|
pArg = *(void **)pArg;
|
|
}
|
|
|
|
RpcTryFinally
|
|
{
|
|
|
|
(Ndr64UnmarshallRoutinesTable[ NDR64_ROUTINE_INDEX( *pFormat )])
|
|
( pStubMsg,
|
|
(uchar __RPC_FAR * __RPC_FAR *)&pArg,
|
|
pFormat,
|
|
FALSE );
|
|
|
|
if ( NDR64_IS_POINTER_TYPE(*pFormat) )
|
|
{
|
|
// Don't drop the pointee, if it was allocated.
|
|
|
|
*(void **)pObject = pArg;
|
|
}
|
|
|
|
if ( pStubMsg->pCorrInfo )
|
|
Ndr64CorrelationPass( pStubMsg );
|
|
|
|
// Next decoding needs to start at aligned to 16.
|
|
ALIGN( pStubMsg->Buffer, 15 );
|
|
}
|
|
RpcFinally
|
|
{
|
|
Ndr64pPicklingClientFinally( pStubMsg, NULL ); // object
|
|
}
|
|
RpcEndFinally
|
|
}
|
|
|
|
void RPC_ENTRY
|
|
NdrMesTypeDecode3(
|
|
handle_t Handle,
|
|
const MIDL_TYPE_PICKLING_INFO * pPicklingInfo,
|
|
const MIDL_STUBLESS_PROXY_INFO* pProxyInfo,
|
|
const unsigned long ** ArrTypeOffset,
|
|
unsigned long nTypeIndex,
|
|
void __RPC_FAR * pObject )
|
|
{
|
|
size_t RequiredLen;
|
|
|
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|
uchar * BufferSaved;
|
|
PFNMESDECODE pfnDecode;
|
|
MIDL_SYNTAX_INFO * pSyntaxInfo;
|
|
PFORMAT_STRING pTypeFormat;
|
|
SYNTAX_TYPE SyntaxType;
|
|
NDR_PROC_CONTEXT ProcContext;
|
|
|
|
if ( ! pObject )
|
|
RpcRaiseException( RPC_X_NULL_REF_POINTER );
|
|
|
|
Ndr64pCommonTypeHeaderUnmarshall( pMesMsg );
|
|
|
|
NdrpSetupMesTypeCommon( pfnDecode, NdrMesTypeDecode2, Ndr64MesTypeDecode );
|
|
|
|
(* pfnDecode )( Handle, pPicklingInfo, pProxyInfo->pStubDesc, pTypeFormat, pObject );
|
|
}
|
|
|
|
|
|
void RPC_ENTRY
|
|
Ndr64MesTypeFree(
|
|
handle_t Handle,
|
|
const MIDL_TYPE_PICKLING_INFO * pxPicklingInfo,
|
|
const MIDL_STUB_DESC * pStubDesc,
|
|
PFORMAT_STRING pFormat,
|
|
void __RPC_FAR * 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.
|
|
|
|
--*/
|
|
{
|
|
NDR_PROC_CONTEXT ProcContext;
|
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|
PMIDL_TYPE_PICKLING_INFOp pPicklingInfo;
|
|
|
|
Ndr64pValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|
|
|
pPicklingInfo = (PMIDL_TYPE_PICKLING_INFOp) pxPicklingInfo;
|
|
|
|
NDR_ASSERT( pPicklingInfo->Flags.Oicf, "Oicf should always be on" )
|
|
|
|
if ( ! pObject )
|
|
RpcRaiseException( RPC_X_NULL_REF_POINTER );
|
|
|
|
if( (LONG_PTR)pStubMsg->Buffer & 0xf )
|
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|
|
|
|
|
// Now the individual type object.
|
|
|
|
if ( NDR64_IS_POINTER_TYPE(*pFormat) )
|
|
{
|
|
// We have to dereference the pointer once.
|
|
pObject = *(void __RPC_FAR * __RPC_FAR *)pObject;
|
|
}
|
|
|
|
(Ndr64FreeRoutinesTable[ NDR64_ROUTINE_INDEX(*pFormat) ])
|
|
( pStubMsg,
|
|
(uchar __RPC_FAR *)pObject,
|
|
pFormat );
|
|
|
|
Ndr64pPicklingClientFinally( pStubMsg, NULL ); // object
|
|
}
|
|
|
|
void RPC_ENTRY
|
|
NdrMesTypeFree3(
|
|
handle_t Handle,
|
|
const MIDL_TYPE_PICKLING_INFO * pxPicklingInfo,
|
|
const MIDL_STUBLESS_PROXY_INFO* pProxyInfo,
|
|
const unsigned long ** ArrTypeOffset,
|
|
unsigned long nTypeIndex,
|
|
void __RPC_FAR * pObject )
|
|
{
|
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|
PMIDL_TYPE_PICKLING_INFOp pPicklingInfo;
|
|
PFNMESFREE pfnFree;
|
|
MIDL_SYNTAX_INFO * pSyntaxInfo;
|
|
PFORMAT_STRING pTypeFormat;
|
|
SYNTAX_TYPE SyntaxType;
|
|
NDR_PROC_CONTEXT ProcContext;
|
|
|
|
|
|
pPicklingInfo = (PMIDL_TYPE_PICKLING_INFOp) pxPicklingInfo;
|
|
|
|
NdrpSetupMesTypeCommon( pfnFree, NdrMesTypeFree2, Ndr64MesTypeFree );
|
|
|
|
(*pfnFree)(Handle, pxPicklingInfo, pProxyInfo->pStubDesc, pTypeFormat, pObject );
|
|
}
|
|
|
|
void
|
|
Ndr64pMesProcEncodeInit( PMIDL_ES_MESSAGE pMesMsg,
|
|
const MIDL_STUBLESS_PROXY_INFO * pProxyInfo,
|
|
unsigned long nProcNum,
|
|
MIDL_ES_CODE Operation,
|
|
NDR_PROC_CONTEXT * pContext,
|
|
uchar * StartofStack)
|
|
{
|
|
PMIDL_STUB_DESC pStubDesc = pProxyInfo->pStubDesc;
|
|
SYNTAX_TYPE syntaxType;
|
|
BOOL fUseEncode, fIsSupported = FALSE;
|
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|
RPC_STATUS res;
|
|
|
|
// TODO: verify stub version.
|
|
|
|
if ( Operation == MES_ENCODE )
|
|
{
|
|
syntaxType = XFER_SYNTAX_DCE;
|
|
memcpy( &( (PMIDL_ES_MESSAGE_EX)pMesMsg )->TransferSyntax,
|
|
&NDR_TRANSFER_SYNTAX ,
|
|
sizeof( RPC_SYNTAX_IDENTIFIER ) );
|
|
}
|
|
else
|
|
{
|
|
syntaxType = XFER_SYNTAX_NDR64;
|
|
memcpy( &( (PMIDL_ES_MESSAGE_EX)pMesMsg )->TransferSyntax,
|
|
&NDR64_TRANSFER_SYNTAX ,
|
|
sizeof( RPC_SYNTAX_IDENTIFIER ) );
|
|
}
|
|
|
|
Ndr64ClientInitializeContext( syntaxType, pProxyInfo, nProcNum, pContext, StartofStack );
|
|
|
|
pStubMsg->pContext = pContext;
|
|
pStubMsg->StubDesc = pStubDesc;
|
|
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
|
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
|
|
|
// varify proc header
|
|
if ( syntaxType == XFER_SYNTAX_DCE )
|
|
{
|
|
uchar InterpreterFlag = * ((uchar *)&pContext->NdrInfo.InterpreterFlags );
|
|
fUseEncode = InterpreterFlag & ENCODE_IS_USED;
|
|
memcpy( & (pContext->pfnInit), &SyncDcePicklingClient, sizeof( SYNTAX_DISPATCH_TABLE ) );
|
|
}
|
|
else
|
|
{
|
|
fUseEncode = ( ( (NDR64_PROC_FLAGS *) & pContext->Ndr64Header->Flags)->IsEncode );
|
|
memcpy( & (pContext->pfnInit), &SyncNdr64PicklingClient, sizeof( SYNTAX_DISPATCH_TABLE ) );
|
|
}
|
|
|
|
if (!fUseEncode )
|
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|
}
|
|
|
|
CLIENT_CALL_RETURN RPC_VAR_ENTRY
|
|
NdrMesProcEncode3(
|
|
PMIDL_ES_MESSAGE pMesMsg,
|
|
const MIDL_STUBLESS_PROXY_INFO* pProxyInfo,
|
|
unsigned long nProcNum,
|
|
uchar * StartofStack )
|
|
{
|
|
PMIDL_STUB_MESSAGE pStubMsg = & pMesMsg->StubMsg;
|
|
NDR_PROC_CONTEXT ProcContext;
|
|
unsigned long ulAlignment;
|
|
unsigned char * BufferSaved;
|
|
size_t WriteLength;
|
|
CLIENT_CALL_RETURN Ret;
|
|
|
|
Ret.Simple = NULL;
|
|
|
|
pMesMsg->ProcNumber = nProcNum;
|
|
|
|
|
|
Ndr64pMesProcEncodeInit( pMesMsg,
|
|
pProxyInfo,
|
|
nProcNum,
|
|
pMesMsg->Operation,
|
|
&ProcContext,
|
|
StartofStack );
|
|
|
|
RpcTryFinally
|
|
{
|
|
ProcContext.pfnInit( pStubMsg,
|
|
NULL ); // return value
|
|
|
|
ProcContext.pfnSizing( pStubMsg,
|
|
TRUE );
|
|
|
|
if ( pMesMsg->Operation == MES_ENCODE )
|
|
ulAlignment = 0x7;
|
|
else
|
|
ulAlignment = 0xf;
|
|
|
|
// we are not changing the proc header, but we need to overestimate because
|
|
// proc header is marshalled first.
|
|
LENGTH_ALIGN( pStubMsg->BufferLength, ulAlignment );
|
|
|
|
pStubMsg->BufferLength += MES_PROC_HEADER_SIZE ;
|
|
|
|
LENGTH_ALIGN( pStubMsg->BufferLength, ulAlignment );
|
|
|
|
size_t LengthSaved;
|
|
|
|
NdrpAllocPicklingBuffer( pMesMsg, pStubMsg->BufferLength );
|
|
BufferSaved = pStubMsg->Buffer;
|
|
LengthSaved = pStubMsg->BufferLength;
|
|
|
|
NDR_ASSERT( ( (ULONG_PTR)pStubMsg->Buffer & ulAlignment ) == 0, "pickling buffer is not aligned" );
|
|
|
|
NdrpProcHeaderMarshallAll( pMesMsg );
|
|
|
|
ALIGN( pStubMsg->Buffer, ulAlignment );
|
|
|
|
ProcContext.pfnMarshal( pStubMsg,
|
|
FALSE );
|
|
|
|
ALIGN( pStubMsg->Buffer, ulAlignment );
|
|
|
|
WriteLength = (size_t)(pStubMsg->Buffer - BufferSaved);
|
|
* (unsigned long __RPC_FAR *)
|
|
( 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 );
|
|
}
|
|
RpcFinally
|
|
{
|
|
( *ProcContext.pfnClientFinally)( pStubMsg, NULL ); // not object
|
|
}
|
|
RpcEndFinally
|
|
|
|
return Ret;
|
|
}
|
|
|
|
|
|
// both encode and decode acts like the client side.
|
|
void
|
|
Ndr64pMesProcDecodeInit( PMIDL_ES_MESSAGE pMesMsg,
|
|
const MIDL_STUBLESS_PROXY_INFO * pProxyInfo,
|
|
SYNTAX_TYPE SyntaxType,
|
|
unsigned long nProcNum,
|
|
NDR_PROC_CONTEXT * pContext,
|
|
uchar * StartofStack )
|
|
{
|
|
RPC_STATUS res;
|
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|
unsigned long nFormatOffset;
|
|
PMIDL_STUB_DESC pStubDesc = pProxyInfo->pStubDesc;
|
|
BOOL fUseDecode;
|
|
|
|
// REVIEW: Calling the "Client" init for decode seems weird but it does
|
|
// the right thing and NdrServerSetupMultipleTransferSyntax assumes
|
|
// ndr64.
|
|
|
|
Ndr64ClientInitializeContext(
|
|
SyntaxType,
|
|
pProxyInfo,
|
|
nProcNum,
|
|
pContext,
|
|
StartofStack );
|
|
|
|
pStubMsg->pContext = pContext;
|
|
pStubMsg->StubDesc = pStubDesc;
|
|
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
|
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
|
|
|
NdrpDataBufferInit( pMesMsg, pContext->pProcFormat );
|
|
|
|
if ( SyntaxType == XFER_SYNTAX_DCE )
|
|
{
|
|
uchar InterpreterFlag = * ((uchar *)&pContext->NdrInfo.InterpreterFlags );
|
|
fUseDecode = InterpreterFlag & DECODE_IS_USED;
|
|
memcpy( & (pContext->pfnInit), &SyncDcePicklingClient, sizeof( SYNTAX_DISPATCH_TABLE ) );
|
|
}
|
|
else
|
|
{
|
|
fUseDecode = ( ( (NDR64_PROC_FLAGS *) & pContext->Ndr64Header->Flags)->IsDecode );
|
|
memcpy( & (pContext->pfnInit), &SyncNdr64PicklingClient, sizeof( SYNTAX_DISPATCH_TABLE ) );
|
|
}
|
|
|
|
if (!fUseDecode )
|
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|
}
|
|
|
|
|
|
CLIENT_CALL_RETURN RPC_VAR_ENTRY
|
|
NdrMesProcDecode3(
|
|
PMIDL_ES_MESSAGE pMesMsg,
|
|
const MIDL_STUBLESS_PROXY_INFO *pProxyInfo,
|
|
unsigned long nProcNum,
|
|
uchar * StartofStack,
|
|
void * pReturnValue )
|
|
{
|
|
CLIENT_CALL_RETURN RetVal;
|
|
NDR_PROC_CONTEXT ProcContext;
|
|
SYNTAX_TYPE SyntaxType;
|
|
PMIDL_STUB_MESSAGE pStubMsg = & pMesMsg->StubMsg;
|
|
NDR64_PROC_FLAGS *ProcFlags;
|
|
unsigned long ulAlign;
|
|
long HasComplexReturn;
|
|
|
|
RetVal.Simple = NULL;
|
|
if (NULL == pReturnValue )
|
|
pReturnValue = &RetVal;
|
|
|
|
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
|
|
NdrpProcHeaderUnmarshallAll( pMesMsg );
|
|
|
|
SyntaxType = NdrpGetSyntaxType( &((PMIDL_ES_MESSAGE_EX)pMesMsg)->TransferSyntax );
|
|
|
|
if ( SyntaxType == XFER_SYNTAX_DCE )
|
|
{
|
|
pMesMsg->Operation = MES_DECODE;
|
|
ulAlign = 0x7;
|
|
}
|
|
else if ( SyntaxType == XFER_SYNTAX_NDR64 )
|
|
{
|
|
pMesMsg->Operation = ( MIDL_ES_CODE )MES_DECODE_NDR64;
|
|
ulAlign = 0xf;
|
|
}
|
|
else
|
|
RpcRaiseException( RPC_S_UNSUPPORTED_TRANS_SYN );
|
|
|
|
if ( (LONG_PTR)pStubMsg->BufferStart & ulAlign )
|
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|
|
|
Ndr64pMesProcDecodeInit( pMesMsg,
|
|
pProxyInfo,
|
|
SyntaxType,
|
|
nProcNum,
|
|
&ProcContext,
|
|
StartofStack );
|
|
|
|
RpcTryFinally
|
|
{
|
|
|
|
ProcContext.pfnInit( pStubMsg,
|
|
NULL ); // return value
|
|
|
|
ALIGN( pStubMsg->Buffer, ulAlign );
|
|
|
|
ProcContext.pfnUnMarshal( pStubMsg,
|
|
ProcContext.HasComplexReturn
|
|
? &pReturnValue
|
|
: pReturnValue );
|
|
|
|
// prepare for new decoding.
|
|
ALIGN( pStubMsg->Buffer, ulAlign );
|
|
|
|
}
|
|
RpcFinally
|
|
{
|
|
|
|
( *ProcContext.pfnClientFinally)( pStubMsg, NULL ); // object
|
|
}
|
|
RpcEndFinally
|
|
|
|
return *(CLIENT_CALL_RETURN *)pReturnValue;
|
|
|
|
}
|
|
|
|
CLIENT_CALL_RETURN RPC_VAR_ENTRY
|
|
NdrMesProcEncodeDecode3(
|
|
handle_t Handle,
|
|
const MIDL_STUBLESS_PROXY_INFO* pProxyInfo,
|
|
unsigned long nProcNum,
|
|
void *pReturnValue,
|
|
... )
|
|
{
|
|
BOOL fMoreParams;
|
|
PFORMAT_STRING pProcFormat;
|
|
void __RPC_FAR * pArg;
|
|
va_list ArgList;
|
|
unsigned char * BufferSaved;
|
|
size_t WriteLength;
|
|
uchar * StartofStack;
|
|
|
|
Ndr64pValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|
|
|
INIT_ARG( ArgList, pReturnValue );
|
|
GET_FIRST_IN_ARG(ArgList);
|
|
StartofStack = (uchar *)GET_STACK_START(ArgList);
|
|
|
|
if ( pMesMsg->Operation == MES_ENCODE ||
|
|
pMesMsg->Operation == MES_ENCODE_NDR64 )
|
|
return NdrMesProcEncode3( (PMIDL_ES_MESSAGE)Handle, pProxyInfo, nProcNum, StartofStack );
|
|
else
|
|
return NdrMesProcDecode3( (PMIDL_ES_MESSAGE)Handle, pProxyInfo, nProcNum, StartofStack, pReturnValue );
|
|
|
|
|
|
}
|
|
|
|
|
|
void RPC_ENTRY
|
|
NdrpPicklingClientFinally( PMIDL_STUB_MESSAGE pStubMsg,
|
|
void * pThis )
|
|
{
|
|
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *) pStubMsg->pContext;
|
|
PMIDL_STUB_DESC pStubDesc = pStubMsg->StubDesc;
|
|
|
|
NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables);
|
|
|
|
NdrCorrelationFree( pStubMsg );
|
|
|
|
NdrpAllocaDestroy( & pContext->AllocateContext );
|
|
|
|
}
|
|
|
|
void RPC_ENTRY
|
|
Ndr64pPicklingClientFinally( PMIDL_STUB_MESSAGE pStubMsg,
|
|
void * pThis )
|
|
{
|
|
NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables);
|
|
|
|
NdrpAllocaDestroy( & ( (NDR_PROC_CONTEXT *)pStubMsg->pContext )->AllocateContext );
|
|
}
|
|
|
|
|
|
// =======================================================================
|
|
//
|
|
// Ready to use AlignSize routines for simple types
|
|
//
|
|
// =======================================================================
|
|
void ValidateMesSimpleTypeAll( const MIDL_STUBLESS_PROXY_INFO * pProxyInfo,
|
|
MIDL_ES_CODE Operation )
|
|
{
|
|
ulong i;
|
|
SYNTAX_TYPE SyntaxType;
|
|
|
|
if ( Operation == MES_ENCODE ||
|
|
Operation == MES_DECODE )
|
|
SyntaxType = XFER_SYNTAX_DCE;
|
|
else
|
|
SyntaxType = XFER_SYNTAX_NDR64;
|
|
|
|
for ( i = 0; i < ( ulong )pProxyInfo->nCount; i++ )
|
|
{
|
|
if ( NdrpGetSyntaxType( &pProxyInfo->pSyntaxInfo[i].TransferSyntax ) == SyntaxType )
|
|
break;
|
|
}
|
|
|
|
// Raise exception if we didn't find the supported syntax in proxyinfo.
|
|
if ( i >= pProxyInfo->nCount )
|
|
RpcRaiseException( RPC_S_UNSUPPORTED_TRANS_SYN );
|
|
}
|
|
|
|
|
|
size_t RPC_ENTRY
|
|
NdrMesSimpleTypeAlignSizeAll(
|
|
handle_t Handle,
|
|
const MIDL_STUBLESS_PROXY_INFO * pProxyInfo
|
|
)
|
|
/*++
|
|
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.
|
|
--*/
|
|
{
|
|
if ( (( PMIDL_ES_MESSAGE)Handle )->Operation != MES_ENCODE &&
|
|
(( PMIDL_ES_MESSAGE)Handle )->Operation != MES_ENCODE_NDR64 )
|
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|
|
|
Ndr64pValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|
|
|
PMIDL_STUB_MESSAGE pStubMsg = &((PMIDL_ES_MESSAGE) Handle)->StubMsg;
|
|
|
|
ValidateMesSimpleTypeAll( pProxyInfo, ((PMIDL_ES_MESSAGE)Handle)->Operation );
|
|
|
|
unsigned long OldLength = pStubMsg->BufferLength;
|
|
|
|
if ( ((PMIDL_ES_MESSAGE)Handle)->Operation == MES_ENCODE )
|
|
{
|
|
if( (long)( pStubMsg->BufferLength & 0x7 ) )
|
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|
|
|
NdrpCommonTypeHeaderSize( (PMIDL_ES_MESSAGE)Handle );
|
|
pStubMsg->BufferLength += 8;
|
|
}
|
|
else
|
|
{
|
|
if( (long)( pStubMsg->BufferLength & 0xf ) )
|
|
RpcRaiseException( RPC_X_INVALID_BUFFER );
|
|
|
|
Ndr64pCommonTypeHeaderSize( (PMIDL_ES_MESSAGE)Handle );
|
|
LENGTH_ALIGN( pStubMsg->BufferLength, 0xf );
|
|
pStubMsg->BufferLength += 16;
|
|
}
|
|
|
|
return( (size_t)(pStubMsg->BufferLength - OldLength) );
|
|
}
|
|
|
|
|
|
// =======================================================================
|
|
//
|
|
// Ready to use Encode routines for simple types
|
|
//
|
|
// =======================================================================
|
|
|
|
void RPC_ENTRY
|
|
NdrMesSimpleTypeEncodeAll(
|
|
handle_t Handle,
|
|
const MIDL_STUBLESS_PROXY_INFO * pProxyInfo,
|
|
const void __RPC_FAR * 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.
|
|
--*/
|
|
{
|
|
if ( (( PMIDL_ES_MESSAGE)Handle )->Operation != MES_ENCODE &&
|
|
(( PMIDL_ES_MESSAGE)Handle )->Operation != MES_ENCODE_NDR64 )
|
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|
|
|
Ndr64pValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|
|
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|
PMIDL_STUB_MESSAGE pStubMsg = &pMesMsg->StubMsg;
|
|
PMIDL_STUB_DESC pStubDesc = pProxyInfo->pStubDesc;
|
|
pStubMsg->pfnAllocate = pStubDesc->pfnAllocate;
|
|
pStubMsg->pfnFree = pStubDesc->pfnFree;
|
|
unsigned long ulAlignment;
|
|
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 = NdrMesSimpleTypeAlignSizeAll( Handle, pProxyInfo );
|
|
NdrpAllocPicklingBuffer( pMesMsg, RequiredLen );
|
|
|
|
// See if we need to marshall the common type header
|
|
|
|
uchar __RPC_FAR * pBufferSaved = pStubMsg->Buffer;
|
|
|
|
if ( pMesMsg->Operation == MES_ENCODE )
|
|
{
|
|
NdrpCommonTypeHeaderMarshall( pMesMsg );
|
|
ulAlignment = 0x7;
|
|
}
|
|
else if ( pMesMsg->Operation == MES_ENCODE_NDR64 )
|
|
{
|
|
Ndr64pCommonTypeHeaderMarshall( pMesMsg );
|
|
ulAlignment = 0xf;
|
|
}
|
|
else
|
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|
|
|
ALIGN( pStubMsg->Buffer, ulAlignment );
|
|
|
|
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 += ulAlignment+1;
|
|
|
|
NdrpWritePicklingBuffer( pMesMsg, pBufferSaved, RequiredLen );
|
|
}
|
|
|
|
|
|
|
|
// =======================================================================
|
|
//
|
|
// Ready to use Decode routines for simple types
|
|
//
|
|
// =======================================================================
|
|
|
|
void RPC_ENTRY
|
|
NdrMesSimpleTypeDecodeAll(
|
|
handle_t Handle,
|
|
const MIDL_STUBLESS_PROXY_INFO * pProxyInfo,
|
|
void __RPC_FAR * 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.
|
|
|
|
Note that the compiler uses the 32bit tokens for this since this routine
|
|
is common to both formats.
|
|
--*/
|
|
{
|
|
if ( ( (PMIDL_ES_MESSAGE)Handle )->Operation != MES_DECODE &&
|
|
( (PMIDL_ES_MESSAGE)Handle )->Operation != MES_DECODE_NDR64 )
|
|
RpcRaiseException( RPC_X_INVALID_ES_ACTION );
|
|
|
|
Ndr64pValidateMesHandle( (PMIDL_ES_MESSAGE_EX)Handle );
|
|
|
|
PMIDL_ES_MESSAGE pMesMsg = (PMIDL_ES_MESSAGE) Handle;
|
|
PMIDL_STUB_MESSAGE pStubMsg = &((PMIDL_ES_MESSAGE)Handle)->StubMsg;
|
|
uchar * BufferSaved;
|
|
unsigned long ulAlignment;
|
|
|
|
// See if we need to unmarshall the common type header.
|
|
Ndr64pCommonTypeHeaderUnmarshall( pMesMsg );
|
|
|
|
|
|
// Now the data.
|
|
|
|
if ( pMesMsg->Operation == MES_DECODE )
|
|
{
|
|
NdrpReadPicklingBuffer( (PMIDL_ES_MESSAGE) Handle, 8);
|
|
ulAlignment = 0x7;
|
|
}
|
|
else
|
|
{
|
|
NdrpReadPicklingBuffer( (PMIDL_ES_MESSAGE) Handle, 16);
|
|
ulAlignment = 0xf;
|
|
}
|
|
|
|
NDR_ASSERT( ( (ULONG_PTR)pStubMsg->Buffer & ulAlignment ) == 0, "invalid buffer alignment in simple type pickling" );
|
|
|
|
ValidateMesSimpleTypeAll( pProxyInfo, ((PMIDL_ES_MESSAGE)Handle)->Operation );
|
|
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:
|
|
* 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:
|
|
if (pMesMsg->Operation == MES_DECODE )
|
|
*((INT64 *)pData) = *((long *) pStubMsg->Buffer);
|
|
else
|
|
*((INT64 *)pData) = *((INT64 *) pStubMsg->Buffer);
|
|
break;
|
|
|
|
case FC_UINT3264:
|
|
if (pMesMsg->Operation == MES_DECODE )
|
|
*((UINT64 *)pData) = *((ulong *)pStubMsg->Buffer);
|
|
else
|
|
*((UINT64 *)pData) = *((UINT64 *)pStubMsg->Buffer);
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
NDR_ASSERT( 0, " Size generation problem for simple types" );
|
|
}
|
|
|
|
pStubMsg->Buffer += ulAlignment+1;
|
|
}
|
|
|