windows-nt/Source/XPSP1/NT/com/rpc/ndr64/mulsyntx.cxx
2020-09-26 16:20:57 +08:00

1201 lines
36 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1999-2000 Microsoft Corporation
Module Name :
mulsyntx.c
Abstract :
This file contains multiple transfer syntaxes negotiation related code
Author :
Yong Qu yongqu September 1999.
Revision History :
---------------------------------------------------------------------*/
#include "precomp.hxx"
#define CINTERFACE
#include "ndrole.h"
#include "rpcproxy.h"
#include "expr.h"
#include "auxilary.h"
#include "..\..\ndr20\pipendr.h"
uchar Ndr64HandleTypeMap[] =
{
0,
FC64_BIND_GENERIC,
FC64_BIND_PRIMITIVE,
FC64_AUTO_HANDLE,
FC64_CALLBACK_HANDLE
} ;
extern const SYNTAX_DISPATCH_TABLE SyncDceClient =
{
NdrpClientInit,
NdrpSizing,
NdrpClientMarshal,
NdrpClientUnMarshal,
NdrpClientExceptionHandling,
NdrpClientFinally
};
extern const SYNTAX_DISPATCH_TABLE AsyncDceClient =
{
NdrpClientInit,
NdrpSizing,
NdrpClientMarshal,
NdrpClientUnMarshal,
NdrpAsyncClientExceptionHandling,
NdrpClientFinally
};
extern const SYNTAX_DISPATCH_TABLE SyncDcomDceClient =
{
NdrpClientInit,
NdrpSizing,
NdrpClientMarshal,
NdrpClientUnMarshal,
NdrpDcomClientExceptionHandling,
NdrpClientFinally
};
extern const SYNTAX_DISPATCH_TABLE SyncNdr64Client =
{
Ndr64pClientInit,
Ndr64pSizing,
Ndr64pClientMarshal,
Ndr64pClientUnMarshal,
Ndr64pClientExceptionHandling,
Ndr64pClientFinally
};
extern const SYNTAX_DISPATCH_TABLE SyncDcomNdr64Client =
{
Ndr64pClientInit,
Ndr64pSizing,
Ndr64pClientMarshal,
Ndr64pClientUnMarshal,
Ndr64pDcomClientExceptionHandling,
Ndr64pClientFinally
};
const RPC_SYNTAX_IDENTIFIER NDR_TRANSFER_SYNTAX = {{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
const RPC_SYNTAX_IDENTIFIER NDR64_TRANSFER_SYNTAX = {{0x71710533,0xbeba,0x4937,{0x83, 0x19, 0xb5, 0xdb, 0xef, 0x9c, 0xcc, 0x36}},{1,0}};
const RPC_SYNTAX_IDENTIFIER FAKE_NDR64_TRANSFER_SYNTAX = { { 0xb4537da9,0x3d03,0x4f6b,{0xb5, 0x94, 0x52, 0xb2, 0x87, 0x4e, 0xe9, 0xd0} }, {1,0} };
CStdProxyBuffer * RPC_ENTRY
NdrGetProxyBuffer(
void *pThis);
void
EnsureNSLoaded();
#pragma code_seg(".ndr64")
__inline
const IID * RPC_ENTRY
NdrGetSyncProxyIID(
IN void *pThis)
/*++
Routine Description:
The NDRGetSyncProxyIID function returns a pointer to IID.
Arguments:
pThis - Supplies a pointer to the async interface proxy.
Return Value:
This function returns a pointer to the corresponding sync IID.
--*/
{
CStdAsyncProxyBuffer * pAsyncPB = ( CStdAsyncProxyBuffer *) NdrGetProxyBuffer( pThis );
return pAsyncPB->pSyncIID;
}
void RPC_ENTRY
Ndr64SetupClientContextVtbl ( NDR_PROC_CONTEXT * pContext )
{
if ( pContext->CurrentSyntaxType == XFER_SYNTAX_DCE )
{
if ( pContext->IsObject )
memcpy( & (pContext->pfnInit), &SyncDcomDceClient, sizeof( SYNTAX_DISPATCH_TABLE ) );
else
{
if ( pContext->IsAsync )
memcpy( & (pContext->pfnInit), &AsyncDceClient, sizeof( SYNTAX_DISPATCH_TABLE ) );
else
memcpy( & (pContext->pfnInit), &SyncDceClient, sizeof( SYNTAX_DISPATCH_TABLE ) );
}
}
else
{
if ( pContext->IsObject )
memcpy( & (pContext->pfnInit), &SyncDcomNdr64Client, sizeof( SYNTAX_DISPATCH_TABLE ) );
else
memcpy( & (pContext->pfnInit), &SyncNdr64Client, sizeof( SYNTAX_DISPATCH_TABLE ) );
}
}
/*++
Routine Description :
This routine initialize the server side NDR_PROC_CONTEXT when using
NDR64.
Arguments :
Return :
None.
--*/
void
NdrServerSetupNDR64TransferSyntax(
ulong ProcNum,
MIDL_SYNTAX_INFO * pSyntaxInfo,
NDR_PROC_CONTEXT * pContext)
{
PFORMAT_STRING pFormat;
SYNTAX_TYPE SyntaxType = XFER_SYNTAX_NDR64;
NDR_ASSERT( SyntaxType == NdrpGetSyntaxType( &pSyntaxInfo->TransferSyntax ) ,
"invalid transfer sytnax" );
pFormat = NdrpGetProcString( pSyntaxInfo,
SyntaxType,
ProcNum );
MulNdrpInitializeContextFromProc(
SyntaxType,
pFormat,
pContext,
NULL ); // StartofStack. Don't have it yet.
pContext->pSyntaxInfo = pSyntaxInfo;
}
/*++
Routine Description :
Setup the client side transfer syntax information from MIDL_PROXY_INFO
This is the first thing the engine do from the public entries, so if
somethings goes wrong here, we don't have enough information about the
procedure and we can't recover from the error. We have to raise exception
back to the application.
Arguments :
Return :
RPC_S_OK if
--*/
void RPC_ENTRY
Ndr64ClientInitializeContext(
SYNTAX_TYPE SyntaxType,
const MIDL_STUBLESS_PROXY_INFO * pProxyInfo,
ulong nProcNum,
NDR_PROC_CONTEXT * pContext,
uchar * StartofStack )
{
PFORMAT_STRING pFormat;
RPC_STATUS res = RPC_S_OK;
MIDL_SYNTAX_INFO * pSyntaxInfo = NULL;
ulong i;
pContext->StartofStack = StartofStack;
for ( i = 0; i < pProxyInfo->nCount; i ++ )
if ( SyntaxType == NdrpGetSyntaxType( &pProxyInfo->pSyntaxInfo[i].TransferSyntax ) )
{
pSyntaxInfo = & pProxyInfo->pSyntaxInfo[i];
break;
}
// We can't do much if we are reading invalid format string
if ( NULL == pSyntaxInfo )
RpcRaiseException( RPC_S_UNSUPPORTED_TRANS_SYN );
else
{
pFormat = NdrpGetProcString( pSyntaxInfo, SyntaxType, nProcNum );
MulNdrpInitializeContextFromProc( SyntaxType, pFormat, pContext, StartofStack );
pContext->pSyntaxInfo = pSyntaxInfo;
}
}
// Fill in RPC_CLIENT_INTERFACE in rpcmessage if the proxy only support one transfer syntax.
__inline
HRESULT NdrpDcomSetupSimpleClientInterface(
MIDL_STUB_MESSAGE * pStubMsg,
RPC_CLIENT_INTERFACE * pClientIf,
const IID * riid,
MIDL_STUBLESS_PROXY_INFO * pProxyInfo )
{
memset(pClientIf, 0, sizeof( RPC_CLIENT_INTERFACE ) );
pClientIf->Length = sizeof( RPC_CLIENT_INTERFACE );
pClientIf->InterfaceId.SyntaxGUID = *riid;
memcpy(&pClientIf->TransferSyntax,
pProxyInfo->pTransferSyntax,
sizeof(RPC_SYNTAX_IDENTIFIER) );
pClientIf->InterpreterInfo = pProxyInfo;
pStubMsg->RpcMsg->RpcInterfaceInformation = pClientIf;
return S_OK;
}
RPC_STATUS RPC_ENTRY
Ndr64pClientSetupTransferSyntax( void * pThis,
RPC_MESSAGE * pRpcMsg,
MIDL_STUB_MESSAGE * pStubMsg,
MIDL_STUBLESS_PROXY_INFO * pProxyInfo,
NDR_PROC_CONTEXT * pContext,
ulong nProcNum )
{
const MIDL_STUB_DESC * pStubDesc = pProxyInfo->pStubDesc;
RPC_STATUS res = S_OK;
// setup vtbl first so we can recover from error
Ndr64SetupClientContextVtbl( pContext );
pStubMsg->pContext = pContext;
pStubMsg->StackTop = pContext->StartofStack;
if ( pThis )
{
ulong SyncProcNum;
// In DCOM async interface, the proc number in rpcmessage is the sync method id
// instead of async methodid, so we need to setup the proxy differently.
if ( pContext->IsAsync )
SyncProcNum = (nProcNum + 3 ) / 2;
else
SyncProcNum = nProcNum;
Ndr64ProxyInitialize( pThis,
pRpcMsg,
pStubMsg,
pProxyInfo,
SyncProcNum );
}
else
{
handle_t Handle;
PFNEXPLICITBINDHANDLEMGR pfnExpBindMgr = NULL;
PFNIMPLICITBINDHANDLEMGR pfnImpBindMgr = NULL;
if ( pContext->CurrentSyntaxType == XFER_SYNTAX_NDR64 )
{
pfnExpBindMgr = &Ndr64ExplicitBindHandleMgr;
pfnImpBindMgr = &Ndr64ImplicitBindHandleMgr;
}
else
{
pfnExpBindMgr = &ExplicitBindHandleMgr;
pfnImpBindMgr = &ImplicitBindHandleMgr;
}
Ndr64ClientInitialize( pRpcMsg,
pStubMsg,
pProxyInfo,
(uint) nProcNum );
if ( pContext->HandleType )
{
//
// We have an implicit handle.
//
Handle = (*pfnImpBindMgr)( pStubDesc,
pContext->HandleType,
&(pContext->SavedGenericHandle) );
}
else
{
PFORMAT_STRING pFormat;
if ( pContext->CurrentSyntaxType == XFER_SYNTAX_DCE )
pFormat = (PFORMAT_STRING) pContext->pHandleFormatSave;
else
pFormat = (uchar *) pContext->Ndr64Header+ sizeof(NDR64_PROC_FORMAT);
Handle = (*pfnExpBindMgr)( pStubDesc,
pContext->StartofStack,
pFormat,
&(pContext->SavedGenericHandle ) );
}
pStubMsg->RpcMsg->Handle = pStubMsg->SavedHandle = Handle;
}
pStubMsg->RpcMsg->RpcFlags = pContext->RpcFlags;
// The client only negotiates when the stub support more than one
// transfer syntax.
if ( pProxyInfo->nCount > 1 )
{
res = Ndr64ClientNegotiateTransferSyntax( pThis,
pStubMsg,
pProxyInfo,
pContext );
if ( RPC_S_OK == res )
{
PFORMAT_STRING pFormat;
SYNTAX_TYPE SyntaxType;
ulong i = 0;
SyntaxType = NdrpGetSyntaxType( pStubMsg->RpcMsg->TransferSyntax );
if ( SyntaxType != pContext->CurrentSyntaxType )
{
for (i = 0; i < pProxyInfo->nCount; i++)
{
if ( SyntaxType == NdrpGetSyntaxType( &pProxyInfo->pSyntaxInfo[i].TransferSyntax ) )
{
pContext->pSyntaxInfo = &( pProxyInfo->pSyntaxInfo[i] );
break;
}
}
NDR_ASSERT( i < pProxyInfo->nCount, "can't find the right syntax" );
// Reread the format string if we select a different transfer syntax
pFormat = NdrpGetProcString( pContext->pSyntaxInfo,
SyntaxType,
nProcNum );
MulNdrpInitializeContextFromProc( SyntaxType ,
pFormat,
pContext,
pContext->StartofStack,
TRUE ); // reset
Ndr64SetupClientContextVtbl( pContext );
}
}
}
else
{
pContext->pSyntaxInfo = pProxyInfo->pSyntaxInfo;
// we need to fake the RPC_CLIENT_INTERFACE if client only support NDR64
if ( pThis )
{
const IID * riid;
RPC_CLIENT_INTERFACE * pClientIf;
pClientIf = (RPC_CLIENT_INTERFACE *)NdrpAlloca( &pContext->AllocateContext, sizeof( RPC_CLIENT_INTERFACE ) );
if ( pContext->IsAsync )
{
riid = NdrGetSyncProxyIID( pThis );
}
else
riid = NdrGetProxyIID(pThis);
NdrpDcomSetupSimpleClientInterface( pStubMsg,
pClientIf,
riid,
pProxyInfo );
}
}
return res;
}
HRESULT NdrpDcomNegotiateSyntax( void * pThis,
MIDL_STUB_MESSAGE *pStubMsg,
MIDL_STUBLESS_PROXY_INFO * pProxyInfo,
NDR_PROC_CONTEXT * pContext
)
{
IRpcSyntaxNegotiate * pNegotiate = NULL;
IRpcChannelBuffer * pChannel = pStubMsg->pRpcChannelBuffer;
HRESULT hr = E_FAIL ;
ulong nPrefer;
const IID * riid;
RPC_CLIENT_INTERFACE * pclientIf;
pclientIf = ( RPC_CLIENT_INTERFACE * ) NdrpAlloca( &pContext->AllocateContext, sizeof( RPC_CLIENT_INTERFACE ) );
if ( pContext->IsAsync )
{
riid = NdrGetSyncProxyIID( pThis );
}
else
riid = NdrGetProxyIID(pThis);
hr = pChannel->lpVtbl->QueryInterface( pChannel, IID_IRpcSyntaxNegotiate, (void **)&pNegotiate );
if ( SUCCEEDED( hr ) )
{
// create RPC_CLIENT_INTERFACE here.
memset(pclientIf, 0, sizeof( RPC_CLIENT_INTERFACE ) );
pclientIf->Length = sizeof( RPC_CLIENT_INTERFACE ) ;
pclientIf->InterfaceId.SyntaxGUID = *riid;
memcpy(&pclientIf->TransferSyntax,
pProxyInfo->pTransferSyntax,
sizeof(RPC_SYNTAX_IDENTIFIER) );
pclientIf->InterpreterInfo = pProxyInfo;
pclientIf->Flags |= RPCFLG_HAS_MULTI_SYNTAXES;
pStubMsg->RpcMsg->RpcInterfaceInformation = pclientIf;
hr = pNegotiate->lpVtbl->NegotiateSyntax( pNegotiate, (RPCOLEMESSAGE *)pStubMsg->RpcMsg );
// OLE will return S_FALSE in local server case, where OLE doesn't involve RPC runtime
// to send package, such that I_RpcNegotiateSyntax can't be called.
if ( hr == S_FALSE )
{
NdrpGetPreferredSyntax( (ulong )pProxyInfo->nCount, pProxyInfo->pSyntaxInfo, &nPrefer );
pStubMsg->RpcMsg->TransferSyntax = &pProxyInfo->pSyntaxInfo[nPrefer].TransferSyntax;
hr = S_OK;
}
pNegotiate->lpVtbl->Release( pNegotiate );
}
else
{
// old style proxy
hr = NdrpDcomSetupSimpleClientInterface( pStubMsg, pclientIf, riid, pProxyInfo );
}
return hr;
}
RPC_STATUS RPC_ENTRY
Ndr64ClientNegotiateTransferSyntax(
void * pThis,
MIDL_STUB_MESSAGE *pStubMsg,
MIDL_STUBLESS_PROXY_INFO *pProxyInfo,
NDR_PROC_CONTEXT *pContext )
{
RPC_STATUS status = RPC_S_UNSUPPORTED_TRANS_SYN ;
RPC_MESSAGE *pRpcMsg = pStubMsg->RpcMsg;
const MIDL_STUB_DESC * pStubDesc = pProxyInfo->pStubDesc;
ulong i;
ushort FormatOffset;
ushort * pFormat;
uchar HandleType;
HRESULT hr;
SYNTAX_TYPE SyntaxType;
if ( pThis )
{
hr = NdrpDcomNegotiateSyntax( pThis, pStubMsg, pProxyInfo, pContext );
if ( FAILED( hr ) )
RpcRaiseException( hr );
status = RPC_S_OK;
}
else
{
if ( pContext->UseLocator )
{
// call into locator's negotiation code
EnsureNSLoaded();
status = (*pRpcNsNegotiateTransferSyntax)( pStubMsg->RpcMsg );
}
else
{
status = I_RpcNegotiateTransferSyntax( pStubMsg->RpcMsg );
}
if ( status != RPC_S_OK )
RpcRaiseException( status );
}
return status;
}
void RPC_ENTRY
Ndr64pSizing( MIDL_STUB_MESSAGE * pStubMsg,
BOOL IsClient )
{
long n;
uchar * pArg;
NDR64_PARAM_FLAGS * pParamFlags;
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
NDR64_PARAM_FORMAT * Params =
(NDR64_PARAM_FORMAT*)pContext->Params;
CORRELATION_CONTEXT CorrCtxt( pStubMsg, pContext->StartofStack );
for (ulong n = 0; n < pContext->NumberParams; n++ )
{
pParamFlags = ( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
if ( IsClient && pParamFlags->IsPartialIgnore )
{
LENGTH_ALIGN(pStubMsg->BufferLength, NDR64_PTR_WIRE_ALIGN );
pStubMsg->BufferLength += sizeof(NDR64_PTR_WIRE_TYPE);
continue;
}
if ( !NDR64SAMEDIRECTION(IsClient, pParamFlags) ||
! ( pParamFlags->MustSize ) )
continue;
//
// Note : Basetypes will always be factored into the
// constant buffer size emitted by in the format strings.
//
pArg = pContext->StartofStack + Params[n].StackOffset;
if ( ! pParamFlags->IsByValue )
pArg = *((uchar **)pArg);
Ndr64TopLevelTypeSize( pStubMsg,
pArg,
Params[n].Type );
}
}
void
Ndr64ClientZeroOut(
PMIDL_STUB_MESSAGE pStubMsg,
PNDR64_FORMAT pFormat,
uchar * pArg
)
{
const NDR64_POINTER_FORMAT *pPointerFormat =
(const NDR64_POINTER_FORMAT*)pFormat;
//
// In an object proc, we must zero all [out] unique and interface
// pointers which occur as the referent of a ref pointer or embedded in a
// structure or union.
//
// Let's not die on a null ref pointer.
if ( !pArg )
return;
//
// The only top level [out] type allowed is a ref pointer or an array.
//
if ( *(PFORMAT_STRING)pFormat == FC64_RP )
{
pFormat = pPointerFormat->Pointee;
// Double pointer.
if ( NDR64_POINTER_DEREF( pPointerFormat->Flags ) )
{
*((void **)pArg) = 0;
return;
}
// we need to zero out basetype because it might be conformant/
// varying descriptor.
if ( NDR64_SIMPLE_POINTER( pPointerFormat->Flags ) )
{
MIDL_memset( pArg, 0,
(uint) NDR64_SIMPLE_TYPE_MEMSIZE( *(PFORMAT_STRING)pFormat ) );
return;
}
}
NDR64_UINT32 Size = Ndr64pMemorySize( pStubMsg,
pFormat,
FALSE );
MIDL_memset( pArg, 0, (size_t)Size );
}
void RPC_ENTRY
Ndr64pClientInit( MIDL_STUB_MESSAGE * pStubMsg,
void * pReturnValue )
{
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
NDR64_PROC_FORMAT * pHeader = pContext->Ndr64Header;
BOOL fRaiseExcFlag = FALSE;
ulong n;
uchar * pArg;
NDR64_PARAM_FORMAT * Params;
NDR64_PROC_FLAGS * pNdr64Flags;
NDR64_PARAM_FLAGS * pParamFlags;
pNdr64Flags = (NDR64_PROC_FLAGS * )&(pHeader->Flags) ;
Params = ( NDR64_PARAM_FORMAT *) pContext->Params;
if ( pNdr64Flags->UsesFullPtrPackage )
pStubMsg->FullPtrXlatTables = NdrFullPointerXlatInit( 0, XLAT_CLIENT );
else
pStubMsg->FullPtrXlatTables = 0;
if ( pNdr64Flags->UsesRpcSmPackage )
NdrRpcSmSetClientToOsf( pStubMsg );
if ( pNdr64Flags->UsesPipes )
NdrpPipesInitialize64( pStubMsg,
&pContext->AllocateContext,
(PFORMAT_STRING) Params,
(char *)pContext->StartofStack,
pContext->NumberParams );
pStubMsg->StackTop = pContext->StartofStack;
pStubMsg->pCorrMemory = pStubMsg->StackTop;
// get initial size here: we might not need to get into sizing code.
pStubMsg->BufferLength = pHeader->ConstantClientBufferSize;
for ( n = 0; n < pContext->NumberParams; n++ )
{
pParamFlags = ( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
if ( pParamFlags->IsReturn )
pArg = (uchar *) &pReturnValue;
else
pArg = pContext->StartofStack + Params[n].StackOffset;
if ( pParamFlags->IsSimpleRef && !pParamFlags->IsReturn )
{
// We cannot raise the exception here,
// as some out args may not be zeroed out yet.
if ( ! *((uchar **)pArg) )
{
fRaiseExcFlag = TRUE;
continue;
}
}
// if top level point is ref pointer and the stack is NULL, we'll catch this
// before the call goes to server.
if ( pParamFlags->IsOut && !pParamFlags->IsBasetype )
{
if ( *(PFORMAT_STRING) Params[n].Type == FC64_RP && !*((uchar **)pArg) )
{
fRaiseExcFlag = TRUE;
continue;
}
}
if ( ( pNdr64Flags->IsObject &&
! pContext->IsAsync &&
( pParamFlags->IsPartialIgnore ||
( ! pParamFlags->IsIn &&
! pParamFlags->IsReturn &&
! pParamFlags->IsPipe ) ) ) ||
( pNdr64Flags->HasComplexReturn &&
pParamFlags->IsReturn ) )
{
if ( pParamFlags->IsBasetype )
{
// [out] only arg can only be ref, we checked that above.
NDR64_FORMAT_CHAR type = *(PFORMAT_STRING) Params[n].Type;
MIDL_memset( *(uchar **)pArg,
0,
(size_t)NDR64_SIMPLE_TYPE_MEMSIZE( type ));
}
else
{
Ndr64ClientZeroOut(
pStubMsg,
Params[n].Type,
*(uchar **)pArg );
}
}
}
if ( fRaiseExcFlag )
RpcRaiseException( RPC_X_NULL_REF_POINTER );
if ( pNdr64Flags->ClientMustSize )
{
if ( pNdr64Flags->UsesPipes )
RpcRaiseException( RPC_X_WRONG_PIPE_VERSION );
}
else
pContext->pfnSizing = (PFNSIZING)NdrpNoopSizing;
}
void RPC_ENTRY
Ndr64pDcomClientExceptionHandling( MIDL_STUB_MESSAGE * pStubMsg,
ulong ProcNum,
RPC_STATUS ExceptionCode,
CLIENT_CALL_RETURN * pReturnValue )
{
ulong NumberParams ;
NDR64_PARAM_FORMAT * Params ;
ulong n;
uchar * pArg;
NDR64_PARAM_FLAGS * pParamFlags;
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
pReturnValue->Simple = NdrProxyErrorHandler(ExceptionCode);
if( pStubMsg->dwStubPhase != PROXY_UNMARSHAL)
return ;
NumberParams = pContext->NumberParams;
Params = ( NDR64_PARAM_FORMAT * ) pContext->Params;
//
// Set the Buffer endpoints so the Ndr64Free routines work.
//
pStubMsg->BufferStart = 0;
pStubMsg->BufferEnd = 0;
for ( n = 0; n < NumberParams; n++ )
{
pParamFlags = ( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
//
// Skip everything but [out] only parameters. We make
// the basetype check to cover [out] simple ref pointers
// to basetypes.
//
if ( !pParamFlags->IsPartialIgnore )
{
if ( pParamFlags->IsIn ||
pParamFlags->IsReturn ||
pParamFlags->IsBasetype ||
pParamFlags->IsPipe )
continue;
}
pArg = pContext->StartofStack + Params[n].StackOffset;
Ndr64ClearOutParameters( pStubMsg,
Params[n].Type,
*((uchar **)pArg) );
}
return ;
}
void RPC_ENTRY
Ndr64pClientExceptionHandling( MIDL_STUB_MESSAGE * pStubMsg,
ulong ProcNum,
RPC_STATUS ExceptionCode,
CLIENT_CALL_RETURN * pReturnValue )
{
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
if ( ( (NDR64_PROC_FLAGS *) & pContext->Ndr64Header->Flags)->HandlesExceptions )
{
NdrClientMapCommFault( pStubMsg,
ProcNum,
ExceptionCode,
(ULONG_PTR*)&pReturnValue->Simple );
}
else
{
RpcRaiseException(ExceptionCode);
}
return;
}
void RPC_ENTRY
Ndr64pClientMarshal( MIDL_STUB_MESSAGE * pStubMsg,
BOOL IsObject )
{
NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT *) pStubMsg->pContext;
// if ( (ULONG_PTR)pStubMsg->Buffer & 15 )
// RpcRaiseException( RPC_X_INVALID_BUFFER );
CORRELATION_CONTEXT CorrCtxt( pStubMsg, pContext->StartofStack );
NDR64_PARAM_FORMAT *Params = (NDR64_PARAM_FORMAT *) pContext->Params;
for ( ulong n = 0; n < pContext->NumberParams; n++ )
{
NDR64_PARAM_FLAGS *pParamFlags =
( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
uchar *pArg = pContext->StartofStack + Params[n].StackOffset;
if ( pParamFlags->IsPartialIgnore )
{
ALIGN( pStubMsg->Buffer, NDR64_PTR_WIRE_ALIGN );
*((NDR64_PTR_WIRE_TYPE*)pStubMsg->Buffer) = (*pArg) ? (NDR64_PTR_WIRE_TYPE)1 :
(NDR64_PTR_WIRE_TYPE)0;
pStubMsg->Buffer += sizeof(NDR64_PTR_WIRE_TYPE);
continue;
}
if ( !pParamFlags->IsIn ||
pParamFlags->IsPipe )
continue;
if ( pParamFlags->IsBasetype )
{
NDR64_FORMAT_CHAR type = *(PFORMAT_STRING)Params[n].Type;
//
// Check for pointer to basetype.
//
if ( pParamFlags->IsSimpleRef )
pArg = *((uchar **)pArg);
else
{
#ifdef _IA64_
if ( !IsObject && type == FC64_FLOAT32 )
{
// Due to the fact that NdrClientCall2 is called with the
// parameters in ... arguments, floats get promoted to doubles.
// This is not true for DCOM since an assembly langauge wrapper
// is used that saves the floats as floats.
//
// BUG, BUG. IA64 passes byval structures that consist
// entirely of float fields with each field in a separate register.
// We do not handle this case properly.
*((float *) pArg) = (float) *((double *)pArg);
}
#endif
}
ALIGN( pStubMsg->Buffer, NDR64_SIMPLE_TYPE_BUFALIGN( type ) );
RpcpMemoryCopy(
pStubMsg->Buffer,
pArg,
NDR64_SIMPLE_TYPE_BUFSIZE( type ) );
pStubMsg->Buffer +=
NDR64_SIMPLE_TYPE_BUFSIZE( type );
continue;
}
if ( ! pParamFlags->IsByValue )
pArg = *((uchar **)pArg);
Ndr64TopLevelTypeMarshall( pStubMsg,
pArg,
Params[n].Type );
}
if ( pStubMsg->RpcMsg->BufferLength <
(uint)(pStubMsg->Buffer - (uchar *)pStubMsg->RpcMsg->Buffer) )
{
NDR_ASSERT( 0, "Ndr64pClientmarshal: buffer overflow!" );
RpcRaiseException( RPC_X_BAD_STUB_DATA );
}
}
void RPC_ENTRY
Ndr64pServerMarshal( MIDL_STUB_MESSAGE * pStubMsg )
{
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
// if ( (ULONG_PTR)pStubMsg->Buffer & 15 )
// RpcRaiseException( RPC_X_INVALID_BUFFER );
CORRELATION_CONTEXT CorrCtxt( pStubMsg, pContext->StartofStack );
NDR64_PARAM_FORMAT *Params = (NDR64_PARAM_FORMAT *) pContext->Params;
for ( ulong n = 0; n < pContext->NumberParams; n++ )
{
NDR64_PARAM_FLAGS *pParamFlags = ( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
uchar *pArg = pContext->StartofStack + Params[n].StackOffset;
if (!pParamFlags->IsOut ||
pParamFlags->IsPipe )
continue;
if ( pParamFlags->IsBasetype )
{
NDR64_FORMAT_CHAR type = *(PFORMAT_STRING)Params[n].Type;
//
// Check for pointer to basetype.
//
if ( pParamFlags->IsSimpleRef )
pArg = *((uchar **)pArg);
ALIGN( pStubMsg->Buffer, NDR64_SIMPLE_TYPE_BUFALIGN( type ) );
RpcpMemoryCopy(
pStubMsg->Buffer,
pArg,
NDR64_SIMPLE_TYPE_BUFSIZE( type ) );
pStubMsg->Buffer +=
NDR64_SIMPLE_TYPE_BUFSIZE( type );
continue;
}
if ( ! pParamFlags->IsByValue )
pArg = *((uchar **)pArg);
Ndr64TopLevelTypeMarshall( pStubMsg,
pArg,
Params[n].Type);
}
if ( pStubMsg->RpcMsg->BufferLength <
(uint)(pStubMsg->Buffer - (uchar *)pStubMsg->RpcMsg->Buffer) )
{
NDR_ASSERT( 0, "Ndr64pCompleteAsyncServerCall marshal: buffer overflow!" );
RpcRaiseException( RPC_X_BAD_STUB_DATA );
}
}
void RPC_ENTRY
Ndr64pClientUnMarshal ( MIDL_STUB_MESSAGE * pStubMsg,
void * pReturnValue )
{
uchar * pArg;
NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT *) pStubMsg->pContext;
NDR64_PARAM_FORMAT *Params = (NDR64_PARAM_FORMAT *)pContext->Params;
// if ( (ULONG_PTR)pStubMsg->Buffer & 15 )
// RpcRaiseException( RPC_X_INVALID_BUFFER );
CORRELATION_CONTEXT( pStubMsg, pContext->StartofStack );
//
// ----------------------------------------------------------
// Unmarshall Pass.
// ----------------------------------------------------------
//
for ( ulong n = 0; n < pContext->NumberParams; n++ )
{
NDR64_PARAM_FLAGS *pParamFlags = ( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
if ( pParamFlags->IsPipe )
continue;
if ( !pParamFlags->IsOut )
{
if ( !pParamFlags->IsIn && !pParamFlags->IsReturn )
{
// If a param is not [in], [out], or a return value,
// then it is a "hidden" client-side only status
// paramater. It will get set below if an exception
// happens. If everything is ok we need to zero it
// out here.
NDR_ASSERT( pParamFlags->IsSimpleRef
&& pParamFlags->IsBasetype
&& FC64_ERROR_STATUS_T ==
*(PFORMAT_STRING)Params[n].Type,
"Apparently not a hidden status param" );
pArg = pContext->StartofStack + Params[n].StackOffset;
** (error_status_t **) pArg = RPC_S_OK;
}
continue;
}
if ( pParamFlags->IsReturn )
{
if ( ! pReturnValue )
RpcRaiseException( RPC_S_INVALID_ARG );
pArg = (uchar *) pReturnValue;
}
else
pArg = pContext->StartofStack + Params[n].StackOffset;
//
// This is for returned basetypes and for pointers to
// basetypes.
//
if ( pParamFlags->IsBasetype )
{
NDR64_FORMAT_CHAR type = *(PFORMAT_STRING)Params[n].Type;
//
// Check for a pointer to a basetype.
//
if ( pParamFlags->IsSimpleRef )
pArg = *((uchar **)pArg);
ALIGN( pStubMsg->Buffer, NDR64_SIMPLE_TYPE_BUFALIGN( type ) );
RpcpMemoryCopy(
pArg,
pStubMsg->Buffer,
NDR64_SIMPLE_TYPE_BUFSIZE( type ) );
pStubMsg->Buffer +=
NDR64_SIMPLE_TYPE_BUFSIZE( type );
continue;
}
uchar **ppArg = pParamFlags->IsByValue ? &pArg : (uchar **)pArg;
//
// Transmit/Represent as can be passed as [out] only, thus
// the IsByValue check.
//
Ndr64TopLevelTypeUnmarshall( pStubMsg,
ppArg,
Params[n].Type,
false );
}
if ( pStubMsg->pCorrInfo )
Ndr64CorrelationPass( pStubMsg );
return ;
}
void RPC_ENTRY
Ndr64pClientFinally( PMIDL_STUB_MESSAGE pStubMsg,
void * pThis )
{
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
PMIDL_STUB_DESC pStubDesc = pStubMsg->StubDesc;
NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables);
//
// Free the RPC buffer.
//
if ( pThis )
{
NdrProxyFreeBuffer( pThis, pStubMsg );
}
else
{
NdrFreeBuffer( pStubMsg );
//
// Unbind if generic handle used. We do this last so that if the
// the user's unbind routine faults, then all of our internal stuff
// will already have been freed.
//
if ( pContext->SavedGenericHandle )
Ndr64GenericHandleUnbind( pStubDesc,
pContext->StartofStack,
(uchar *)pContext->Ndr64Header+ sizeof(NDR64_PROC_FORMAT),
(pContext->HandleType) ? IMPLICIT_MASK : 0,
&pContext->SavedGenericHandle );
}
NdrpAllocaDestroy( & pContext->AllocateContext );
}
void
Ndr64pServerOutInit( PMIDL_STUB_MESSAGE pStubMsg )
{
NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT *) pStubMsg->pContext;
NDR64_PARAM_FLAGS * pParamFlags;
NDR64_PARAM_FORMAT* Params = (NDR64_PARAM_FORMAT*)pContext->Params;
NDR64_PROC_FLAGS * pNdr64Flags = (NDR64_PROC_FLAGS *)&pContext->Ndr64Header->Flags;
uchar * pArg;
for ( ulong n = 0; n < pContext->NumberParams; n++ )
{
pParamFlags = ( NDR64_PARAM_FLAGS * ) & ( Params[n].Attributes );
if ( !pParamFlags->IsPartialIgnore )
{
if ( pParamFlags->IsIn ||
(pParamFlags->IsReturn && !pNdr64Flags->HasComplexReturn) ||
pParamFlags->IsPipe )
continue;
pArg = pContext->StartofStack + Params[n].StackOffset;
}
else
{
pArg = pContext->StartofStack + Params[n].StackOffset;
if ( !*(void**)pArg )
continue;
}
//
// Check if we can initialize this parameter using some of our
// stack.
//
if ( pParamFlags->UseCache )
{
*((void **)pArg) = NdrpAlloca( &pContext->AllocateContext, 64 );
MIDL_memset( *((void **)pArg),
0,
64 );
continue;
}
else if ( pParamFlags->IsBasetype )
{
*((void **)pArg) = NdrpAlloca( &pContext->AllocateContext,8);
MIDL_memset( *((void **)pArg), 0, 8 );
continue;
};
Ndr64OutInit( pStubMsg,
Params[n].Type,
(uchar **)pArg );
}
}
#pragma code_seg()