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

📄 stdproxy.cpp

📁 vxworks操作系统的源代码 供研究学习
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* StdProxy.cpp - COM/DCOM StdProxy class implementation *//*modification history--------------------02l,03jan02,nel  Remove use of alloca.02k,17dec01,nel  Add include symbold for diab build.02j,10oct01,dbs  add AddKnownInterface() method to IOrpcClientChannel02i,26jul01,dbs  use IOrpcClientChannel and IOrpcProxy interfaces02h,13jul01,dbs  fix up includes02g,13mar01,nel  SPR#35873. Modify code to search for first resovable address                 in dual string passed as part of marshalling an interface.02f,06mar01,nel  SPR#35589. Add code to make Oxid addresses unique to prevent                 clash with other targets.02e,05oct00,nel  SPR#34947. Correct marshling error introduced by T2 fix                 merge.02d,20sep00,nel  Add changes made in T2 since branch.02c,28feb00,dbs  fix IRemUnknown facelet so it is never Release()'ed02b,15feb00,dbs  implement IRemUnknown calls directly02a,05aug99,dbs  change to byte instead of char01z,09jul99,dbs  implement ping functionality in SCM now01y,08jul99,dbs  use SCM's oxidResolve() method always01x,06jul99,aim  change from RpcBinding to RpcIfClient01w,30jun99,dbs  remove const-ness warnings in dtor01v,30jun99,dbs  make Facelet-map contain smart-pointers01u,30jun99,dbs  fix m_facelets search in RemoteQI()01t,10jun99,dbs  remove op new and delete01s,08jun99,dbs  remove use of mtmap01r,07jun99,dbs  change GuidMap to mtmap01q,03jun99,dbs  no return value from mutex lock01p,03jun99,dbs  remove refs to comSyncLib01o,27may99,dbs  implement Ping functionality01n,20may99,dbs  free memory using CoTaskMemFree(), and reformat01m,17may99,dbs  remove IID from args of interaceInfoGet01l,13may99,dbs  change BufferInit method to interfaceInfoGet01k,11may99,dbs  simplify proxy remoting architecture01j,11may99,dbs  rename VXCOM to VXDCOM01i,10may99,dbs  simplify binding-handle usage01h,05may99,dbs  update existing RemoteOxid with resolver address01g,28apr99,dbs  use COM_MEM_ALLOC for all classes01f,27apr99,dbs  use new allocation calls01e,26apr99,aim  added TRACE_CALL01d,26apr99,dbs  add mem-pool to class01c,22apr99,dbs  tidy up potential leaks01b,21apr99,dbs  add length arg to orpcDSAFormat()01a,20apr99,dbs  created during Grand Renaming*//*  DESCRIPTION:  StdProxy -- */#include "StdProxy.h"#include "orpcLib.h"#include "dcomProxy.h"#include "OxidResolver.h"#include "PSFactory.h"#include "NdrStreams.h"#include "RpcStringBinding.h"#include "RpcIfClient.h"#include "SCM.h"/* Include symbol for diab */extern "C" int include_vxdcom_StdProxy (void)    {    return 0;    }////////////////////////////////////////////////////////////////////////////// Statics / globals...//VxStdProxy::OXID2RemApartment_t VxStdProxy::s_allProxies;VxMutex                         VxStdProxy::s_allProxiesMutex;////////////////////////////////////////////////////////////////////////////// VxStdProxy ctor -- initialise members...//VxStdProxy::VxStdProxy ()  : m_dwRefCount (0),    m_pOxid (0),    m_oid (0),    m_pRemUnknown (0),    m_pRemUnkFacelet (0)    {    }//////////////////////////////////////////////////////////////////////////// VxStdProxy dtor -- remove this proxy from records, and remove its// OID from the ping tables in the SCM...//VxStdProxy::~VxStdProxy ()    {    // Remove this proxy from list of all known proxies    s_allProxiesMutex.lock ();    OXID2RemApartment_t::iterator i = s_allProxies.find (oxid ());    if (i != s_allProxies.end ())        (*i).second.erase (oid ());    s_allProxiesMutex.unlock ();    // Remove our OID from the ping list..    SCM::theSCM()->oidDel (m_resAddr, m_oid);    // Disconnect all facelets belonging to this proxy-object...    FACELETMAP::iterator j;    VxCritSec cs (m_mutex);        for (j = m_facelets.begin (); j != m_facelets.end (); ++j)	{        // @@@ FIXME have a fake interface-proxy for IUnknown        if ((*j).second.pProxy)            (*j).second.pProxy->Disconnect ();	}    // Free the RemUnknown facelet    if (m_pRemUnkFacelet)        {        m_pRemUnkFacelet->pProxy->Disconnect ();        delete m_pRemUnkFacelet;        }    }////////////////////////////////////////////////////////////////////////////// UnmarshalInterface - initialises the proxy object, newly created in// the client task, by reading the stream and extracting the OBJREF// from it. The OBJREF is always marshaled in little-endian byte// order, so it may have to be corrected.//// When unmarshaling an interface pointer, if the IID of the interface// being unmarshaled is IID_IUnknown, then we can create a VxStdProxy// and we don't need to QI since IUnknown is explicitly implemented// by VxStdProxy. If we are unmarshaling another interface (not// IUnknown), then we need to know if we already have this object (i.e.// an instance of VxStdProxy with the same OXID and OID) proxied locally.// If so, we should simply QI that object for the desired interface. If// not, then we need to create a new VxStdProxy (which gives us an// IUnknown proxy) and QI that for the desired interface. This is// not currently implemented, however -- there don't seem to be any// valid cases where we could get separately-marshaled interfaces// for the same object.//HRESULT VxStdProxy::UnmarshalInterface    (    IStream*        pStm,    REFIID          riid,    void**          ppv    )    {    TRACE_CALL;    // Preset results...    HRESULT hr = S_OK;    *ppv = 0;        // Unmarshal data from packet - first find out how big the    // packet is...    ULARGE_INTEGER len;    pStm->Seek (0, STREAM_SEEK_END, &len);    if (len > OBJREF_MAX)        return RPC_E_INVALID_OBJREF;    // Read the packet into a local buffer...    byte mshlbuf [OBJREF_MAX];    pStm->Seek (0, STREAM_SEEK_SET, 0);    pStm->Read (mshlbuf, len, 0);    // Prepare an NDR stream to assist unmarshaling    NdrUnmarshalStream	us (NdrPhase::NOPHASE,			    VXDCOM_DREP_LITTLE_ENDIAN,			    mshlbuf,			    sizeof (mshlbuf));    // Unmarshal...    OBJREF* pObjRef = (OBJREF*) malloc (len);    hr = ndrUnmarshalOBJREF (&us, pObjRef);    if (FAILED (hr))        return hr;    // Record OID (Object ID), OXID (object-exporter ID - this can be    // used to look up the IPID of the IRemUnknown later) and IPID of    // the new interface pointer...    OID oidNew = pObjRef->u_objref.u_standard.std.oid;    IPID ipidNew = pObjRef->u_objref.u_standard.std.ipid;    DWORD nRefs = pObjRef->u_objref.u_standard.std.cPublicRefs;    OXID oxidNew = pObjRef->u_objref.u_standard.std.oxid;    DUALSTRINGARRAY* pdsa = &pObjRef->u_objref.u_standard.saResAddr;    // Check the DUALSTRINGARRAY entries, to find one which can be    // 'resolved' into an IP address on this machine. Win2K sometimes    // provides hostnames as well as the IP numbers that NT usually    // sends, so we need to scan the array to find an IP number...        RpcStringBinding remoteAddr = RpcStringBinding (pdsa, VXDCOM_SCM_ENDPOINT);    // If we couldn't resolve any addresses, we bail out now...    if (! remoteAddr.resolve ())        {        free (pObjRef);        return MAKE_HRESULT (SEVERITY_ERROR,                             FACILITY_RPC,                             RPC_S_INVALID_NET_ADDR);        }    if (remoteAddr.isLocalhost ())	{	// Its on this machine, so we must find the object table entry	// corresponding to the given OXID/OID/IPID combination...	ObjectExporter* pExp = SCM::theSCM()->objectExporter ();	if (pExp->oxid () != oxidNew)	    return OR_INVALID_OXID;	ObjectTableEntry* pOTE = pExp->objectFindByOid (oidNew);	if (! pOTE)	    return OR_INVALID_OID;	// Now we have the right object table entry, we must find the	// right interface pointer corresponding to the IPID and	// IID...	IUnknown* punk = pOTE->stdStub.getIUnknown ();	if (! punk)	    return E_UNEXPECTED;	// Now just QI for the requested interface...	hr = punk->QueryInterface (riid, ppv);	// Now we have an extra local ref, since the 'exported'	// reference was never actually exported???	}    else	{	// If the OID and OXID match that of an existing proxy, then this	// interface must belong to that object. In this case, we defer	// the interface to that object, adding the interface-proxy to	// that object, and calling Release() for this one so it can be	// destroyed when the caller is done with it...	VxStdProxy*	rcvr=0;        // Lock 'allProxies' mutex while we search...        s_allProxiesMutex.lock ();        // First, find (or create, if it doesn't exist already) a        // 'remote apartment' with the given OXID identifier...        RemoteApartment_t& apt = s_allProxies [oxidNew];        // Now look for an object in this apartment with the same        // OID -- if it exists, its the same object as far as we are        // concerned...        RemoteApartment_t::iterator i = apt.find (oidNew);        if (i == apt.end ())            {	    // No extant proxy has this OID/OXID combination, so this	    // object must become a true proxy...	    rcvr = this;	    m_oid = oidNew;		    // Insert into list of all known proxies...            apt [oidNew] = this;            // Its now safe to unlock...            s_allProxiesMutex.unlock ();	    // Ask the SCM to resolve the OXID and resolver-address	    // (from the OBJREF) into a string-binding we can use to	    // talk to the actual remote object...	    m_resAddr = remoteAddr;	    hr = SCM::theSCM()->oxidResolve (oxidNew,					     remoteAddr,					     m_pOxid);	    if (SUCCEEDED (hr))		{		m_pChannel = new RpcIfClient (m_pOxid->stringBinding ());		if (m_pChannel == 0)		    hr = E_OUTOFMEMORY;                // Now create a special facelet to handle the                // IRemUnknown methods within this proxy. After                // creation the interface proxy has one reference, and                // when we QI it for IRemUnknown that adds a ref to                // this StdProxy (since the interface-proxy delegates                // its public interface's IUnknown methods to this                // StdProxy object). However, we want to keep                // IRemUnknown hidden, so we don't need this extra                // ref. Hence, the Release() if the facelet creation                // succeeds...                IOrpcProxy* pProxy = 0;                VxPSFactory* pPSFactory = VxPSFactory::theInstance ();                hr = pPSFactory->CreateProxy (this,                                               IID_IRemUnknown,                                              m_pOxid->ipidRemUnknown (),                                              &pProxy);                if (SUCCEEDED (hr))                    {                    // Connect the proxy...                    pProxy->Connect (m_pChannel);                                        // Now make a special facelet, and get the actual                    // IRemUnknown pointer out, too...                    m_pRemUnkFacelet = new facelet_t (pProxy,                                                      0,                                                      m_pOxid->ipidRemUnknown ());                     // Now get the IRemUnknown interface we want...                    hr = pProxy->QueryInterface (IID_IRemUnknown,                                                 (void**) &m_pRemUnknown);                    if (SUCCEEDED (hr))                        Release ();                    // Now the facelet has its own reference to the                    // interface-proxy, so we can drop the original                    // one we got from CreateProxy()...                    pProxy->Release ();                    }		// Add our OID to the SCM's list of OIDs belonging to		// the remote machine where our real object resides...		SCM::theSCM()->oidAdd (m_resAddr, m_oid);		}            }        else            {	    // Found an object with the same OID/OXID - we must add	    // the new interface to it, and this object is just	    // serving as an unmarshaler, so can be destroyed after	    // this function completes its job...	    hr = S_OK;	    rcvr = (*i).second;            s_allProxiesMutex.unlock ();	    }	// If we have a std-proxy suitable to handle this interface,	// then add a facelet to it for the requested interface ID -	// this will take care of registering the IPID against the	// interface-ptr we export to the client... 	if (SUCCEEDED (hr))	    hr = rcvr->faceletAdd (riid, ipidNew, nRefs, ppv);        }        // Tidy up...    free (pObjRef);    return hr;    }        ////////////////////////////////////////////////////////////////////////////HRESULT VxStdProxy::ReleaseMarshalData    (    IStream*	pStm    )    {    TRACE_CALL;    return S_OK;    }////////////////////////////////////////////////////////////////////////////// VxStdProxy::DisconnectObject - disconnect all out-of-process clients//// Call Disconnect() for all interface proxies (facelets).//HRESULT VxStdProxy::DisconnectObject    (    DWORD	dwReserved    )    {    if (! m_pChannel)        return CO_E_OBJNOTCONNECTED;    FACELETMAP::iterator i;    VxCritSec cs (m_mutex);        for (i = m_facelets.begin (); i != m_facelets.end (); ++i)        {        (*i).second.pProxy->Disconnect ();        }    return S_OK;    }////////////////////////////////////////////////////////////////////////////// VxStdProxy::AddRef - implements AddRef() method of IUnknown// implementation...//ULONG VxStdProxy::AddRef ()    {

⌨️ 快捷键说明

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