📄 objectexporter.cpp
字号:
/* ObjectExporter.cpp - COM/DCOM ObjectExporter class implementation *//*modification history--------------------02x,17dec01,nel Add include symbol for diab.02w,03aug01,dbs re-instate ref-counting methods02v,30jul01,dbs import T2 changes for RemAddRef and object ID02u,18jul01,dbs clean up stray printfs02t,13jul01,dbs fix use of NEW macro to operator new02s,02mar01,nel SPR#62130 - implement CoDisconnectObject.02r,13oct00,nel SPR#34947. Correct marshalling error introduced by T2 fix merge.02q,18sep00,nel SPR#33730. Merge T2 OPC fixes into T3 branch.02p,23feb00,dbs add full ref-counting impl02o,08feb00,dbs add diagnostics on RemUnknown IPID02n,19aug99,aim change assert to VXDCOM_ASSERT02m,17aug99,aim removed copy ctor and operator= from ObjectTable02l,09aug99,aim now defaults to using ThreadPools02k,30jul99,aim added thread pooling02j,26jul99,dbs move marshaling into exporter02i,15jul99,aim replaced RpcINETAddr02h,12jul99,dbs remove unwanted prints02g,09jul99,dbs copy in replacement class from NObjectExporter files01i,06jul99,dbs simplify activation mechanism01h,29jun99,dbs remove ostream << OID refs01g,29jun99,dbs make StdStub a member of ObjectTableEntry01f,28jun99,dbs make AddRef() and Release() dummy functions01e,23jun99,aim removed purify_new_leaks()01d,18jun99,aim fixed serverAddr checks01c,17jun99,aim changed assert to assert01b,08jun99,aim rework01a,27may99,aim snapshot*/#include "TraceCall.h"#include "ObjectExporter.h"#include "RpcStringBinding.h"#include "orpcLib.h"#include "ObjectTable.h"#include "StdMarshaler.h"/* Include symbol for diab */extern "C" int include_vxdcom_ObjectExporter (void) { return 0; }ObjectExporter::ObjectExporter (Reactor* r, OXID oxid) : RpcIfServer (r, &m_dispatcher, RpcIfServer::ThreadPooled), m_oxid (oxid), m_objectTable (), m_dispatcher (&m_objectTable), m_mutex (), m_oid (0), m_dwRefCount (1) { TRACE_CALL; }HRESULT ObjectExporter::addressBinding (BSTR* pbsResAddr) { TRACE_CALL; if (rpcAddressFormat (pbsResAddr) < 0) return E_FAIL; else return S_OK; }////////////////////////////////////////////////////////////////////////////// ObjectExporter -- dtor...//ObjectExporter::~ObjectExporter () { TRACE_CALL; // Unregister our own marshaled interface... objectUnregister (m_oid); }//////////////////////////////////////////////////////////////////////////////// AddRef -- standard IUnknown method//DWORD ObjectExporter::AddRef () { return comSafeInc (&m_dwRefCount); }//////////////////////////////////////////////////////////////////////////////// Release -- standard IUnknown method//DWORD ObjectExporter::Release () { DWORD n = comSafeDec (&m_dwRefCount); if (n == 0) delete this; return n; }//////////////////////////////////////////////////////////////////////////////HRESULT ObjectExporter::QueryInterface (REFIID iid, void** ppv) { TRACE_CALL; if ((iid == IID_IUnknown) || (iid == IID_IRemUnknown)) { *ppv = static_cast<IUnknown*> (this); AddRef (); return S_OK; } return E_NOINTERFACE; }//////////////////////////////////////////////////////////////////////////////// RemQueryInterface -- respond to a remote QI request...//HRESULT ObjectExporter::RemQueryInterface ( REFIPID ipid, ULONG cRefs, USHORT cIIDs, const IID* iids, REMQIRESULT** ppQIResults ) { TRACE_CALL; REMQIRESULT* pQIResults = 0; HRESULT hr = S_OK; IPID ipidNew; OID oid; ObjectTableEntry* pOTE; VxStdStub* pStub; // Find the stub-object corresponding to the IPID... oid = orpcOidFromIpid (ipid); pOTE = objectFindByOid (oid); if (pOTE) pStub = &pOTE->stdStub; else return RPC_E_INVALID_IPID; // Allocate space for results... pQIResults = (REMQIRESULT*) CoTaskMemAlloc (sizeof (REMQIRESULT) * cIIDs); // For each requested interface, add it to the stub... for (int n=0; n < cIIDs; ++n) { pQIResults [n].hResult = pStub->interfaceAdd (iids [n], cRefs, &ipidNew); if (SUCCEEDED (pQIResults [n].hResult)) { pQIResults [n].std.flags = 0; pQIResults [n].std.cPublicRefs = cRefs; pQIResults [n].std.oxid = m_oxid; pQIResults [n].std.oid = oid; pQIResults [n].std.ipid = ipidNew; } else { S_ERR (LOG_DCOM, "RemQueryInterface(" << vxcomGUID2String(iids[n]) << ") : HRESULT=0x" << pQIResults[n].hResult); hr = S_FALSE; } } // Done... *ppQIResults = pQIResults; return hr; }//////////////////////////////////////////////////////////////////////////////// RemAddRef - first check that all referenced IPIDs are valid, if any// aren't then return E_INVALIDARG and don't modify any refcounts. If// they are all valid, then update the refcounts of each of the// referenced IPIDs...//HRESULT ObjectExporter::RemAddRef ( USHORT cInterfaceRefs, REMINTERFACEREF interfaceRefs [], HRESULT* pResults ) { HRESULT hr = S_OK; int n; // Allocate array to cache OTEs... ObjectTableEntry** arrayOTEs = new ObjectTableEntry* [cInterfaceRefs]; if (! arrayOTEs) return E_UNEXPECTED; // Scan interface refs, getting OID and caching OTE pointer... for (n=0; n < cInterfaceRefs; ++n) { OID oid = orpcOidFromIpid (interfaceRefs [n].ipid); ObjectTableEntry* pOTE = objectFindByOid (oid); if (pOTE) arrayOTEs [n] = pOTE; else { // Invalid IPID - we don't do any releasing, just exit // with E_INVALIDARG... hr = E_INVALIDARG; break; } } if (SUCCEEDED (hr)) { // Now iterate over OTE pointers, adding refs... for (n=0; n < cInterfaceRefs; ++n) { arrayOTEs[n]->stdStub.AddRef (interfaceRefs[n].cPublicRefs, interfaceRefs [n].ipid); } } // Tidy up... delete [] arrayOTEs; return hr; }//////////////////////////////////////////////////////////////////////////////// RemRelease - make sure we have all valid IPIDs, if not return// E_INVALIDARG. If all okay, then remove the refs on each IPID in// turn. If this results in zero total refs on that object, then it// can be unregistered.//HRESULT ObjectExporter::RemRelease ( USHORT cInterfaceRefs, REMINTERFACEREF interfaceRefs [] ) { HRESULT hr = S_OK; int n; // Allocate array to cache OTEs... ObjectTableEntry** arrayOTEs = new ObjectTableEntry* [cInterfaceRefs]; if (! arrayOTEs) return E_UNEXPECTED; // Scan interface refs, getting OID and caching OTE pointer... for (n=0; n < cInterfaceRefs; ++n) { OID oid = orpcOidFromIpid (interfaceRefs [n].ipid); ObjectTableEntry* pOTE = objectFindByOid (oid); if (pOTE) arrayOTEs [n] = pOTE; else { // Invalid IPID - we don't do any releasing, just exit // with E_INVALIDARG... hr = E_INVALIDARG; break; } } if (SUCCEEDED (hr)) { // Now iterate over OTE pointers, releasing refs. If the // result is non-zero, then there are outstanding remote refs // on that object, so we leave it alone. If the result is zero // remote refs, then we must unregister it... for (n=0; n < cInterfaceRefs; ++n) { ObjectTableEntry* pOTE = arrayOTEs [n]; DWORD nr = pOTE->stdStub.Release (interfaceRefs[n].cPublicRefs, interfaceRefs [n].ipid); if (nr > 0) // Outstanding refs on this object, so we don't touch // it in the next scan... arrayOTEs [n] = 0; } // Now iterate over any non-NULL entries in arrayOTEs[] and // unregister them... for (n=0; n < cInterfaceRefs; ++n) { if (arrayOTEs [n]) objectUnregister (arrayOTEs[n]->oid); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -