1475 lines
48 KiB
C++
1475 lines
48 KiB
C++
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|||
|
|
|||
|
Copyright (c) 1999-2000 Microsoft Corporation
|
|||
|
|
|||
|
Module Name :
|
|||
|
|
|||
|
mulsyntx.cxx
|
|||
|
|
|||
|
Abstract :
|
|||
|
|
|||
|
This file contains multiple transfer syntaxes negotiation related code
|
|||
|
|
|||
|
Author :
|
|||
|
|
|||
|
Yong Qu yongqu September 1999.
|
|||
|
|
|||
|
Revision History :
|
|||
|
|
|||
|
|
|||
|
---------------------------------------------------------------------*/
|
|||
|
|
|||
|
|
|||
|
#include "ndrp.h"
|
|||
|
#define CINTERFACE
|
|||
|
#include "ndrole.h"
|
|||
|
#include "rpcproxy.h"
|
|||
|
#include "mulsyntx.h"
|
|||
|
#include "hndl.h"
|
|||
|
#include "auxilary.h"
|
|||
|
#include "pipendr.h"
|
|||
|
#include "ndr64tkn.h"
|
|||
|
|
|||
|
const extern PMARSHALL_ROUTINE MarshallRoutinesTable[];
|
|||
|
const extern PUNMARSHALL_ROUTINE UnmarshallRoutinesTable[];
|
|||
|
const extern PSIZE_ROUTINE SizeRoutinesTable[];
|
|||
|
const extern PMEM_SIZE_ROUTINE MemSizeRoutinesTable[];
|
|||
|
const extern PFREE_ROUTINE FreeRoutinesTable[];
|
|||
|
//const extern PWALKIP_ROUTINE WalkIPRoutinesTable[];
|
|||
|
|
|||
|
// TODO: move this to ndrpall.h after Preview.
|
|||
|
#define MIDL_VERSION_6_0_322 ((6UL << 24) | (0UL << 16) | 322UL)
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrpClientInit(MIDL_STUB_MESSAGE * pStubMsg,
|
|||
|
void * pReturnValue )
|
|||
|
{
|
|||
|
PFORMAT_STRING pFormatParam;
|
|||
|
ulong ProcNum;
|
|||
|
BOOL fRaiseExcFlag;
|
|||
|
ulong n;
|
|||
|
uchar * pArg;
|
|||
|
INTERPRETER_FLAGS InterpreterFlags;
|
|||
|
PPARAM_DESCRIPTION Params;
|
|||
|
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *) pStubMsg->pContext;
|
|||
|
INTERPRETER_OPT_FLAGS OptFlags = pContext->NdrInfo.pProcDesc->Oi2Flags;
|
|||
|
PFORMAT_STRING pTypeFormat;
|
|||
|
|
|||
|
// When this routine is called from ndrclientcall2, we don't have MIDL_SYNTAX_INFO,
|
|||
|
// so we need to read it from MIDL_STUB_DESC;
|
|||
|
// Note: we need to conenct StubDesc to pStubMsg before calling into here.
|
|||
|
if ( NULL == pContext->pSyntaxInfo )
|
|||
|
pContext->DceTypeFormatString = pStubMsg->StubDesc->pFormatTypes;
|
|||
|
else
|
|||
|
pContext->DceTypeFormatString = pContext->pSyntaxInfo->TypeString;
|
|||
|
|
|||
|
InterpreterFlags = pContext->NdrInfo.InterpreterFlags;
|
|||
|
Params = ( PPARAM_DESCRIPTION )pContext->Params;
|
|||
|
pTypeFormat = pContext->DceTypeFormatString;
|
|||
|
|
|||
|
if ( InterpreterFlags.FullPtrUsed )
|
|||
|
pStubMsg->FullPtrXlatTables = NdrFullPointerXlatInit( 0, XLAT_CLIENT );
|
|||
|
else
|
|||
|
pStubMsg->FullPtrXlatTables = 0;
|
|||
|
|
|||
|
if ( InterpreterFlags.RpcSsAllocUsed )
|
|||
|
NdrRpcSmSetClientToOsf( pStubMsg );
|
|||
|
|
|||
|
// Set Rpc flags after the call to client initialize.
|
|||
|
pStubMsg->RpcMsg->RpcFlags = pContext->RpcFlags;
|
|||
|
|
|||
|
if ( OptFlags.HasPipes )
|
|||
|
NdrpPipesInitialize32( pStubMsg,
|
|||
|
&pContext->AllocateContext,
|
|||
|
(PFORMAT_STRING) pContext->Params,
|
|||
|
( char * )pContext->StartofStack,
|
|||
|
pContext->NumberParams );
|
|||
|
|
|||
|
// Must do this before the sizing pass!
|
|||
|
pStubMsg->StackTop = pContext->StartofStack;
|
|||
|
|
|||
|
if ( OptFlags.HasExtensions )
|
|||
|
{
|
|||
|
pStubMsg->fHasExtensions = 1;
|
|||
|
pStubMsg->fHasNewCorrDesc = pContext->NdrInfo.pProcDesc->NdrExts.Flags2.HasNewCorrDesc;
|
|||
|
if ( pContext->NdrInfo.pProcDesc->NdrExts.Flags2.ClientCorrCheck )
|
|||
|
{
|
|||
|
ulong *pCache =
|
|||
|
(ulong*)NdrpAlloca(&pContext->AllocateContext,
|
|||
|
NDR_DEFAULT_CORR_CACHE_SIZE );
|
|||
|
|
|||
|
NdrCorrelationInitialize( pStubMsg,
|
|||
|
pCache,
|
|||
|
NDR_DEFAULT_CORR_CACHE_SIZE,
|
|||
|
0 /* flags */ );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Get the compile time computed buffer size.
|
|||
|
//
|
|||
|
pStubMsg->BufferLength = pContext->NdrInfo.pProcDesc->ClientBufferSize;
|
|||
|
|
|||
|
//
|
|||
|
// Check ref pointers and do object proc [out] zeroing.
|
|||
|
//
|
|||
|
|
|||
|
fRaiseExcFlag = FALSE;
|
|||
|
|
|||
|
for ( n = 0; n < pContext->NumberParams; n++ )
|
|||
|
{
|
|||
|
if ( Params[n].ParamAttr.IsReturn )
|
|||
|
pArg = (uchar *) &pReturnValue;
|
|||
|
else
|
|||
|
pArg = pContext->StartofStack + Params[n].StackOffset;
|
|||
|
|
|||
|
if ( Params[n].ParamAttr.IsSimpleRef && !Params[n].ParamAttr.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 FC_RP and the arg is NULL, we'll catch this
|
|||
|
// before the call goes to server.
|
|||
|
// We wouldn't catch all the null ref pointer here, but we should be able
|
|||
|
// to catch the most obvious ones.
|
|||
|
// This code is called from sync & raw async code; in async dcom,
|
|||
|
// we only go through outinit in finish routine so we can't do anything anyhow.
|
|||
|
if ( Params[n].ParamAttr.IsOut && ! Params[n].ParamAttr.IsBasetype )
|
|||
|
{
|
|||
|
pFormatParam = pTypeFormat + Params[n].TypeOffset;
|
|||
|
if ( * pFormatParam == FC_RP && !*((uchar **)pArg) )
|
|||
|
{
|
|||
|
fRaiseExcFlag = TRUE;
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// In object procs and complex return types we have to zero
|
|||
|
// out all [out] parameters. We do the basetype check to
|
|||
|
// cover the [out] simple ref to basetype case.
|
|||
|
//
|
|||
|
if ( ( InterpreterFlags.ObjectProc &&
|
|||
|
! pContext->IsAsync &&
|
|||
|
( Params[n].ParamAttr.IsPartialIgnore ||
|
|||
|
( ! Params[n].ParamAttr.IsIn &&
|
|||
|
! Params[n].ParamAttr.IsReturn &&
|
|||
|
! Params[n].ParamAttr.IsPipe ) ) ) ||
|
|||
|
( pContext->HasComplexReturn &&
|
|||
|
Params[n].ParamAttr.IsReturn ) )
|
|||
|
{
|
|||
|
if ( Params[n].ParamAttr.IsBasetype )
|
|||
|
{
|
|||
|
// [out] only arg can only be ref, we checked that above.
|
|||
|
MIDL_memset( *(uchar **)pArg,
|
|||
|
0,
|
|||
|
(size_t)SIMPLE_TYPE_MEMSIZE( Params[n].SimpleType.Type ));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pFormatParam = pTypeFormat +
|
|||
|
Params[n].TypeOffset;
|
|||
|
|
|||
|
NdrClientZeroOut(
|
|||
|
pStubMsg,
|
|||
|
pFormatParam,
|
|||
|
*(uchar **)pArg );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( fRaiseExcFlag )
|
|||
|
RpcRaiseException( RPC_X_NULL_REF_POINTER );
|
|||
|
|
|||
|
if ( OptFlags.ClientMustSize )
|
|||
|
{
|
|||
|
// Compiler prevents variable size non-pipe args for NT v.4.0.
|
|||
|
|
|||
|
if ( OptFlags.HasPipes )
|
|||
|
RpcRaiseException( RPC_X_WRONG_PIPE_VERSION );
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
pContext->pfnSizing = (PFNSIZING)NdrpNoopSizing;
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrpNoopSizing( MIDL_STUB_MESSAGE * pStubMsg,
|
|||
|
BOOL IsClient )
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrpSizing( MIDL_STUB_MESSAGE * pStubMsg,
|
|||
|
BOOL IsClient )
|
|||
|
{
|
|||
|
PFORMAT_STRING pFormatParam;
|
|||
|
ulong n;
|
|||
|
uchar * pArg;
|
|||
|
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
|
|||
|
PPARAM_DESCRIPTION Params = ( PPARAM_DESCRIPTION )pContext->Params;
|
|||
|
PFORMAT_STRING pTypeFormat = pContext->DceTypeFormatString;
|
|||
|
|
|||
|
//
|
|||
|
// Skip buffer size pass if possible.
|
|||
|
//
|
|||
|
|
|||
|
for ( n = 0; n < pContext->NumberParams; n++ )
|
|||
|
{
|
|||
|
|
|||
|
if ( !SAMEDIRECTION(IsClient, Params[n]) ||
|
|||
|
! Params[n].ParamAttr.MustSize )
|
|||
|
continue;
|
|||
|
|
|||
|
if ( IsClient &&
|
|||
|
Params[n].ParamAttr.IsPartialIgnore )
|
|||
|
{
|
|||
|
LENGTH_ALIGN( pStubMsg->BufferLength, 0x3 );
|
|||
|
pStubMsg->BufferLength += PTR_WIRE_SIZE;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Note : Basetypes will always be factored into the
|
|||
|
// constant buffer size emitted by in the format strings.
|
|||
|
//
|
|||
|
|
|||
|
pFormatParam = pTypeFormat +
|
|||
|
Params[n].TypeOffset;
|
|||
|
|
|||
|
pArg = pContext->StartofStack + Params[n].StackOffset;
|
|||
|
|
|||
|
if ( ! Params[n].ParamAttr.IsByValue )
|
|||
|
pArg = *((uchar **)pArg);
|
|||
|
|
|||
|
(*SizeRoutinesTable[ROUTINE_INDEX(*pFormatParam)])
|
|||
|
( pStubMsg,
|
|||
|
pArg,
|
|||
|
pFormatParam );
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrpClientMarshal( MIDL_STUB_MESSAGE * pStubMsg,
|
|||
|
BOOL IsObject )
|
|||
|
{
|
|||
|
ulong n;
|
|||
|
uchar * pArg;
|
|||
|
PFORMAT_STRING pFormatParam;
|
|||
|
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
|
|||
|
PPARAM_DESCRIPTION Params = (PPARAM_DESCRIPTION ) pContext->Params;
|
|||
|
PFORMAT_STRING pTypeFormat = pContext->DceTypeFormatString;
|
|||
|
|
|||
|
//
|
|||
|
// ----------------------------------------------------------
|
|||
|
// Marshall Pass.
|
|||
|
// ----------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
for ( n = 0; n < pContext->NumberParams; n++ )
|
|||
|
{
|
|||
|
|
|||
|
if (!Params[n].ParamAttr.IsIn ||
|
|||
|
Params[n].ParamAttr.IsPipe )
|
|||
|
continue;
|
|||
|
|
|||
|
if ( Params[n].ParamAttr.IsPartialIgnore )
|
|||
|
{
|
|||
|
|
|||
|
pArg = pContext->StartofStack + Params[n].StackOffset;
|
|||
|
|
|||
|
ALIGN( pStubMsg->Buffer, 0x3 );
|
|||
|
*(ulong*)pStubMsg->Buffer = *(void**)pArg ? 1 : 0;
|
|||
|
pStubMsg->Buffer += PTR_WIRE_SIZE;
|
|||
|
continue;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
pArg = pContext->StartofStack + Params[n].StackOffset;
|
|||
|
|
|||
|
if ( Params[n].ParamAttr.IsBasetype )
|
|||
|
{
|
|||
|
//
|
|||
|
// Check for pointer to basetype.
|
|||
|
//
|
|||
|
if ( Params[n].ParamAttr.IsSimpleRef )
|
|||
|
pArg = *((uchar **)pArg);
|
|||
|
else
|
|||
|
{
|
|||
|
|
|||
|
#ifdef _IA64_
|
|||
|
if ( !IsObject &&
|
|||
|
Params[n].SimpleType.Type == FC_FLOAT )
|
|||
|
{
|
|||
|
// 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
|
|||
|
}
|
|||
|
|
|||
|
if ( Params[n].SimpleType.Type == FC_ENUM16 )
|
|||
|
{
|
|||
|
if ( *((int *)pArg) & ~((int)0x7fff) )
|
|||
|
RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
ALIGN( pStubMsg->Buffer,
|
|||
|
SIMPLE_TYPE_ALIGNMENT( Params[n].SimpleType.Type ) );
|
|||
|
|
|||
|
RpcpMemoryCopy(
|
|||
|
pStubMsg->Buffer,
|
|||
|
pArg,
|
|||
|
(uint)SIMPLE_TYPE_BUFSIZE(Params[n].SimpleType.Type) );
|
|||
|
|
|||
|
pStubMsg->Buffer +=
|
|||
|
SIMPLE_TYPE_BUFSIZE( Params[n].SimpleType.Type );
|
|||
|
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
pFormatParam = pTypeFormat +
|
|||
|
Params[n].TypeOffset;
|
|||
|
|
|||
|
if ( ! Params[n].ParamAttr.IsByValue )
|
|||
|
pArg = *((uchar **)pArg);
|
|||
|
|
|||
|
(* MarshallRoutinesTable[ROUTINE_INDEX(*pFormatParam)] )
|
|||
|
( pStubMsg,
|
|||
|
pArg,
|
|||
|
pFormatParam );
|
|||
|
}
|
|||
|
|
|||
|
if ( pStubMsg->RpcMsg->BufferLength <
|
|||
|
(uint)(pStubMsg->Buffer - (uchar *)pStubMsg->RpcMsg->Buffer) )
|
|||
|
{
|
|||
|
NDR_ASSERT( 0, "NdrpClientMarshal marshal: buffer overflow!" );
|
|||
|
RpcRaiseException( RPC_X_BAD_STUB_DATA );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrpServerMarshal( MIDL_STUB_MESSAGE * pStubMsg,
|
|||
|
BOOL IsObject )
|
|||
|
{
|
|||
|
ulong n;
|
|||
|
uchar * pArg;
|
|||
|
PFORMAT_STRING pFormatParam;
|
|||
|
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
|
|||
|
PPARAM_DESCRIPTION Params = (PPARAM_DESCRIPTION ) pContext->Params;
|
|||
|
PFORMAT_STRING pTypeFormat = pContext->DceTypeFormatString;
|
|||
|
|
|||
|
//
|
|||
|
// ----------------------------------------------------------
|
|||
|
// Marshall Pass.
|
|||
|
// ----------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
for ( n = 0; n < pContext->NumberParams; n++ )
|
|||
|
{
|
|||
|
if (!Params[n].ParamAttr.IsOut ||
|
|||
|
Params[n].ParamAttr.IsPipe )
|
|||
|
continue;
|
|||
|
|
|||
|
pArg = pContext->StartofStack + Params[n].StackOffset;
|
|||
|
|
|||
|
if ( Params[n].ParamAttr.IsBasetype )
|
|||
|
{
|
|||
|
//
|
|||
|
// Check for pointer to basetype.
|
|||
|
//
|
|||
|
if ( Params[n].ParamAttr.IsSimpleRef )
|
|||
|
pArg = *((uchar **)pArg);
|
|||
|
|
|||
|
if ( Params[n].SimpleType.Type == FC_ENUM16 )
|
|||
|
{
|
|||
|
if ( *((int *)pArg) & ~((int)0x7fff) )
|
|||
|
RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
ALIGN( pStubMsg->Buffer,
|
|||
|
SIMPLE_TYPE_ALIGNMENT( Params[n].SimpleType.Type ) );
|
|||
|
|
|||
|
RpcpMemoryCopy(
|
|||
|
pStubMsg->Buffer,
|
|||
|
pArg,
|
|||
|
(uint)SIMPLE_TYPE_BUFSIZE(Params[n].SimpleType.Type) );
|
|||
|
|
|||
|
pStubMsg->Buffer +=
|
|||
|
SIMPLE_TYPE_BUFSIZE( Params[n].SimpleType.Type );
|
|||
|
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
pFormatParam = pTypeFormat +
|
|||
|
Params[n].TypeOffset;
|
|||
|
|
|||
|
if ( ! Params[n].ParamAttr.IsByValue )
|
|||
|
pArg = *((uchar **)pArg);
|
|||
|
|
|||
|
(* MarshallRoutinesTable[ROUTINE_INDEX(*pFormatParam)] )
|
|||
|
( pStubMsg,
|
|||
|
pArg,
|
|||
|
pFormatParam );
|
|||
|
}
|
|||
|
|
|||
|
if ( pStubMsg->RpcMsg->BufferLength <
|
|||
|
(uint)(pStubMsg->Buffer - (uchar *)pStubMsg->RpcMsg->Buffer) )
|
|||
|
{
|
|||
|
NDR_ASSERT( 0, "NdrpServerMarshal marshal: buffer overflow!" );
|
|||
|
RpcRaiseException( RPC_X_BAD_STUB_DATA );
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
From: To: Marshall: User Exception: Cleanup:Rundown: context handle:
|
|||
|
---------- ---------------------------------- --------------------------------
|
|||
|
Any NULL Y N/A No No INVALID_HANDLE from the server
|
|||
|
!NULL Same value Any Any No No Same as before
|
|||
|
!NULL Different Any Any No No New context on the server
|
|||
|
!NULL Any N/A Y No No No new context handle is created
|
|||
|
NULL ANY N/A Y Yes No INVALID_HANDLE from the server
|
|||
|
NULL !NULL Y N Yes Yes INVALID_HANDLE from the server
|
|||
|
NULL !NULL N N Yes Yes INVALID_HANDLE from the server
|
|||
|
!NULL NULL N N Yes No No new context handle is created
|
|||
|
NULL NULL N N Yes No No new context handle is created
|
|||
|
|
|||
|
In the OUT only context handle case:
|
|||
|
To: Marshall: User Exception: Cleanup:Rundown: context handle:
|
|||
|
--------------------------------------------------------------------------------------
|
|||
|
Any N/A Y N N No new context handle is created
|
|||
|
NULL N N N N No new context handle is created
|
|||
|
NULL Y N N N No new context handle is created
|
|||
|
!NULL N N N Y No new context handle is created
|
|||
|
!NULL Y N Y Y No new context handle is created
|
|||
|
|
|||
|
|
|||
|
*/
|
|||
|
void
|
|||
|
NdrpEmergencyContextCleanup(
|
|||
|
MIDL_STUB_MESSAGE * pStubMsg,
|
|||
|
PNDR_CONTEXT_HANDLE_ARG_DESC pCtxtDesc,
|
|||
|
void * pArg,
|
|||
|
BOOL fManagerRoutineException
|
|||
|
)
|
|||
|
{
|
|||
|
int RtnIndex = pCtxtDesc->RundownRtnIndex;
|
|||
|
NDR_RUNDOWN pfnRundown = pStubMsg->StubDesc->apfnNdrRundownRoutines[ RtnIndex ];
|
|||
|
NDR_SCONTEXT SContext = pStubMsg->SavedContextHandles[ pCtxtDesc->ParamOrdinal ];
|
|||
|
void * NewHandle = pArg;
|
|||
|
|
|||
|
// if runtime failes during marshalling context handle, we shouldn't call into
|
|||
|
// cleanup routine since it's already cleanup by runtime.
|
|||
|
if ( SContext == (NDR_SCONTEXT )CONTEXT_HANDLE_BEFORE_MARSHAL_MARKER )
|
|||
|
return;
|
|||
|
|
|||
|
|
|||
|
if ( fManagerRoutineException )
|
|||
|
{
|
|||
|
// NDR_ASSERT( SContext != NULL || pCtxtDesc->Flags.IsReturn ,
|
|||
|
// "only return context handle can have null scontext in exception" );
|
|||
|
|
|||
|
// if we failed somewhere during unmarshalling, or this is a return context handle,
|
|||
|
// we don't need to cleanup
|
|||
|
if ( SContext == NULL )
|
|||
|
return;
|
|||
|
|
|||
|
// in NdrServerOutInit, we initialize the scontext for regular [out] parameters,
|
|||
|
// and runtime has already allocated some memory. But for return context handle,
|
|||
|
// we initialize the scontext during marshalling and saved context is NULL till
|
|||
|
// just before marshalling.
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// haven't unmarshalled yet.
|
|||
|
if ( SContext == NULL )
|
|||
|
{
|
|||
|
if ( NULL == NewHandle )
|
|||
|
return;
|
|||
|
else
|
|||
|
{
|
|||
|
// note : what if the context handle is both return and viaptr?
|
|||
|
NDR_ASSERT( pCtxtDesc->Flags.IsReturn, "has to be return context handle" );
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
if ( SContext == (NDR_SCONTEXT )CONTEXT_HANDLE_AFTER_MARSHAL_MARKER )
|
|||
|
{
|
|||
|
// this particular context handle has been marshalled; the exception happens
|
|||
|
// during marshalling other parameters after this one.
|
|||
|
|
|||
|
// After marshalling is done, the runtime will release the user context if new context
|
|||
|
// handle is NULL, so we can't reference to the user context at this point.
|
|||
|
NewHandle = NULL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if ( pCtxtDesc->Flags.IsViaPtr )
|
|||
|
NewHandle = *((void * UNALIGNED *)pArg);
|
|||
|
}
|
|||
|
// if this is a regular [in,out] or [out] context handle, and it hasn't been marshalled
|
|||
|
// yet, we need to call into runtime to cleanup.
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Kamen volunteer to process the logic of calling runtime or not. In NDR we just
|
|||
|
// don't call into the routine when it isn't supposed to.
|
|||
|
NDRSContextEmergencyCleanup( pStubMsg->RpcMsg->Handle,
|
|||
|
SContext,
|
|||
|
pfnRundown,
|
|||
|
NewHandle,
|
|||
|
fManagerRoutineException );
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
NdrpCleanupServerContextHandles(
|
|||
|
MIDL_STUB_MESSAGE * pStubMsg,
|
|||
|
uchar * pStartOfStack,
|
|||
|
BOOL fManagerRoutineException )
|
|||
|
{
|
|||
|
ulong n;
|
|||
|
uchar * pArg;
|
|||
|
PFORMAT_STRING pFormatParam;
|
|||
|
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
|
|||
|
PPARAM_DESCRIPTION Params = (PPARAM_DESCRIPTION ) pContext->Params;
|
|||
|
PFORMAT_STRING pTypeFormat = pContext->DceTypeFormatString;
|
|||
|
|
|||
|
//
|
|||
|
// ------------------------------------------------------------------------
|
|||
|
// Context handle loop: clean up out context handles to prevent leaks.
|
|||
|
//
|
|||
|
// Note, this routine handles only the handles that may have been dropped
|
|||
|
// due to the NDR engine raising exception between a clean return from
|
|||
|
// the manager routine and end of marshaling back of the parameters.
|
|||
|
// This addresses a situation where handles get dropped by NDR without being
|
|||
|
// registered with the runtime and so the server leaks because the rundown
|
|||
|
// routine is never called on the dropped handles.
|
|||
|
// ------------------------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
for ( n = 0; n < pContext->NumberParams; n++ )
|
|||
|
{
|
|||
|
if (!Params[n].ParamAttr.IsOut ||
|
|||
|
Params[n].ParamAttr.IsPipe )
|
|||
|
continue;
|
|||
|
|
|||
|
pArg = pContext->StartofStack + Params[n].StackOffset;
|
|||
|
|
|||
|
if ( Params[n].ParamAttr.IsBasetype )
|
|||
|
{
|
|||
|
//
|
|||
|
// Check for pointer to basetype.
|
|||
|
//
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
pFormatParam = pTypeFormat +
|
|||
|
Params[n].TypeOffset;
|
|||
|
|
|||
|
if ( ! Params[n].ParamAttr.IsByValue )
|
|||
|
pArg = *((uchar **)pArg);
|
|||
|
|
|||
|
// Context handle have their own "via pointer" flag to mark dereference.
|
|||
|
|
|||
|
if ( *pFormatParam == FC_BIND_CONTEXT )
|
|||
|
{
|
|||
|
NdrpEmergencyContextCleanup( pStubMsg,
|
|||
|
(PNDR_CONTEXT_HANDLE_ARG_DESC) pFormatParam,
|
|||
|
pArg,
|
|||
|
fManagerRoutineException
|
|||
|
);
|
|||
|
}
|
|||
|
} // parameter loop
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrpClientUnMarshal ( MIDL_STUB_MESSAGE * pStubMsg,
|
|||
|
void * pReturnValue )
|
|||
|
{
|
|||
|
ulong n;
|
|||
|
uchar * pArg;
|
|||
|
uchar ** ppArg;
|
|||
|
PFORMAT_STRING pFormatParam, pFormat;
|
|||
|
NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT *) pStubMsg->pContext;
|
|||
|
PPARAM_DESCRIPTION Params = (PPARAM_DESCRIPTION)pContext->Params;
|
|||
|
PFORMAT_STRING pTypeFormat = pContext->DceTypeFormatString;
|
|||
|
|
|||
|
// we only need to do conversion in NDR32 now: we cut off endian
|
|||
|
// conversion in NDR64.
|
|||
|
// Do endian/floating point conversions if necessary.
|
|||
|
//
|
|||
|
if ( (pStubMsg->RpcMsg->DataRepresentation & 0X0000FFFFUL) !=
|
|||
|
NDR_LOCAL_DATA_REPRESENTATION )
|
|||
|
{
|
|||
|
NdrConvert2( pStubMsg,
|
|||
|
(PFORMAT_STRING) Params,
|
|||
|
pContext->NumberParams );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// ----------------------------------------------------------
|
|||
|
// Unmarshall Pass.
|
|||
|
// ----------------------------------------------------------
|
|||
|
//
|
|||
|
|
|||
|
for ( n = 0; n < pContext->NumberParams; n++ )
|
|||
|
{
|
|||
|
if ( Params[n].ParamAttr.IsPipe )
|
|||
|
continue;
|
|||
|
|
|||
|
if ( !Params[n].ParamAttr.IsOut )
|
|||
|
{
|
|||
|
if ( !Params[n].ParamAttr.IsIn
|
|||
|
&& !Params[n].ParamAttr.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( Params[n].ParamAttr.IsSimpleRef
|
|||
|
&& Params[n].ParamAttr.IsBasetype
|
|||
|
&& FC_ERROR_STATUS_T ==
|
|||
|
Params[n].SimpleType.Type,
|
|||
|
"Apparently not a hidden status param" );
|
|||
|
|
|||
|
pArg = pContext->StartofStack + Params[n].StackOffset;
|
|||
|
|
|||
|
** (error_status_t **) pArg = RPC_S_OK;
|
|||
|
}
|
|||
|
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if ( Params[n].ParamAttr.IsReturn )
|
|||
|
pArg = (uchar *) pReturnValue;
|
|||
|
else
|
|||
|
pArg = pContext->StartofStack + Params[n].StackOffset;
|
|||
|
|
|||
|
//
|
|||
|
// This is for returned basetypes and for pointers to
|
|||
|
// basetypes.
|
|||
|
//
|
|||
|
if ( Params[n].ParamAttr.IsBasetype )
|
|||
|
{
|
|||
|
//
|
|||
|
// Check for a pointer to a basetype.
|
|||
|
//
|
|||
|
if ( Params[n].ParamAttr.IsSimpleRef )
|
|||
|
pArg = *((uchar **)pArg);
|
|||
|
|
|||
|
ALIGN( pStubMsg->Buffer,
|
|||
|
SIMPLE_TYPE_ALIGNMENT(Params[n].SimpleType.Type) );
|
|||
|
|
|||
|
#if defined(__RPC_WIN64__)
|
|||
|
// Special case for int3264.
|
|||
|
|
|||
|
if ( Params[n].SimpleType.Type == FC_INT3264 ||
|
|||
|
Params[n].SimpleType.Type == FC_UINT3264 )
|
|||
|
{
|
|||
|
if ( Params[n].SimpleType.Type == FC_INT3264 )
|
|||
|
*((INT64 *)pArg) = *((long * &)pStubMsg->Buffer)++;
|
|||
|
else
|
|||
|
*((UINT64 *)pArg) = *((ulong * &)pStubMsg->Buffer)++;
|
|||
|
continue;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
if ( Params[n].SimpleType.Type == FC_ENUM16 )
|
|||
|
{
|
|||
|
*((int *)(pArg)) = *((int *)pArg) & ((int)0x7fff) ;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
RpcpMemoryCopy(
|
|||
|
pArg,
|
|||
|
pStubMsg->Buffer,
|
|||
|
(uint)SIMPLE_TYPE_BUFSIZE(Params[n].SimpleType.Type) );
|
|||
|
|
|||
|
pStubMsg->Buffer +=
|
|||
|
SIMPLE_TYPE_BUFSIZE( Params[n].SimpleType.Type );
|
|||
|
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
ppArg = Params[n].ParamAttr.IsByValue ? &pArg : (uchar **)pArg;
|
|||
|
|
|||
|
pFormatParam = pTypeFormat +
|
|||
|
Params[n].TypeOffset;
|
|||
|
|
|||
|
//
|
|||
|
// Transmit/Represent as can be passed as [out] only, thus
|
|||
|
// the IsByValue check.
|
|||
|
//
|
|||
|
(* UnmarshallRoutinesTable[ROUTINE_INDEX(*pFormatParam)] )
|
|||
|
( pStubMsg,
|
|||
|
ppArg,
|
|||
|
pFormatParam,
|
|||
|
FALSE );
|
|||
|
}
|
|||
|
|
|||
|
if ( pStubMsg->pCorrInfo )
|
|||
|
NdrCorrelationPass( pStubMsg );
|
|||
|
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrpServerUnMarshal ( MIDL_STUB_MESSAGE * pStubMsg )
|
|||
|
{
|
|||
|
ulong n;
|
|||
|
uchar * pArg;
|
|||
|
uchar ** ppArg;
|
|||
|
PFORMAT_STRING pFormatParam, pFormat;
|
|||
|
NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT *) pStubMsg->pContext;
|
|||
|
PPARAM_DESCRIPTION Params = (PPARAM_DESCRIPTION)pContext->Params;
|
|||
|
PFORMAT_STRING pTypeFormat = pContext->DceTypeFormatString;
|
|||
|
|
|||
|
|
|||
|
// we only need to do conversion in NDR32 now: we cut off endian
|
|||
|
// conversion in NDR64.
|
|||
|
// Do endian/floating point conversions if necessary.
|
|||
|
//
|
|||
|
if ( ( pStubMsg->RpcMsg->DataRepresentation & 0X0000FFFFUL) !=
|
|||
|
NDR_LOCAL_DATA_REPRESENTATION )
|
|||
|
{
|
|||
|
NdrConvert2( pStubMsg,
|
|||
|
(PFORMAT_STRING) Params,
|
|||
|
(long) pContext->NumberParams );
|
|||
|
}
|
|||
|
|
|||
|
// --------------------------------
|
|||
|
// Unmarshall all of our parameters.
|
|||
|
// --------------------------------
|
|||
|
|
|||
|
for ( n = 0; n < pContext->NumberParams; n++ )
|
|||
|
{
|
|||
|
|
|||
|
if ( ! Params[n].ParamAttr.IsIn ||
|
|||
|
Params[n].ParamAttr.IsPipe )
|
|||
|
continue;
|
|||
|
|
|||
|
if ( Params[n].ParamAttr.IsPartialIgnore )
|
|||
|
{
|
|||
|
pArg = pContext->StartofStack + Params[n].StackOffset;
|
|||
|
|
|||
|
ALIGN( pStubMsg->Buffer, 0x3 );
|
|||
|
*(void**)pArg = *(ulong*)pStubMsg->Buffer ? (void*)1 : (void*)0;
|
|||
|
pStubMsg->Buffer += PTR_WIRE_SIZE;
|
|||
|
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
pArg = pContext->StartofStack + Params[n].StackOffset;
|
|||
|
|
|||
|
if ( Params[n].ParamAttr.IsBasetype )
|
|||
|
{
|
|||
|
//
|
|||
|
// Check for a pointer to a basetype. Set the arg pointer
|
|||
|
// at the correct buffer location and you're done.
|
|||
|
// Except darn int3264
|
|||
|
if ( Params[n].ParamAttr.IsSimpleRef )
|
|||
|
{
|
|||
|
ALIGN( pStubMsg->Buffer,
|
|||
|
SIMPLE_TYPE_ALIGNMENT( Params[n].SimpleType.Type ) );
|
|||
|
|
|||
|
#if defined(__RPC_WIN64__)
|
|||
|
// Special case for a ref pointer to int3264.
|
|||
|
|
|||
|
if ( Params[n].SimpleType.Type == FC_INT3264 ||
|
|||
|
Params[n].SimpleType.Type == FC_UINT3264 )
|
|||
|
{
|
|||
|
*((void **)pArg) = NdrpAlloca( &pContext->AllocateContext, 8 );
|
|||
|
|
|||
|
if ( Params[n].SimpleType.Type == FC_INT3264 )
|
|||
|
*(*(INT64**)pArg) = *((long * &)pStubMsg->Buffer)++;
|
|||
|
else
|
|||
|
*(*(UINT64**)pArg)= *((ulong * &)pStubMsg->Buffer)++;
|
|||
|
continue;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
*((uchar **)pArg) = pStubMsg->Buffer;
|
|||
|
|
|||
|
pStubMsg->Buffer +=
|
|||
|
SIMPLE_TYPE_BUFSIZE( Params[n].SimpleType.Type );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
NdrUnmarshallBasetypeInline(
|
|||
|
pStubMsg,
|
|||
|
pArg,
|
|||
|
Params[n].SimpleType.Type );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
continue;
|
|||
|
} // IsBasetype
|
|||
|
|
|||
|
//
|
|||
|
// This is an initialization of [in] and [in,out] ref pointers
|
|||
|
// to pointers. These can not be initialized to point into the
|
|||
|
// rpc buffer and we want to avoid doing a malloc of 4 bytes!
|
|||
|
// 32b: a ref pointer to any pointer, we allocate the pointee pointer.
|
|||
|
//
|
|||
|
if ( Params[n].ParamAttr.ServerAllocSize != 0 )
|
|||
|
{
|
|||
|
*((void **)pArg) = NdrpAlloca(& pContext->AllocateContext, PTR_MEM_SIZE );
|
|||
|
|
|||
|
// Triple indirection - cool!
|
|||
|
**((void ***)pArg) = 0;
|
|||
|
}
|
|||
|
|
|||
|
pStubMsg->ReuseBuffer = Params[n].ParamAttr.IsForceAllocate;
|
|||
|
ppArg = Params[n].ParamAttr.IsByValue ? &pArg : (uchar **)pArg;
|
|||
|
|
|||
|
pFormatParam = pTypeFormat +
|
|||
|
Params[n].TypeOffset;
|
|||
|
|
|||
|
(*UnmarshallRoutinesTable[ROUTINE_INDEX(*pFormatParam)])
|
|||
|
( pStubMsg,
|
|||
|
ppArg,
|
|||
|
pFormatParam,
|
|||
|
Params[n].ParamAttr.IsForceAllocate &&
|
|||
|
!Params[n].ParamAttr.IsByValue );
|
|||
|
|
|||
|
pStubMsg->ReuseBuffer = FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if ( pStubMsg->pCorrInfo )
|
|||
|
NdrCorrelationPass( pStubMsg );
|
|||
|
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrpDcomClientExceptionHandling( MIDL_STUB_MESSAGE * pStubMsg,
|
|||
|
ulong ProcNum,
|
|||
|
RPC_STATUS ExceptionCode,
|
|||
|
CLIENT_CALL_RETURN * pReturnValue )
|
|||
|
{
|
|||
|
ulong NumberParams;
|
|||
|
PPARAM_DESCRIPTION Params;
|
|||
|
PFORMAT_STRING pTypeFormat;
|
|||
|
ulong n;
|
|||
|
uchar * pArg;
|
|||
|
PFORMAT_STRING pFormatParam;
|
|||
|
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
|
|||
|
|
|||
|
pReturnValue->Simple = NdrProxyErrorHandler(ExceptionCode);
|
|||
|
if( pStubMsg->dwStubPhase != PROXY_UNMARSHAL)
|
|||
|
return;
|
|||
|
|
|||
|
NumberParams = pContext->NumberParams;
|
|||
|
Params = ( PPARAM_DESCRIPTION )pContext->Params;
|
|||
|
// alert: this can't be directly called from ndrclientcall2: we don't have pSyntaxInfo.
|
|||
|
pTypeFormat = pContext->DceTypeFormatString;
|
|||
|
|
|||
|
//
|
|||
|
// In OLE, since they don't know about error_status_t and wanted to
|
|||
|
// reinvent the wheel, check to see if we need to map the exception.
|
|||
|
// In either case, set the return value and then try to free the
|
|||
|
// [out] params, if required.
|
|||
|
//
|
|||
|
pStubMsg->BufferStart = 0;
|
|||
|
pStubMsg->BufferEnd = 0;
|
|||
|
|
|||
|
for ( n = 0; n < pContext->NumberParams; n++ )
|
|||
|
{
|
|||
|
//
|
|||
|
// Skip everything but [out] only parameters. We make
|
|||
|
// the basetype check to cover [out] simple ref pointers
|
|||
|
// to basetypes.
|
|||
|
//
|
|||
|
|
|||
|
if ( !Params[n].ParamAttr.IsPartialIgnore )
|
|||
|
{
|
|||
|
if ( Params[n].ParamAttr.IsIn ||
|
|||
|
Params[n].ParamAttr.IsReturn ||
|
|||
|
Params[n].ParamAttr.IsBasetype ||
|
|||
|
Params[n].ParamAttr.IsPipe )
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
pArg = pContext->StartofStack + Params[n].StackOffset;
|
|||
|
|
|||
|
pFormatParam = pTypeFormat +
|
|||
|
Params[n].TypeOffset;
|
|||
|
|
|||
|
NdrClearOutParameters( pStubMsg,
|
|||
|
pFormatParam,
|
|||
|
*((uchar **)pArg) );
|
|||
|
}
|
|||
|
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrpClientExceptionHandling( MIDL_STUB_MESSAGE * pStubMsg,
|
|||
|
ulong ProcNum,
|
|||
|
RPC_STATUS ExceptionCode,
|
|||
|
CLIENT_CALL_RETURN * pReturnValue )
|
|||
|
{
|
|||
|
NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT * ) pStubMsg->pContext;
|
|||
|
|
|||
|
NDR_ASSERT( pContext->NdrInfo.InterpreterFlags.HasCommOrFault,
|
|||
|
" must have comm or fault to catch" );
|
|||
|
NdrClientMapCommFault( pStubMsg,
|
|||
|
ProcNum,
|
|||
|
ExceptionCode,
|
|||
|
(ULONG_PTR*)&pReturnValue->Simple );
|
|||
|
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrpAsyncClientExceptionHandling( MIDL_STUB_MESSAGE * pStubMsg,
|
|||
|
ulong ProcNum,
|
|||
|
RPC_STATUS ExceptionCode,
|
|||
|
CLIENT_CALL_RETURN * pReturnValue )
|
|||
|
{
|
|||
|
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
|
|||
|
|
|||
|
if ( pContext->NdrInfo.InterpreterFlags.HasCommOrFault )
|
|||
|
{
|
|||
|
NdrClientMapCommFault( pStubMsg,
|
|||
|
ProcNum,
|
|||
|
ExceptionCode,
|
|||
|
(ULONG_PTR*)&pReturnValue->Simple );
|
|||
|
if ( ExceptionCode == RPC_S_ASYNC_CALL_PENDING )
|
|||
|
{
|
|||
|
// If the call is just pending, force the pending error code
|
|||
|
// to show up in the return value of RpcAsyncCallComplete.
|
|||
|
|
|||
|
pReturnValue->Simple = RPC_S_ASYNC_CALL_PENDING;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
RpcRaiseException(ExceptionCode);
|
|||
|
}
|
|||
|
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void RPC_ENTRY
|
|||
|
NdrpClientFinally( PMIDL_STUB_MESSAGE pStubMsg,
|
|||
|
void * pThis )
|
|||
|
{
|
|||
|
NDR_PROC_CONTEXT * pContext = ( NDR_PROC_CONTEXT * ) pStubMsg->pContext;
|
|||
|
NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables);
|
|||
|
|
|||
|
NdrCorrelationFree( pStubMsg );
|
|||
|
|
|||
|
//
|
|||
|
// 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 )
|
|||
|
GenericHandleUnbind( pStubMsg->StubDesc,
|
|||
|
pContext->StartofStack,
|
|||
|
pContext->pHandleFormatSave,
|
|||
|
(pContext->HandleType) ? IMPLICIT_MASK : 0,
|
|||
|
&pContext->SavedGenericHandle );
|
|||
|
}
|
|||
|
|
|||
|
NdrpAllocaDestroy( & pContext->AllocateContext );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
NdrpServerInit( PMIDL_STUB_MESSAGE pStubMsg,
|
|||
|
RPC_MESSAGE * pRpcMsg,
|
|||
|
PMIDL_STUB_DESC pStubDesc,
|
|||
|
void * pThis,
|
|||
|
IRpcChannelBuffer * pChannel,
|
|||
|
PNDR_ASYNC_MESSAGE pAsyncMsg )
|
|||
|
{
|
|||
|
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *) pStubMsg->pContext;
|
|||
|
|
|||
|
uchar * pArg;
|
|||
|
uchar * pArgBuffer = pContext->StartofStack;
|
|||
|
|
|||
|
if ( pContext->pSyntaxInfo == NULL )
|
|||
|
pContext->DceTypeFormatString = pStubDesc->pFormatTypes;
|
|||
|
else
|
|||
|
pContext->DceTypeFormatString = pContext->pSyntaxInfo->TypeString;
|
|||
|
|
|||
|
if ( ! pContext->HandleType )
|
|||
|
{
|
|||
|
//
|
|||
|
// For a handle_t parameter we must pass the handle field of
|
|||
|
// the RPC message to the server manager.
|
|||
|
//
|
|||
|
if ( *pContext->pHandleFormatSave == FC_BIND_PRIMITIVE )
|
|||
|
{
|
|||
|
pArg = pArgBuffer + *((ushort *)&pContext->pHandleFormatSave[2]);
|
|||
|
|
|||
|
if ( IS_HANDLE_PTR(pContext->pHandleFormatSave[1]) )
|
|||
|
pArg = *((uchar **)pArg);
|
|||
|
|
|||
|
*((handle_t *)pArg) = pRpcMsg->Handle;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If OLE, put pThis in first dword of stack.
|
|||
|
//
|
|||
|
if ( pThis )
|
|||
|
{
|
|||
|
*((void **)pArgBuffer) =
|
|||
|
(void *)((CStdStubBuffer *)pThis)->pvServerObject;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the Stub message.
|
|||
|
//
|
|||
|
if ( ! pChannel )
|
|||
|
{
|
|||
|
if ( ! pContext->NdrInfo.pProcDesc->Oi2Flags.HasPipes )
|
|||
|
{
|
|||
|
NdrServerInitializeNew( pRpcMsg,
|
|||
|
pStubMsg,
|
|||
|
pStubDesc );
|
|||
|
}
|
|||
|
else
|
|||
|
NdrServerInitializePartial( pRpcMsg,
|
|||
|
pStubMsg,
|
|||
|
pStubDesc,
|
|||
|
pContext->NdrInfo.pProcDesc->ClientBufferSize );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// pipe is not supported in obj interface.
|
|||
|
NDR_ASSERT( ! pContext->HasPipe, "Pipe is not supported in dcom" );
|
|||
|
NdrStubInitialize( pRpcMsg,
|
|||
|
pStubMsg,
|
|||
|
pStubDesc,
|
|||
|
pChannel );
|
|||
|
}
|
|||
|
|
|||
|
if ( pAsyncMsg )
|
|||
|
{
|
|||
|
pStubMsg->pAsyncMsg = pAsyncMsg;
|
|||
|
pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC;
|
|||
|
}
|
|||
|
|
|||
|
if ( pContext->NdrInfo.InterpreterFlags.FullPtrUsed )
|
|||
|
pStubMsg->FullPtrXlatTables = NdrFullPointerXlatInit( 0, XLAT_SERVER );
|
|||
|
else
|
|||
|
pStubMsg->FullPtrXlatTables = NULL;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Set StackTop AFTER the initialize call, since it zeros the field
|
|||
|
// out.
|
|||
|
//
|
|||
|
pStubMsg->StackTop = pArgBuffer;
|
|||
|
|
|||
|
if ( pContext->NdrInfo.pProcDesc->Oi2Flags.HasPipes )
|
|||
|
{
|
|||
|
NdrpPipesInitialize32( pStubMsg,
|
|||
|
&pContext->AllocateContext,
|
|||
|
(PFORMAT_STRING) pContext->Params,
|
|||
|
(char*)pArgBuffer,
|
|||
|
pContext->NumberParams );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// We must make this check AFTER the call to ServerInitialize,
|
|||
|
// since that routine puts the stub descriptor alloc/dealloc routines
|
|||
|
// into the stub message.
|
|||
|
//
|
|||
|
if ( pContext->NdrInfo.InterpreterFlags.RpcSsAllocUsed )
|
|||
|
NdrRpcSsEnableAllocate( pStubMsg );
|
|||
|
|
|||
|
if ( pContext->NdrInfo.pProcDesc->Oi2Flags.HasExtensions )
|
|||
|
{
|
|||
|
pStubMsg->fHasExtensions = 1;
|
|||
|
pStubMsg->fHasNewCorrDesc = pContext->NdrInfo.pProcDesc->NdrExts.Flags2.HasNewCorrDesc;
|
|||
|
if ( pContext->NdrInfo.pProcDesc->NdrExts.Flags2.ServerCorrCheck )
|
|||
|
{
|
|||
|
|
|||
|
void * pCorr = NdrpAlloca( &pContext->AllocateContext, NDR_DEFAULT_CORR_CACHE_SIZE );
|
|||
|
NdrCorrelationInitialize( pStubMsg,
|
|||
|
pCorr,
|
|||
|
NDR_DEFAULT_CORR_CACHE_SIZE,
|
|||
|
0 /* flags */ );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void NdrpServerOutInit( PMIDL_STUB_MESSAGE pStubMsg )
|
|||
|
{
|
|||
|
ulong n;
|
|||
|
NDR_PROC_CONTEXT * pContext = (NDR_PROC_CONTEXT *)pStubMsg->pContext;
|
|||
|
PPARAM_DESCRIPTION Params = ( PPARAM_DESCRIPTION ) pContext->Params;
|
|||
|
PFORMAT_STRING pFormatTypes = pContext->DceTypeFormatString;
|
|||
|
uchar * pArgBuffer = pContext->StartofStack;
|
|||
|
uchar * pArg;
|
|||
|
PFORMAT_STRING pFormatParam;
|
|||
|
|
|||
|
for ( n = 0; n < pContext->NumberParams; n++ )
|
|||
|
{
|
|||
|
|
|||
|
if ( !Params[n].ParamAttr.IsPartialIgnore )
|
|||
|
{
|
|||
|
if ( Params[n].ParamAttr.IsIn ||
|
|||
|
( Params[n].ParamAttr.IsReturn && !pContext->HasComplexReturn ) ||
|
|||
|
Params[n].ParamAttr.IsPipe )
|
|||
|
continue;
|
|||
|
|
|||
|
pArg = pArgBuffer + Params[n].StackOffset;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pArg = pArgBuffer + Params[n].StackOffset;
|
|||
|
|
|||
|
if ( !*(void**)pArg )
|
|||
|
continue;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check if we can initialize this parameter using some of our
|
|||
|
// stack.
|
|||
|
//
|
|||
|
if ( Params[n].ParamAttr.ServerAllocSize != 0 )
|
|||
|
{
|
|||
|
*((void **)pArg) = NdrpAlloca( &pContext->AllocateContext,
|
|||
|
Params[n].ParamAttr.ServerAllocSize * 8);
|
|||
|
|
|||
|
MIDL_memset( *((void **)pArg),
|
|||
|
0,
|
|||
|
Params[n].ParamAttr.ServerAllocSize * 8 );
|
|||
|
continue;
|
|||
|
}
|
|||
|
else if ( Params[n].ParamAttr.IsBasetype )
|
|||
|
{
|
|||
|
*((void **)pArg) = NdrpAlloca( &pContext->AllocateContext, 8 );
|
|||
|
MIDL_memset( *((void **)pArg), 0, 8 );
|
|||
|
continue;
|
|||
|
};
|
|||
|
|
|||
|
pFormatParam = pFormatTypes + Params[n].TypeOffset;
|
|||
|
|
|||
|
NdrOutInit( pStubMsg,
|
|||
|
pFormatParam,
|
|||
|
(uchar **)pArg );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
#if defined( BUILD_NDR64 )
|
|||
|
BOOL IsServerSupportNDR64( MIDL_SERVER_INFO *pServerInfo )
|
|||
|
{
|
|||
|
if ( ( pServerInfo->pStubDesc->Version > NDR_VERSION ) ||
|
|||
|
( pServerInfo->pStubDesc->Version < NDR_VERSION_6_0 ) ||
|
|||
|
( pServerInfo->pStubDesc->MIDLVersion < MIDL_VERSION_6_0_322 ) ||
|
|||
|
! ( pServerInfo->pStubDesc->mFlags & RPCFLG_HAS_MULTI_SYNTAXES ) )
|
|||
|
return FALSE;
|
|||
|
return TRUE;
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
NdrClientGetSupportedSyntaxes(
|
|||
|
IN RPC_CLIENT_INTERFACE * pInf,
|
|||
|
OUT ulong * pCount,
|
|||
|
MIDL_SYNTAX_INFO ** pArr )
|
|||
|
{
|
|||
|
MIDL_SYNTAX_INFO *pSyntaxInfo;
|
|||
|
|
|||
|
NDR_ASSERT( pInf->Flags & RPCFLG_HAS_MULTI_SYNTAXES, "invalid clientif" );
|
|||
|
if ( pInf->Flags & RPCFLG_HAS_CALLBACK )
|
|||
|
{
|
|||
|
// interpreter info is MIDL_SERVER_INFO
|
|||
|
MIDL_SERVER_INFO * pServerInfo = ( MIDL_SERVER_INFO *) pInf->InterpreterInfo;
|
|||
|
*pCount = ( ulong ) pServerInfo->nCount ;
|
|||
|
*pArr = pServerInfo->pSyntaxInfo;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
MIDL_STUBLESS_PROXY_INFO * pProxyInfo = ( MIDL_STUBLESS_PROXY_INFO *) pInf->InterpreterInfo;
|
|||
|
*pCount = ( ulong ) pProxyInfo->nCount ;
|
|||
|
*pArr = pProxyInfo->pSyntaxInfo;
|
|||
|
}
|
|||
|
|
|||
|
return RPC_S_OK;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
NdrServerGetSupportedSyntaxes(
|
|||
|
IN RPC_SERVER_INTERFACE * pInf,
|
|||
|
OUT ulong * pCount,
|
|||
|
MIDL_SYNTAX_INFO ** pArr,
|
|||
|
OUT ulong * pPrefer)
|
|||
|
{
|
|||
|
NDR_ASSERT( pInf->Flags & RPCFLG_HAS_MULTI_SYNTAXES,"invalid serverif" );
|
|||
|
MIDL_SERVER_INFO *pServerInfo = ( MIDL_SERVER_INFO *) pInf->InterpreterInfo;
|
|||
|
*pCount = ( ulong ) pServerInfo->nCount;
|
|||
|
*pArr = pServerInfo->pSyntaxInfo;
|
|||
|
NdrpGetPreferredSyntax( ( ulong )pServerInfo->nCount, pServerInfo->pSyntaxInfo, pPrefer );
|
|||
|
return RPC_S_OK;
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
NdrCreateServerInterfaceFromStub(
|
|||
|
IN IRpcStubBuffer* pStub,
|
|||
|
IN OUT RPC_SERVER_INTERFACE *pServerIf )
|
|||
|
{
|
|||
|
#if !defined( BUILD_NDR64 )
|
|||
|
return S_OK;
|
|||
|
#else
|
|||
|
CInterfaceStubVtbl * pStubVTable;
|
|||
|
PMIDL_SERVER_INFO pServerInfo;
|
|||
|
IRpcStubBuffer * pv = NULL;
|
|||
|
RpcTryExcept
|
|||
|
{
|
|||
|
// filter out non-ndr stub first.
|
|||
|
if ( S_OK != pStub->lpVtbl->QueryInterface(pStub, IID_IPrivStubBuffer, (void **)& pv ) )
|
|||
|
return S_OK;
|
|||
|
|
|||
|
pv->lpVtbl->Release(pv);
|
|||
|
|
|||
|
pStubVTable = (CInterfaceStubVtbl *)
|
|||
|
(*((uchar **)pStub) - sizeof(CInterfaceStubHeader));
|
|||
|
|
|||
|
pServerInfo = (PMIDL_SERVER_INFO) pStubVTable->header.pServerInfo;
|
|||
|
|
|||
|
// In /Os mode, we don't have pServerInfo.
|
|||
|
if ( pServerInfo &&
|
|||
|
IsServerSupportNDR64( pServerInfo ) )
|
|||
|
{
|
|||
|
memcpy ( &pServerIf->TransferSyntax, pServerInfo->pTransferSyntax, sizeof( RPC_SYNTAX_IDENTIFIER ) );
|
|||
|
pServerIf->Flags |= RPCFLG_HAS_MULTI_SYNTAXES;
|
|||
|
pServerIf->InterpreterInfo = pServerInfo;
|
|||
|
}
|
|||
|
}
|
|||
|
RpcExcept( 1 )
|
|||
|
{
|
|||
|
}
|
|||
|
RpcEndExcept
|
|||
|
#endif
|
|||
|
|
|||
|
return S_OK;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description :
|
|||
|
|
|||
|
Read the proc header for different transfer syntax.
|
|||
|
We need to return proc number in dce because for stubs compiled with
|
|||
|
DCE only, proc header is the only place to get the procnum.
|
|||
|
|
|||
|
This rountine being called from both client and server. The difference
|
|||
|
is that client side we are reading from the default one; server side we
|
|||
|
are reading from the selected one.
|
|||
|
Arguments :
|
|||
|
|
|||
|
|
|||
|
Return :
|
|||
|
|
|||
|
none. Raise exception if something goes wrong. We can't recovered
|
|||
|
from here because we don't have enough information about how the
|
|||
|
stub looks like if we don't have valid proc header.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
ulong RPC_ENTRY
|
|||
|
MulNdrpInitializeContextFromProc (
|
|||
|
SYNTAX_TYPE SyntaxType,
|
|||
|
PFORMAT_STRING pFormat,
|
|||
|
NDR_PROC_CONTEXT * pContext,
|
|||
|
uchar * StartofStack,
|
|||
|
BOOLEAN IsReset )
|
|||
|
{
|
|||
|
ulong RpcFlags;
|
|||
|
ulong ProcNum = 0;
|
|||
|
|
|||
|
if ( !IsReset )
|
|||
|
NdrpInitializeProcContext( pContext );
|
|||
|
|
|||
|
pContext->pProcFormat = pFormat;
|
|||
|
pContext->StartofStack = StartofStack;
|
|||
|
|
|||
|
|
|||
|
if ( SyntaxType == XFER_SYNTAX_DCE )
|
|||
|
{
|
|||
|
PPARAM_DESCRIPTION Params;
|
|||
|
INTERPRETER_FLAGS InterpreterFlags;
|
|||
|
PFORMAT_STRING pNewProcDescr;
|
|||
|
INTERPRETER_OPT_FLAGS OptFlags;
|
|||
|
|
|||
|
pContext->CurrentSyntaxType = XFER_SYNTAX_DCE;
|
|||
|
|
|||
|
pContext->HandleType = *pFormat++ ;
|
|||
|
pContext->UseLocator = (FC_AUTO_HANDLE == pContext->HandleType);
|
|||
|
|
|||
|
pContext->NdrInfo.InterpreterFlags = *((PINTERPRETER_FLAGS)pFormat++);
|
|||
|
|
|||
|
InterpreterFlags = pContext->NdrInfo.InterpreterFlags;
|
|||
|
|
|||
|
if ( InterpreterFlags.HasRpcFlags )
|
|||
|
RpcFlags = *(( UNALIGNED ulong* &)pFormat)++;
|
|||
|
else
|
|||
|
RpcFlags = 0;
|
|||
|
|
|||
|
ProcNum = *(ushort *)pFormat; pFormat += 2;
|
|||
|
pContext->StackSize = *(ushort *)pFormat; pFormat += 2;
|
|||
|
|
|||
|
pContext->pHandleFormatSave = pFormat;
|
|||
|
|
|||
|
pNewProcDescr = pFormat;
|
|||
|
|
|||
|
if ( ! pContext->HandleType )
|
|||
|
{
|
|||
|
// explicit handle
|
|||
|
|
|||
|
pNewProcDescr += ((*pFormat == FC_BIND_PRIMITIVE) ? 4 : 6);
|
|||
|
}
|
|||
|
|
|||
|
pContext->NdrInfo.pProcDesc = (NDR_PROC_DESC *)pNewProcDescr;
|
|||
|
|
|||
|
OptFlags = ( (NDR_PROC_DESC *)pNewProcDescr )->Oi2Flags;
|
|||
|
|
|||
|
pContext->NumberParams = pContext->NdrInfo.pProcDesc->NumberParams;
|
|||
|
|
|||
|
//
|
|||
|
// Parameter descriptions are nicely spit out by MIDL.
|
|||
|
// If there is no extension, Params is in the position of extensions.
|
|||
|
//
|
|||
|
Params = (PPARAM_DESCRIPTION) &( pContext->NdrInfo.pProcDesc->NdrExts );
|
|||
|
|
|||
|
|
|||
|
// Proc header extentions, from NDR ver. 5.2.
|
|||
|
// Params must be set correctly here because of exceptions.
|
|||
|
|
|||
|
if ( OptFlags.HasExtensions )
|
|||
|
{
|
|||
|
pContext->HasComplexReturn = pContext->NdrInfo.pProcDesc->NdrExts.Flags2.HasComplexReturn;
|
|||
|
|
|||
|
Params = (PPARAM_DESCRIPTION)((uchar*)Params + pContext->NdrInfo.pProcDesc->NdrExts.Size);
|
|||
|
#if defined(_AMD64_) || defined(_IA64_)
|
|||
|
PNDR_PROC_HEADER_EXTS64 pExts = (PNDR_PROC_HEADER_EXTS64 )&pContext->NdrInfo.pProcDesc->NdrExts;
|
|||
|
|
|||
|
pContext->FloatDoubleMask = pExts->FloatArgMask;
|
|||
|
#endif // defined(_AMD64_) || defined(_IA64_)
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
pContext->Params = Params;
|
|||
|
|
|||
|
pContext->IsAsync = OptFlags.HasAsyncUuid ;
|
|||
|
pContext->IsObject = InterpreterFlags.ObjectProc;
|
|||
|
pContext->HasPipe = OptFlags.HasPipes;
|
|||
|
|
|||
|
pContext->ExceptionFlag = ! ( InterpreterFlags.IgnoreObjectException ) &&
|
|||
|
( pContext->IsObject || InterpreterFlags.HasCommOrFault );
|
|||
|
} // XFER_SYNTAX_DCE
|
|||
|
|
|||
|
#if defined(BUILD_NDR64)
|
|||
|
|
|||
|
else if ( SyntaxType == XFER_SYNTAX_NDR64 )
|
|||
|
{
|
|||
|
NDR64_PROC_FLAGS * pProcFlags;
|
|||
|
|
|||
|
pContext->CurrentSyntaxType = XFER_SYNTAX_NDR64;
|
|||
|
|
|||
|
pContext->Ndr64Header = (NDR64_PROC_FORMAT *)pFormat;
|
|||
|
pContext->HandleType =
|
|||
|
NDR64MAPHANDLETYPE( NDR64GETHANDLETYPE( &pContext->Ndr64Header->Flags ) );
|
|||
|
pContext->UseLocator = (FC64_AUTO_HANDLE == pContext->HandleType);
|
|||
|
|
|||
|
RpcFlags = pContext->Ndr64Header->RpcFlags;
|
|||
|
#if defined(_AMD64_) || defined(_IA64_)
|
|||
|
|
|||
|
pContext->FloatDoubleMask = pContext->Ndr64Header->FloatDoubleMask;
|
|||
|
#endif // defined(_AMD64_) || defined(_IA64_)
|
|||
|
pContext->NumberParams = pContext->Ndr64Header->NumberOfParams;
|
|||
|
pContext->Params = (NDR64_PROC_FORMAT *)( (char *) pFormat + sizeof( NDR64_PROC_FORMAT ) + pContext->Ndr64Header->ExtensionSize );
|
|||
|
pContext->StackSize = pContext->Ndr64Header->StackSize;
|
|||
|
|
|||
|
pProcFlags = (NDR64_PROC_FLAGS *) &pContext->Ndr64Header->Flags;
|
|||
|
|
|||
|
pContext->HasComplexReturn = pProcFlags->HasComplexReturn;
|
|||
|
pContext->IsAsync = pProcFlags->IsAsync;
|
|||
|
pContext->IsObject = pProcFlags->IsObject;
|
|||
|
pContext->HasPipe = pProcFlags->UsesPipes;
|
|||
|
|
|||
|
pContext->ExceptionFlag = pContext->IsObject || pProcFlags->HandlesExceptions;
|
|||
|
} // XFER_SYNTAX_NDR64
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
else
|
|||
|
NDR_ASSERT( 0, "Invalid transfer syntax.");
|
|||
|
|
|||
|
// setup the pipe flag before negotiation.
|
|||
|
if ( pContext->HasPipe )
|
|||
|
{
|
|||
|
RpcFlags &= ~RPC_BUFFER_COMPLETE;
|
|||
|
RpcFlags |= RPC_BUFFER_PARTIAL;
|
|||
|
}
|
|||
|
|
|||
|
pContext->RpcFlags = RpcFlags;
|
|||
|
// We need to cleanup the resend flag during initialization in preparation
|
|||
|
// for retry later.
|
|||
|
pContext->NeedsResend = FALSE;
|
|||
|
|
|||
|
return ProcNum;
|
|||
|
}
|