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

📄 scm.cpp

📁 This is a source code of VxWorks
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    // Now activate the requested object/class -- first we need to    // know the current object-exporter so we can discover its    // IRemUnknown IPID and OXID value...    ObjectExporter* pExp = objectExporter ();    *pOxid = pExp->oxid ();    *pIpidRemUnknown = pExp->ipidRemUnknown ();    HRESULT hrActivation = instanceCreate (mode,					   *pClsid,					   nInterfaces,					   mqi);    // Check that the entire activation was successful, i.e. all    // marshaling worked...    DUALSTRINGARRAY* pdsa = 0;        if (SUCCEEDED (hrActivation))	{	// Now marshal each of the resulting interface pointers, and	// output the HRESULTs. We also need to release the local	// reference from each interface-ptr before it is exported. At	// least one of the MQIs must have succeeded or else we return	// E_NOINTERFACE as the hrActivation...	bool allFailed = true;	bool someFailed = false;		for (DWORD k=0; k < nInterfaces; ++k)	    {	    // Marshal each individual interface ptr, or else fail it	    // with the appropriate error-code...	    	    HRESULT hrm = mqiMarshal (*pClsid, mqi [k], &ppItfData [k]);	    if (FAILED (hrm))		pResults [k] = hrm;	    else		pResults [k] = mqi [k].hr;	    // Fail the overall result if any individual interface	    // failed to be marshaled, otherwise release the local ref	    // as the interface has now been remoted successfully...		    if (SUCCEEDED (pResults [k]))		{		allFailed = false;		mqi [k].pItf->Release ();		}	    else		{		someFailed = true;		hrActivation = mqi [k].hr;		}	    }	// Decide on result -- if all failed that must take priority...	if (someFailed)	    hrActivation = CO_S_NOTALLINTERFACES;	if (allFailed)	    hrActivation = E_NOINTERFACE;	if (SUCCEEDED (hrActivation))	    {	    	    // Find the address and endpoint of the exporter that is	    // exporting the object that has just been marshaled	    BSTR bsSvrAddr;	    hrActivation = pExp->addressBinding (&bsSvrAddr);	    if (SUCCEEDED (hrActivation))		{		const OLECHAR wszSecInfo [] = { 0x0A, 0xFFFF, 0 };		// Allocate memory to hold the DSA, allowing some		// leeway at the end (16 bytes)...		const DWORD dsaLen = sizeof (DUALSTRINGARRAY) + 				     (2 * SysStringLen (bsSvrAddr)) +				     (2 * vxcom_wcslen (wszSecInfo)) +				     16;	    		pdsa = (DUALSTRINGARRAY*) CoTaskMemAlloc (dsaLen);		if (pdsa)		    {		    // Format the DSA...		    hrActivation = orpcDSAFormat (pdsa,						  dsaLen,						  bsSvrAddr,						  wszSecInfo);		    }		else		    // Memory ran out?		    hrActivation = E_OUTOFMEMORY;	    		SysFreeString (bsSvrAddr);		}	    }	}        // Activation HRESULT is an out-arg...    *phr = hrActivation;    *ppdsaOxidBindings = pdsa;    // free up the mqi structure allocated on the heap    delete []mqi;    // This function always returns S_OK...    return S_OK;    }////////////////////////////////////////////////////////////////////////////// SCM::mqiMarshal -- marshals a single MULTI_QI entry into an// MInterfacePointer structure...//HRESULT SCM::mqiMarshal    (    REFCLSID		clsid,		// class ID of containing object    const MULTI_QI&	mqi,		// MULTI_QI structure    MInterfacePointer** ppMIP		// output is marshaled ptr    )    {    // Check the MQI contains a valid result...    if (FAILED (mqi.hr))	{	*ppMIP = 0;	return mqi.hr;	}        // Create a stream...    IStream* pStrm=0;    HRESULT hr = VxRWMemStream::CreateInstance (0,						IID_IStream,						(void**) &pStrm);    if (SUCCEEDED (hr))	{	// Marshal interface-ptr into stream - we use the object	// exporter to do this...	ObjectExporter* pExp = objectExporter ();	COM_ASSERT (pExp);	hr = pExp->objectMarshal (clsid,				  pStrm,				  *(mqi.pIID),				  mqi.pItf,				  MSHCTX_DIFFERENTMACHINE,				  0,				  MSHLFLAGS_NORMAL,				  0);	// Now convert the marshaled packet into a MInterfacePointer...	if (SUCCEEDED (hr))	    {	    ISimpleStream* pss=0;	    hr = pStrm->QueryInterface (IID_ISimpleStream,					(void**) &pss);	    if (SUCCEEDED (hr))		{		size_t strmSize = pss->size ();		pss->locationSet (0);		MInterfacePointer* mip		    = (MInterfacePointer*) CoTaskMemAlloc (sizeof							   (MInterfacePointer) +							   strmSize);		if (mip)		    {		    mip->ulCntData = strmSize;		    pss->extract (mip->abData, strmSize);		    pStrm->Release ();		    }		else		    hr = E_OUTOFMEMORY;		*ppMIP = mip;		}	    }	pStrm->Release ();	}    return hr;    }//////////////////////////////////////////////////////////////////////////////// IndirectActivation - activate remote server on behalf of local client////HRESULT SCM::IndirectActivation    (    LPWSTR              pwszServerName, // PROTSEQ + server name     REFGUID		clsid,          // CLSID to activate    DWORD		mode,           // all-1's == get-class-obj    DWORD		nItfs,          // num of interfaces    IID*		iids,           // array of IIDs    MInterfacePointer**	ppItfData,	// returned interface(s)    HRESULT*		pResults	// returned results per i/f    )    {    // Create a string-binding representing the remote SCM...    RpcStringBinding sbRemoteScm (pwszServerName+1,				  pwszServerName[0],				  VXDCOM_SCM_ENDPOINT);    // Prepare for RemoteActivation call...    ORPCTHIS		orpcThis;    ORPCTHAT		orpcThat;    OXID		oxid;    IPID		ipidRemUnknown;    HRESULT		hrActivation;    DUALSTRINGARRAY*	pdsaOxidBinding = 0;    USHORT		arProtseqs [] = { pwszServerName[0] };    COMVERSION		serverVersion;    DWORD               authnHint;	    // Initialise in-args...    orpcThis.version.MajorVersion = 5;    orpcThis.version.MinorVersion = 1;    orpcThis.flags = 0;    orpcThis.reserved1 = 0;    orpcThis.causality = CLSID_NULL;    orpcThis.extensions = 0;    // Get an RPC binding handle to the SCM on the machine where the    // object (or rather its class-object) lives. We don't need to    // free the binding handle later as it belongs to the RemoteSCM    // object itself. First we look to see if we already have a    // connection to that remote SCM...     SPRemoteSCM& pscm = m_remoteScmTable [sbRemoteScm];    if (! pscm)        pscm = new RemoteSCM (sbRemoteScm);     IOrpcClientChannelPtr pClient = pscm->connectionGet ();    // Request activation - note that this function is defined to    // always return S_OK even if some of the internal activation    // results are failures...    HRESULT hr = IRemoteActivation_RemoteActivation_vxproxy        (pClient,			// Client handle         &orpcThis,			// ORPCTHIS         &orpcThat,			// [out] ORPCTHAT         (CLSID*)&clsid,		// CLSID         0,				// pwszObjName         0,				// pObjStorage         0,				// imp level         mode,                          // class-mode?         nItfs,                         // num itfs         iids,                          // IIDs         1,                             // num protseqs         arProtseqs,                    // array of protseqs         &oxid,                         // [out] oxid         &pdsaOxidBinding,		// [out] string binding         &ipidRemUnknown,		// [out] ipid of rem-unknown         &authnHint,                    // [out] auth hint         &serverVersion,		// [out] server version         &hrActivation,                 // [out] activation result         ppItfData,			// [out] resulting interfaces         pResults);			// [out] results for each QI    // Check results...    if (FAILED (hr))        return hr;    if (FAILED (hrActivation))        return hrActivation;    if (! pdsaOxidBinding)        return E_FAIL;	    // Now we have discovered the OXID-resolution for the OXID that is    // exporting the newly-created object, we need to tell the SCM    // about it...    oxidBindingUpdate (oxid,                       sbRemoteScm,                       ipidRemUnknown,                        RpcStringBinding (pdsaOxidBinding));    return S_OK;    }//////////////////////////////////////////////////////////////////////////////// instanceCreate -- creates an instance of a class, marshals its// interface(s), and returns the whole lot in one go! This is used by// the SCM to create instances in response to external requests via// the IRemoteActivation interface.//HRESULT SCM::instanceCreate    (    DWORD		mode,		// get-class-obj?    REFCLSID		clsid,		// CLSID to create    DWORD		nInterfaces,	// num i/f's to return    MULTI_QI*		mqi		// resulting itf ptrs    )    {    // First create a class-factory object...    cout << "In SCM::instanceCreate" << endl;        IUnknown* punk=0;    IClassFactory* pCF;    HRESULT hr = comClassObjectGet (clsid,                                    CLSCTX_INPROC_SERVER,                                    "",                                    IID_IClassFactory,                                    (void**) &pCF);    if (FAILED (hr))        {        cout << "no class object" << endl;        return hr;        }    // If we are being called in CLASS-MODE then just return the    // class-factory pointer, otherwise create an instance and QI    // it for all requested interfaces...    if (mode == MODE_GET_CLASS_OBJECT)        {        punk = pCF;        }    else        {        // Create an instance of the class...        hr = pCF->CreateInstance (0,                                  IID_IUnknown,                                  (void**) &punk);        pCF->Release();        }            // Now QI for each of the requested interfaces...    if (SUCCEEDED (hr))        {        for (ULONG n=0; n < nInterfaces; ++n)            {            mqi[n].hr = punk->QueryInterface (*(mqi[n].pIID),                                              (void**) &mqi[n].pItf);            if (FAILED (mqi[n].hr))                hr = CO_S_NOTALLINTERFACES;            }        punk->Release ();        }    else        cout << "class-factory failed" << endl;        return hr;    }////////////////////////////////////////////////////////////////////////////// oxidBindingUpdate -- update our table of OXID-resolver and// RemoteOxid entries...//void SCM::oxidBindingUpdate    (    OXID			oxid,    const RpcStringBinding&	sbRemoteScm,    REFIPID			ipidRemUnk,    const RpcStringBinding&	sbRemoteOxid    )    {    // See if we already know about a remote SCM at this address...    SPRemoteSCM& rscm = m_remoteScmTable [sbRemoteScm];    // If not, make a new one...    if (! rscm)	rscm = new RemoteSCM (sbRemoteScm);    // Now update its knowledge of this OXID...    rscm->oxidBindingUpdate (oxid, ipidRemUnk, sbRemoteOxid);    }////////////////////////////////////////////////////////////////////////////// oxidResolve -- given an OXID and a string-binding to the remote// machine on which the OXID is known to exist, return the address of// the actual remote Object Exporter. The 'resAddr' may contain the// port-number 135, or may omit it...//HRESULT SCM::oxidResolve    (    OXID			oxid,    const RpcStringBinding&	resAddr,    SPRemoteOxid&		remOxid    )    {    // Create string-binding to remote SCM/OxidResolver, with explicit    // port-number...    RpcStringBinding sbor (resAddr.ipAddress (),			   resAddr.protocolSequence (),			   VXDCOM_SCM_ENDPOINT);    // If we don't already have a RemoteSCM object representing that    // network address, then create one...    SPRemoteSCM rscm = 0;    {    VxCritSec cs1 (m_mutex);    REMOTESCMMAP::const_iterator s = m_remoteScmTable.find (sbor);    if (s == m_remoteScmTable.end ())	{	rscm = new RemoteSCM (sbor);	m_remoteScmTable [sbor] = rscm;	}    else	rscm = (*s).second;    }    // Now see if it knows about the specific OXID...    if (! rscm->oxidBindingLookup (oxid, remOxid))	{	IPID			ipidRemUnk;	DWORD			authnHint;	DUALSTRINGARRAY*	pdsa=0;	OLECHAR			arProtseqs [] = { NCACN_IP_TCP };	HRESULT			hr = S_OK;		// Need to remotely query the OXID-resolver for the answer...        IOrpcClientChannelPtr pChannel = new RpcIfClient (resAddr);	    	// Find the (remote) server, given the OXID and the string-	// binding for the resolver - this will be cached and	// re-used in future if the same OXID recurs...	hr = IOXIDResolver_ResolveOxid_vxproxy (pChannel,						&oxid,						1,						arProtseqs,						&pdsa,						&ipidRemUnk,						&authnHint);	// Only S_OK is valid as a 'good' result, anything else may be	// a warning that the method failed somehow...	if (hr == S_OK)	    {            // Now we have all the info, we need to record it...            oxidBindingUpdate (oxid,                               sbor,                               ipidRemUnk,                                RpcStringBinding (pdsa));            }                	// Tidy up	if (pdsa)            CoTaskMemFree (pdsa);	}        // Return the new binding...    if (! rscm->oxidBindingLookup (oxid, remOxid))	return OR_INVALID_OXID;        return S_OK;    }////////////////////////////////////////////////////////////////////////////// SCM::SimplePing -- ping all the objects whose OIDs are in the set// indicated by 'setid'...//HRESULT SCM::SimplePing    (    SETID		setid		// [in] set ID    )    {    TRACE_CALL;        S_INFO (LOG_SCM, "SimplePing()");    // enter critical section    VxCritSec critSec (m_mutex);	    // Find the appropriate set...    OIDSETMAP::iterator i = m_oidSets.find (setid);    if (i == m_oidSets.end ())	return OR_INVALID_SET;    HRESULT hr = S_OK;    // Iterate over all OIDs in this set...    OIDSET& oidset = (*i).second;    for (OIDSET::iterator o = oidset.begin(); o != oidset.end (); ++o)	{	OID oid = (*o);        bool pinged = false;	// Ping the exporter associated with this OID - we don't know	// which one it is so try them all until we hit one	for (OXIDMAP::iterator j = m_exporters.begin ();	     j != m_exporters.end ();

⌨️ 快捷键说明

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