⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scm.cpp

📁 dcom机制在vxworks上的实现源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* SCM - Service Control Manager *//* Copyright (c) 1999 Wind River Systems, Inc. *//*modification history--------------------02u,03jan02,nel  Remove usage of alloca.02t,17dec01,nel  Add include symbol for diab build.02s,06aug01,dbs  remove instance-creation from SCM02r,03aug01,dbs  remove usage of Thread class02q,01aug01,dbs  fix channel-auth for unix only02p,24jul01,dbs  fix ping-set add/del order, tidy up and comment02o,18jul01,dbs  clean up stray printfs02n,13jul01,dbs  fix up includes02m,14mar01,nel  SPR#35873. Modify code to search for first good address in                 dual string array passed as part of marshaling an interface.02l,02mar01,nel  SPR#35589. Add code to make Oxid addresses unique to prevent                 clash with other targets.02k,20sep00,nel  ensure SCM closes down properly.02j,22aug00,nel  Add assert to catch case where SCM hasn't been init and                 request of ObjectExporter is received.02i,10aug00,nel  Win2K patch.02h,07jun00,nel  Remove static c'tor dependency.02g,15feb00,dbs  add global SCM interface functions02f,20aug99,aim  make nextOID MT safe02e,19aug99,aim  fix MLK02d,19aug99,aim  change assert to VXDCOM_ASSERT02c,18aug99,dbs  improve resilience by use of RC-ptr to ObjExp02b,17aug99,aim  added Object Exporter project resources02a,17aug99,dbs  protect remote-SCM list against threads01z,05aug99,dbs  add sanity checks in CreateInstance()01y,02aug99,dbs  remove stray printf01x,26jul99,dbs  fix case where all QIs fail in successful activation01w,26jul99,dbs  move marshaling into exporter01v,22jul99,dbs  re-use remote SCM connections01u,20jul99,dbs  make sure all out-args of RemoteActivation are zeroed when                 call fails01t,16jul99,aim  serverAddress functionality moved to base class01s,15jul99,dbs  check for local-machine activation01r,15jul99,dbs  ensure proper HRESULTs are returned01q,13jul99,aim  syslog api changes01p,12jul99,aim  added timers01o,09jul99,dbs  implement ping functionality in SCM now01n,08jul99,dbs  clean up remote-SCM connection after activation01m,07jul99,dbs  init next-setid in SCM ctor01l,07jul99,dbs  only marshal resulting ptrs if activation succeeded01k,07jul99,aim  change from RpcBinding to RpcIfClient01j,06jul99,dbs  check return-value of remote-activation01i,06jul99,dbs  simplify activation mechanism01h,06jul99,dbs  make SCM create ObjectExporter at startup01g,30jun99,aim  fixed mod history01f,30jun99,aim  rework for error reporting01e,28jun99,dbs  remove defaultInstance method01d,25jun99,dbs  use channel-ID to determine channel authn status01c,18jun99,aim  resolverAddress return ObjectExporters address01b,08jun99,aim  rework01a,27may99,aim  created*/#include "SCM.h"#include "Reactor.h"#include "INETSockAddr.h"#include "ObjectExporter.h"#include "Syslog.h"#include "orpcLib.h"#include "private/comMisc.h"#include "StdProxy.h"#include "RpcIfClient.h"#include "TimeValue.h"#include "taskLib.h"/* Include symbol for diab */extern "C" int include_vxdcom_SCM (void)    {    return 0;    }EXTERN_C const VXDCOM_STUB_DISPTBL IRemoteActivation_vxstub_disptbl;EXTERN_C const VXDCOM_STUB_DISPTBL IOXIDResolver_vxstub_disptbl;EXTERN_C const VXDCOM_STUB_DISPTBL ISystemActivator_vxstub_disptbl;// SCM staticsSCM* SCM::s_theSCM = 0;////////////////////////////////////////////////////////////////////////////// SCM destructor//SCM::~SCM ()    {    COM_ASSERT (s_theSCM == this);    ObjectExporterPtr pObjectExporter = objectExporter ();    pObjectExporter->AddRef ();    if (pObjectExporter)	{	// Force the exporter to release all exported objects	pObjectExporter->objectUnregisterAll ();	// Remove it from our map...	oxidUnregister (pObjectExporter->oxid ());	}    pObjectExporter->Release ();        s_theSCM = 0;    cout << "SCM : closed down" << endl;    }////////////////////////////////////////////////////////////////////////////SCM::SCM (Reactor* r, NTLMSSP* ssp)  : RpcIfServer (r, &m_dispatcher),    m_mutex (),    m_exporters (),    m_oidSets (),    m_nextSetid (0),    m_dispatchTable (),    m_dispatcher (&m_dispatchTable),    m_ssp (ssp)    {    COM_ASSERT(s_theSCM == 0);    s_theSCM = this;        // Initialise OXID (Object Exporter ID). We factor this node's IP    // address into the OXID to make sure it has some chance of being    // unique, even among similar nodes. This code should really be    // part of the 'network addressing' classes, but that requires    // some deeper rework in future...    char hostname [64];    long adr = -1;    if (gethostname (hostname, sizeof (hostname)) == 0)        {#ifdef VXDCOM_PLATFORM_VXWORKS	adr = ::hostGetByName (hostname);#else	hostent* hp = ::gethostbyname (hostname);	if (hp != 0)            adr = (long) hp->h_addr;#endif        }    // If we got some valid IP address,     if (adr != -1)        // Use the host IP address to weight the initial OXID value...        m_nextOxid = ((LONGLONG) adr) << 32;    else        // Make some feeble attempt to randomize it...        m_nextOxid = ::time (0);    // Initialise the next available OID (Object ID), using the    // IP-factored OXID value, plus the thread ID...    m_nextOid = m_nextOxid + ::taskIdSelf ();    }//////////////////////////////////////////////////////////////////////////////// returns the string indicating the address of the IOXIDResolver// interface.HRESULT SCM::addressBinding (BSTR* pbsResAddr)    {    if (rpcAddressFormat (pbsResAddr, 0 /* no portNumber */) < 0)	return E_FAIL;    else		return S_OK;    }////////////////////////////////////////////////////////////////////////////// theSCM - returns the one and only instance//SCM* SCM::theSCM ()    {    return s_theSCM;    }////////////////////////////////////////////////////////////////////////////// registerStdInterfaces - add DCE interfaces to tables//void SCM::registerStdInterfaces ()    {    m_dispatchTable.dceInterfaceRegister	(IID_IRemoteActivation,	 &IRemoteActivation_vxstub_disptbl);    m_dispatchTable.dceInterfaceRegister	(IID_IOXIDResolver,	 &IOXIDResolver_vxstub_disptbl);    m_dispatchTable.dceInterfaceRegister	(IID_ISystemActivator,	 &ISystemActivator_vxstub_disptbl);    }////////////////////////////////////////////////////////////////////////////NTLMSSP* SCM::ssp ()    {    if (s_theSCM)	return s_theSCM->m_ssp;    return 0;    }////////////////////////////////////////////////////////////////////////////// startService - initiate a SCM service in the current task//int SCM::startService ()    {    INETSockAddr addr(VXDCOM_SCM_ENDPOINT);    Reactor r;    NTLMSSP ssp;    SCM scm (&r, &ssp);    SCM::PingTimer pingTimer;    int result = scm.init (addr);    if (result == 0)	{	scm.reactorGet()->timerAdd (&pingTimer, TimeValue (5));	S_INFO (LOG_SCM, "SCM bound to " << addr << " fd=" << scm.handleGet ());	result = scm.reactorGet()->run ();	}        return result;    }////////////////////////////////////////////////////////////////////////////// init - initialize the SCM//int SCM::init (INETSockAddr& addr)    {    registerStdInterfaces ();    int result = open (addr, reactorGet(), 1 /* reuse addr */);    if (result == 0)	{	if ((result = hostAddrGet (addr)) == 0)	    {	    // Now create the one-and-only object exporter	    ObjectExporter* pExp=0;	    HRESULT hr = newObjectExporter (&pExp);	    if (SUCCEEDED (hr))		{		oxidRegister (pExp->oxid (), pExp);		hr = pExp->init ();		if (FAILED (hr))		    {		    result = hr;		    }		}	    }	}    else        {	S_ERR (LOG_SCM|LOG_ERRNO, "cannot bind to " << addr);	}    return result;    }////////////////////////////////////////////////////////////////////////////// stopService - terminate the SCM instance by closing down reactor//int SCM::stopService ()    {    if (s_theSCM)	{	s_theSCM->reactorGet()->eventLoopEnd ();	s_theSCM->close ();	}    return 0;    }////////////////////////////////////////////////////////////////////////////// GetNextOid - return the next OID (Object ID) value//HRESULT SCM::GetNextOid (OID* pOid)    {    VxCritSec cs (m_mutex);    *pOid = ++m_nextOid;    return S_OK;    }////////////////////////////////////////////////////////////////////////////// nextOXID - return the next OXID (Object eXporter ID) value//OXID SCM::nextOXID ()    {    VxCritSec cs (m_mutex);    return ++m_nextOxid;    }////////////////////////////////////////////////////////////////////////////// nextOID - return the next OID (Object ID) value//OID SCM::nextOid ()    {    OID o;    this->GetNextOid (&o);    return o;    }//////////////////////////////////////////////////////////////////////////////// SCM::objectExporter -- returns the object exporter for the// current context, i.e. the task within which the call is made. In// future this may be PD-dependent, etc, but for now, it simply// returns the one and only exporter. Note that it *doesn't* add a// reference for it...//ObjectExporter* SCM::objectExporter ()    {    SCM* scm = theSCM ();    ObjectExporter* pExp = 0;    // enter critical section    VxCritSec critSec (scm->m_mutex);    if (scm->m_exporters.size () == 0)	pExp = 0;    else	pExp = (* (scm->m_exporters.begin ())).second;    COM_ASSERT(pExp != NULL);    return pExp;    }////////////////////////////////////////////////////////////////////////////// newObjectExporter -- utility to create an instance of the // ObjectExporter. This is a COM object, so is dealt with as such...//HRESULT SCM::newObjectExporter (ObjectExporter** ppObjExp)    {    HRESULT hr = S_OK;        // Create an instance of Object Exporter, with one ref...    ObjectExporterPtr pOX = new ObjectExporter (reactorGet(),                                               nextOXID ());    // Did we get one?    if (! pOX)        return E_OUTOFMEMORY;        // Open it on the required local endpoint...    INETSockAddr addr (g_vxdcomObjectExporterPortNumber);    if (pOX->open (addr, reactorGet(), 1) < 0)        {        // Cannot bind to loca endpoint...        pOX->Release ();        pOX = 0;        hr = MAKE_HRESULT (SEVERITY_ERROR,                           FACILITY_RPC,                           RPC_S_CANT_CREATE_ENDPOINT);        }    else        {        // Make sure we got an endpoint?        if (pOX->hostAddrGet (addr) < 0)            {            pOX->Release ();            pOX = 0;            hr = E_UNEXPECTED;            }        else            {            // Success!            S_INFO (LOG_SCM, "ObjectExporter bound to "                    << addr                    << " fd="                    << pOX->handleGet ());            }        }    if (ppObjExp)        *ppObjExp = pOX;        return hr;            }////////////////////////////////////////////////////////////////////////////// SCM::RemoteActivation -- called by external DCE clients to activate// an instance of an object-class on this machine.//HRESULT SCM::RemoteActivation    (    int			channelId,	// channel    ORPCTHIS*		pOrpcThis,	// housekeeping    ORPCTHAT*		pOrpcThat,	// returned housekeeping    GUID*		pClsid,		// CLSID to activate    OLECHAR*		pwszObjName,	// NULL    MInterfacePointer*	pObjStorage,	// NULL    DWORD		clientImpLevel,	// security    DWORD		mode,		// all-1's == get-class-obj    DWORD		nInterfaces,	// num of interfaces    IID*		pIIDs,		// size_is (nItfs)    USHORT		cReqProtseqs,	// num of protseqs    USHORT		arReqProtseqs[],// array of protseqs    OXID*		pOxid,		// returned OXID    DUALSTRINGARRAY**	ppdsaOxidBindings,// returned bindings    IPID*		pIpidRemUnknown,// returned IPID    DWORD*		pAuthnHint,	// returned security info    COMVERSION*		pSvrVersion,	// returned server version    HRESULT*		phr,		// returned activation result    MInterfacePointer**	ppItfData,	// returned interface(s)    HRESULT*		pResults	// returned results per i/f    )    {    // Preset default out-args...    pOrpcThat->flags = 1;    pOrpcThat->extensions = 0;    pSvrVersion->MinorVersion = 2;    pSvrVersion->MajorVersion = 5;    *pAuthnHint = ssp()->authnLevel ();        // First check with the authentication service that this    // channel-ID is allowed to activate objects...#ifndef VXDCOM_PLATFORM_SOLARIS    HRESULT hrChannel = E_ACCESSDENIED;    NTLMSSP* pssp = ssp ();    if (pssp)	hrChannel = pssp->channelStatusGet (channelId);#else        HRESULT hrChannel = S_OK;#endif    if (FAILED (hrChannel))	{	// Set out-args to NULL...	*pOxid = 0;	*ppdsaOxidBindings = 0;	*pIpidRemUnknown = GUID_NULL;	for (DWORD n=0; n < nInterfaces; ++n)	    {	    pResults [n] = E_FAIL;	    ppItfData [n] = 0;	    }	*phr = hrChannel;	return S_OK;	}        // allocate space for MULTI_QI array    MULTI_QI* mqi = new MULTI_QI [nInterfaces];    if (0 == mqi) return E_OUTOFMEMORY;        for (DWORD j=0; j < nInterfaces; ++j)	{	// fill MQI array with input arguments...	mqi [j].pIID = &pIIDs [j];	mqi [j].pItf = 0;	mqi [j].hr = S_OK;	// initialise output-array elements to NULL	ppItfData [j] = 0;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -