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

📄 stdproxy.cpp

📁 vxworks操作系统的源代码 供研究学习
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    return comSafeInc (&m_dwRefCount);    }////////////////////////////////////////////////////////////////////////////// VxStdProxy::Release - implements remote reference-counting for std// marshaling. When the last reference count is released then we// must send a msg to the server task telling it so it can clear up.//ULONG VxStdProxy::Release ()    {    DWORD n = comSafeDec (&m_dwRefCount);    // Is ref-count exhausted?    if (n == 0)	{	// Object is about to be destroyed, we need to release	// all refs we have on the remote object itself. We must	// release all refs on a per-IPID basis...	REMINTERFACEREF* pRef=0;	int nRefs=0;	{	VxCritSec cs (m_mutex);	nRefs = m_facelets.size ();	pRef = new REMINTERFACEREF [nRefs];	FACELETMAP::const_iterator i = m_facelets.begin ();	for (int n=0; n < nRefs; ++n)	    {	    facelet_t* pFacelet = (facelet_t*) &((*i).second);	    pRef [n].ipid = pFacelet->ipid;	    pRef [n].cPublicRefs = pFacelet->remoteRefCount;	    pRef [n].cPrivateRefs = 0;	    ++i;	    }	}	// Make remote call, if there are any remote refs to release	if (nRefs)	    {	    HRESULT hr = m_pRemUnknown->RemRelease (nRefs, pRef);	    if (FAILED (hr))		S_ERR (LOG_DCOM, "RemRelease failed " << hr);	    }	// Tidy up and destroy this object...	delete this;	delete []pRef;	}    return n;    }////////////////////////////////////////////////////////////////////////////// faceletFind - find a facelet for the given IID//// Searches the facelet-map for a facelet which implements <iid>, and// returns a pointer to that facelet (or NULL if not found). The// reference count of the std-proxy is the same after this operation// as before it, although it may change during it.//VxStdProxy::facelet_t * VxStdProxy::faceletFind (REFIID iid)    {    facelet_t *pFacelet = 0;    FACELETMAP::iterator i;    VxCritSec cs (m_mutex);    for (i = m_facelets.begin (); i != m_facelets.end (); ++i)        {        void* pv;                // Is it the right interface? We borrow the 'pProxy' of each        // facelet in turn (no need to addref/release since its scope        // is shorter than that of the facelet) and ask it...        IOrpcProxy* pProxy = (*i).second.pProxy;        if (pProxy)            {            HRESULT hr = pProxy->QueryInterface (iid, &pv);            if (SUCCEEDED (hr))                {                // Drop the ref-count after a successful QI, and return                // this facelet instance...                Release ();                pFacelet = &((*i).second);                break;                }            }        }    return pFacelet;    }////////////////////////////////////////////////////////////////////////////// QueryInterface - implements QI functionality for the standard proxy// object, which means that it may respond to the QI for any of the// interfaces implemented by its facelets, or to IUnknown and IMarshal// which it implements directly. It may make a remote call to// IRemUnknown::RemQueryInterface() if the requested interface is not// present in the proxy currently...//HRESULT VxStdProxy::QueryInterface    (    REFIID              iid,    void**              ppv    )    {    // Validate args...    if (! ppv)        return E_INVALIDARG;        // If its one of our own interfaces, we can return it directly...    if ((iid == IID_IUnknown) || (iid == IID_IMarshal))        {        *ppv = this;        AddRef ();        return S_OK;        }    // Is it an interface implemented by an existing facelet? If so,    // then thats the interface we want -- if not, we must go remote    facelet_t *pf = faceletFind (iid);    if (pf)        return pf->pProxy->QueryInterface (iid, ppv);        // We didn't find the interface we were looking for, so we must    // make a remote call to IRemUnknown::RemQueryInterface using the    // most convenient IPID we have to hand, which happens to be the    // first in the list...    IPID ipid =  (*(m_facelets.begin ())).second.ipid;    REMQIRESULT* pQIResult;    HRESULT hr = m_pRemUnknown->RemQueryInterface (ipid,                                                   5,                                                   1,                                                   &iid,                                                   &pQIResult);    if (FAILED (hr))        return hr;    // If the OID of the new interface isn't ours, then something went    // horribly wrong...    if (pQIResult->std.oid == m_oid)        {        hr = faceletAdd (iid,                         pQIResult->std.ipid,                         pQIResult->std.cPublicRefs,                         ppv);        }    else        hr = RPC_E_INVALID_OBJECT;    // Tidy up the returned results...    CoTaskMemFree (pQIResult);    // Tell the channel that this interface is definitely known to be    // available at the other end...    m_pChannel->AddKnownInterface (iid);    return hr;    }////////////////////////////////////////////////////////////////////////////// faceletAdd -- adds a (or operates on an existing) facelet for the// given interface (IID) to the VxStdProxy object. The// remote-ref-count for that IPID is bumped up by the given amount.//HRESULT VxStdProxy::faceletAdd    (    REFIID              iid,    REFIPID             ipid,    DWORD               nRefs,    void**              ppv    )    {    HRESULT	hr = S_OK;;    void*	pvResult=0;        // Look for existing facelet on this proxy with the right IID.    // We need to do a linear search of m_facelets, and if we find the    // right one, we need to get its 'iid' interface, too. This adds    // an extra reference to the proxy, as well...    facelet_t* pFacelet = faceletFind (iid);    // Did we find one? If not, we need to create one...    if (pFacelet)        {        // Get the requested interface, adding a local ref. Note that        // this will *never* be called for IUnknown, since QI's for        // IUnknown are handled directly by the StdProxy itself...        COM_ASSERT(iid != IID_IUnknown);        hr = pFacelet->pProxy->QueryInterface (iid, &pvResult);        // Add the remote refs...	pFacelet->remoteRefCount += nRefs;        }    else	{	// Check for explicit IUnknown special case - we must make an	// entry for the IUnknown interface in the 'm_facelets' table	// now it's IPID is known, but we don't give out the pointer	// to the facelet, instead we return the StdProxy's IUnknown,	// and the facelet is used only to count remote refs...        IOrpcProxy* pProxy=0;            	if (iid == IID_IUnknown)	    {            // For IUnknown, we don't create an interface-proxy, and            // we return the primary IUnknown of this StdProxy...            	    AddRef ();	    pvResult = static_cast<IUnknown*> (this);	    }	else    	    {	    // For other IIDs, we need to create an interface-proxy	    // from the factory. This results in one ref in pProxy,            // which we must drop later...            	    VxPSFactory* pPSFactory = VxPSFactory::theInstance ();            hr = pPSFactory->CreateProxy (this, iid, ipid, &pProxy);            if (FAILED (hr))                return hr;            // QI the proxy for the desired interface...            hr = pProxy->QueryInterface (iid, &pvResult);            if (FAILED (hr))                {                pProxy->Release ();                return hr;                }                        // Connect the proxy to the channel...            pProxy->Connect (m_pChannel);            }        // Create a facelet to refer to the interface-proxy...	VxCritSec cs (m_mutex);	m_facelets [pvResult] = facelet_t (pProxy, nRefs, ipid);        // Now drop the ref we got from CreateProxy()...        if (pProxy)            pProxy->Release ();	}    // Return resulting interface ptr...    if (ppv)	*ppv = pvResult;    return hr;    }////////////////////////////////////////////////////////////////////////////HRESULT VxStdProxy::GetUnmarshalClass    (    REFIID,     void*,     DWORD,     void*,     DWORD,     CLSID*    )    {    TRACE_CALL;    return E_NOTIMPL;     }        ////////////////////////////////////////////////////////////////////////////HRESULT VxStdProxy::GetMarshalSizeMax    (    REFIID          iid,    void*           pv,    DWORD           dwDestContext,    void*           pvDestContext,    DWORD           mshlflags,    DWORD*          pSize    )    {    TRACE_CALL;    *pSize = OBJREF_MAX;    return S_OK;    }        ////////////////////////////////////////////////////////////////////////////// MarshalInterface -- this method hands out one of our existing// remote interface-refs to another client, so we decrement the// ref-count for that IPID. If the remaining reference count has// dropped below 2 (i.e. to one) then we must go ask for some more// refs from the real object, via RemAddRef(). It is usual to ask for// 5 at a time...//HRESULT VxStdProxy::MarshalInterface    (    IStream*            pStrm,     REFIID              iid,    void*               pvInterface,     DWORD               dwDestCtx,    void*               pvDestCtx,    DWORD               mshlflags    )    {    HRESULT             hr = S_OK;    // Look for a facelet supporting the requested interface...    facelet_t* pFacelet = faceletFind (iid);    if (! pFacelet)        return E_NOINTERFACE;    // Get one reference from the facelet - if its ref-count drops to    // zero then we must request more from the original object...    if (pFacelet->remoteRefCount < 2)        {        REMINTERFACEREF ref;        HRESULT hrAddRef;                // Invoke RemAddRef() to get more refs...        ref.ipid = pFacelet->ipid;        ref.cPublicRefs = 5;        ref.cPrivateRefs = 0;        hr = m_pRemUnknown->RemAddRef (1, &ref, &hrAddRef);        if (FAILED (hr))            return hr;        if (FAILED (hrAddRef))            return hrAddRef;        pFacelet->remoteRefCount += ref.cPublicRefs;        }        // Now drop the one we want to give out...    pFacelet->remoteRefCount -= 1;        // We need to get the OXID-resolver address associated with our    // remote object exporter, to fill in the OBJREF correctly.    // Fortunately, we cached it when we unmarshaled our original    // OBJREF...    BSTR bsResAddr=0;        if (m_resAddr.format (&bsResAddr, false) != 0)        return E_FAIL;        // Fill in the OBJREF for this object...    OLECHAR wszSecInfo [] = { 0x0A, 0xFFFF, 0 };    const DWORD dsaLen = sizeof (DUALSTRINGARRAY) +                         (2 * SysStringLen (bsResAddr)) +                         (2 * vxcom_wcslen (wszSecInfo)) +                         16;    OBJREF* pObjRef = (OBJREF*) malloc (sizeof (OBJREF) + dsaLen);    if (! pObjRef)        return E_OUTOFMEMORY;        pObjRef->signature = OBJREF_SIGNATURE;    pObjRef->flags = OBJREF_STANDARD;    pObjRef->iid = iid;    pObjRef->u_objref.u_standard.std.flags = 0;    pObjRef->u_objref.u_standard.std.cPublicRefs = 1;    pObjRef->u_objref.u_standard.std.oxid = m_pOxid->oxid ();    pObjRef->u_objref.u_standard.std.oid = m_oid;    pObjRef->u_objref.u_standard.std.ipid = pFacelet->ipid;    // Fill in the DSA with the address info from the resolver...    hr = orpcDSAFormat (&pObjRef->u_objref.u_standard.saResAddr,                        dsaLen,                        bsResAddr,                        wszSecInfo);    if (SUCCEEDED (hr))        {        // Now marshal the OBJREF into the marshaling packet, so it can be        // accessed by the proxy...        NdrMarshalStream ms (NdrPhase::NOPHASE,                             VXDCOM_DREP_LITTLE_ENDIAN);            hr = ndrMarshalOBJREF (&ms, pObjRef);        if (SUCCEEDED (hr))            hr = pStrm->Write (ms.begin (), ms.size (), 0);        }    // Tidy up    free (pObjRef);    // Tidy up...    return hr;    }        

⌨️ 快捷键说明

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