windows-nt/Source/XPSP1/NT/com/svcdlls/trksvcs/common/rpcsvr.cxx
2020-09-26 16:20:57 +08:00

242 lines
8.5 KiB
C++

// Copyright (c) 1996-1999 Microsoft Corporation
//+============================================================================
//
// rpcsvr.cxx
//
// Implementation of CRpcServer, with the common code to support
// trkwks & trksvr RPC servers.
//
//+============================================================================
#include <pch.cxx>
#pragma hdrstop
#include "trklib.hxx"
#define THIS_FILE_NUMBER RPCSVR_CXX_FILE_NO
//+----------------------------------------------------------------------------
//
// CRpcServer::Initialize
//
// Initialize the CRpcServer base class. Before calling this
// method, a derivation should perform all of its necessary
// RpcUseProtseq calls.
//
// If a ptszProtSeqForEpRegistration is specified, find the
// binding handle for that protocol and register this interface
// just with that binding.
//
//+----------------------------------------------------------------------------
void
CRpcServer::Initialize(RPC_IF_HANDLE ifspec,
ULONG grfRpcServerRegisterInterfaceEx,
UINT cMaxCalls,
BOOL fSetAuthInfo,
const TCHAR *ptszProtSeqForEpRegistration )
{
RPC_STATUS rpcstatus;
RPC_BINDING_VECTOR *pBindingVector = NULL;
TCHAR *ptszStringBinding = NULL;
TCHAR *ptszProtSeq = NULL;
_ifspec = ifspec;
_fEpRegister = NULL != ptszProtSeqForEpRegistration;
__try
{
// If required, set authentication information
if( RpcSecurityEnabled() && fSetAuthInfo )
{
RPC_TCHAR tszAuthName[MAX_COMPUTERNAME_LENGTH * 2 + 2 + 1]; // slash and $ and NUL
CMachineId mcid(MCID_LOCAL);
// Get the authentiation name, e.g. domain\machine$
mcid.GetLocalAuthName(tszAuthName, sizeof(tszAuthName)/sizeof(tszAuthName[0]));
// Set the auth info. We set it to negotiate, but we'll always get Kerberos.
rpcstatus = RpcServerRegisterAuthInfo(
tszAuthName,
RPC_C_AUTHN_GSS_NEGOTIATE,
NULL, // RPC_AUTH_KEY_RETRIEVAL_FN,
NULL ); // Arg );
if (rpcstatus)
{
TrkReportInternalError( THIS_FILE_NUMBER, __LINE__,
HRESULT_FROM_WIN32(rpcstatus), tszAuthName );
TrkRaiseWin32Error(rpcstatus);
}
}
// If using dynamic enpoints, register in the endpoint mapper
// for the first binding handle for the specified protocol sequence.
if( _fEpRegister )
{
// Query for the currently active binding handles
rpcstatus = RpcServerInqBindings(&pBindingVector);
if (rpcstatus)
{
TrkLog((TRKDBG_ERROR, TEXT("RpcServerInqBindings %08x"), rpcstatus));
TrkReportInternalError( THIS_FILE_NUMBER, __LINE__,
HRESULT_FROM_WIN32(rpcstatus), TRKREPORT_LAST_PARAM );
TrkRaiseWin32Error(rpcstatus);
}
// Loop through the binding handles, looking for the first one with
// the required protocol sequence.
for( ULONG i = 0; i < pBindingVector->Count; i++ )
{
// Stringize the binding handle.
rpcstatus = RpcBindingToStringBinding( pBindingVector->BindingH[i],
&ptszStringBinding );
if( RPC_S_OK != rpcstatus )
{
TrkLog(( TRKDBG_ERROR, TEXT("RpcBindingToStringBinding %08x"), rpcstatus ));
TrkReportInternalError( THIS_FILE_NUMBER, __LINE__, HRESULT_FROM_WIN32(rpcstatus), TRKREPORT_LAST_PARAM );
TrkRaiseWin32Error(rpcstatus);
}
// Parse the binding string for the protseq
rpcstatus = RpcStringBindingParse( ptszStringBinding, NULL,
&ptszProtSeq,
NULL, NULL, NULL );
if( RPC_S_OK != rpcstatus )
{
TrkLog(( TRKDBG_ERROR, TEXT("RpcStringBindingParse %08x"), rpcstatus ));
TrkReportInternalError( THIS_FILE_NUMBER, __LINE__, HRESULT_FROM_WIN32(rpcstatus), TRKREPORT_LAST_PARAM );
TrkRaiseWin32Error(rpcstatus);
}
// See if this protseq is that which we seek
if( 0 == _tcscmp( ptszProtSeq, ptszProtSeqForEpRegistration ))
{
// We have a match. Register against this binding handle.
RPC_BINDING_VECTOR PartialBindingVector;
PartialBindingVector.Count = 1;
PartialBindingVector.BindingH[0] = pBindingVector->BindingH[i];
rpcstatus = RpcEpRegister(ifspec, &PartialBindingVector, NULL, NULL);
if( RPC_S_OK != rpcstatus )
{
TrkLog((TRKDBG_ERROR, TEXT("RpcEpRegister %08x"), rpcstatus));
TrkReportInternalError( THIS_FILE_NUMBER, __LINE__, HRESULT_FROM_WIN32(rpcstatus), TRKREPORT_LAST_PARAM );
TrkRaiseWin32Error(rpcstatus);
}
else
TrkLog(( TRKDBG_MISC, TEXT("RpcEpRegister on %s"), ptszStringBinding ));
break;
}
RpcStringFree( &ptszStringBinding );
ptszStringBinding = NULL;
RpcStringFree( &ptszProtSeq );
ptszProtSeq = NULL;
}
if( i == pBindingVector->Count )
{
TrkLog((TRKDBG_ERROR, TEXT("Couldn't find protseq %s in binding vector"),
ptszProtSeqForEpRegistration ));
TrkReportInternalError( THIS_FILE_NUMBER, __LINE__, HRESULT_FROM_WIN32(rpcstatus), TRKREPORT_LAST_PARAM );
TrkRaiseWin32Error( HRESULT_FROM_WIN32(RPC_S_NO_PROTSEQS_REGISTERED) );
}
} // if( _fEpRegister )
// Finally, register the server interface
rpcstatus = RpcServerRegisterIfEx(ifspec, NULL, NULL,
grfRpcServerRegisterInterfaceEx,
cMaxCalls, NULL );
if (rpcstatus != RPC_S_OK && rpcstatus != RPC_S_TYPE_ALREADY_REGISTERED)
{
TrkLog((TRKDBG_ERROR, TEXT("RpcServerRegisterIf %08x"), rpcstatus));
TrkReportInternalError( THIS_FILE_NUMBER, __LINE__,
HRESULT_FROM_WIN32(rpcstatus), TRKREPORT_LAST_PARAM );
TrkRaiseWin32Error(rpcstatus);
}
}
__finally
{
if( NULL != pBindingVector )
RpcBindingVectorFree( &pBindingVector );
if( NULL != ptszStringBinding )
RpcStringFree( &ptszStringBinding );
if( NULL != ptszProtSeq )
RpcStringFree( &ptszProtSeq );
}
}
//+----------------------------------------------------------------------------
//
// CRpcServer::UnInitialize
//
// Unregister the interface, and if necessary unregister the endpoints.
//
//+----------------------------------------------------------------------------
void
CRpcServer::UnInitialize()
{
RPC_STATUS rpcstatus;
RPC_BINDING_VECTOR *pBindingVector = NULL;
if (_ifspec == NULL)
return;
// If we registered with the endpoint mapper, unreg now.
if( _fEpRegister )
{
// Ignore any errors; we should still unregister the interface
// no matter what.
rpcstatus = RpcServerInqBindings(&pBindingVector);
if (rpcstatus)
{
TrkLog((TRKDBG_ERROR, TEXT("RpcServerInqBindings %08x"), rpcstatus));
}
else
{
rpcstatus = RpcEpUnregister(_ifspec, pBindingVector, NULL);
RpcBindingVectorFree( &pBindingVector );
if( RPC_S_OK != rpcstatus && EPT_S_NOT_REGISTERED != rpcstatus )
{
TrkLog((TRKDBG_ERROR, TEXT("RpcEpUnregister %08x"), rpcstatus));
}
}
}
// Unregister the interface
rpcstatus = RpcServerUnregisterIf(_ifspec, NULL, 1 /* wait for calls */);
if (rpcstatus != RPC_S_OK)
{
TrkLog((TRKDBG_ERROR, TEXT("RpcServerUnregisterIf %08x"), rpcstatus));
//TrkRaiseWin32Error(rpcstatus);
}
CTrkRpcConfig::UnInitialize();
_ifspec = NULL;
_fEpRegister = FALSE;
}