2020-09-30 17:12:29 +02:00

438 lines
8.0 KiB
C++

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
oxid.hxx
Abstract:
COxid objects represent OXIDs which are in use by processes on this machine.
These always contain a pointer to a process object and a ping set.
Author:
Satish Thatte [SatishT]
Revision History:
SatishT 02-07-96 Merged and simplified Client and Server Oxid classes
--*/
#ifndef __OXID_HXX
#define __OXID_HXX
struct COxidInfo
{
DWORD _dwTid;
DWORD _dwPid;
IPID _ipidRemUnknown;
DWORD _dwAuthnHint;
CDSA _dsaBindings;
COxidInfo(const OXID_INFO& OxidInfo)
: _dwTid(OxidInfo.dwTid),
_dwPid(OxidInfo.dwPid),
_ipidRemUnknown(OxidInfo.ipidRemUnknown),
_dwAuthnHint(OxidInfo.dwAuthnHint), // BUGBUG: global setting OK?
_dsaBindings(OxidInfo.psa) // bindings are process-wide, except for remote OXIDs
{}
operator OXID_INFO()
{
OXID_INFO result;
result.dwTid = _dwTid;
result.dwPid = _dwPid;
result.ipidRemUnknown = _ipidRemUnknown;
result.dwAuthnHint = _dwAuthnHint;
result.psa = _dsaBindings;
return result;
}
ORSTATUS Assign(const COxidInfo& Info);
};
class CId2Key : public ISearchKey
{
public:
CId2Key(const ID id1, const ID id2) : _id1(id1), _id2(id2) { }
virtual DWORD
Hash()
{
return( (DWORD)_id2 ^ (*((DWORD *)&_id2 + 1))
^ (DWORD)_id1 ^ (*((DWORD *)&_id1 + 1)) );
}
virtual BOOL
Compare(ISearchKey &tk)
{
CId2Key &idk = (CId2Key &)tk;
return(idk._id2 == _id2
&& idk._id1 == _id1);
}
ID Id1()
{
return _id1;
}
ID Id2()
{
return _id2;
}
protected:
ID _id1,_id2;
};
class COid : public CTableElement, public CTime // the time of last release, implicitly
// set to creation time by constructor
/*++
Class Description:
Each instance of this class represents an OID registered
by a client or a server on this machine.
Members:
_pOxid - A pointer to the OXID to which this OID belongs.
We own a reference.
--*/
{
private :
COxid OR_BASED * _pOxid;
CId2Key _Key;
public :
COid( // complete constructor for remote OIDs
OID Oid,
COxid *pOxid
);
COid( // simpler constructor for local server allocation
COxid *pOxid
);
~COid();
void * operator new(size_t s)
{
return OrMemAlloc(s);
}
void operator delete(void * p) // do not inherit this!
{
OrMemFree(p);
}
operator ISearchKey&() // this allows us to be a ISearchKey as well
{
return _Key;
}
virtual DWORD Release()
{
SetNow(); // timestamp the release
return CReferencedObject::Release();
}
OXID GetOID()
{
return _Key.Id1();
}
BOOL Match(COid *pOid) // BUGBUG: ??
{
return(pOid->_pOxid == _pOxid);
}
BOOL OkToRundown();
void Rundown();
COxid *GetOxid()
{
return(_pOxid);
}
};
DEFINE_TABLE(COid)
DEFINE_LIST(COid)
class COxid : public CTableElement
/*++
Class Description:
Each instance of this class represents an OXID (object exporter,
a process or an apartment model thread).
BUGBUG: ??
Each OXID is owned,
referenced, by the owning process and the OIDs registered by
that process for this OXID.
Members:
_pProcess - Pointer to the process instance which owns this oxid.
_info - Info registered by the process for this oxid.
_pMid - Pointer to the machine ID for this OXID, we
own a reference.
_fApartment - Server is aparment model if non-zero
_fRunning - Process has not released this oxid if non-zero.
--*/
{
friend class CProcess;
friend class COid;
private:
CProcess OR_BASED *_pProcess;
COxidInfo _info;
CMid OR_BASED *_pMid;
BOOL _fApartment:1;
BOOL _fRunning:1;
BOOL _fLocal:1;
BOOL _fRundownThreadStarted:1;
HANDLE _hRundownThread;
CId2Key _Key;
USHORT _protseq;
COidTable _MyOids;
public:
COxid(
OXID Oxid, // constructor for remote OXIDs
CMid *pMid,
USHORT wProtseq,
OXID_INFO &OxidInfo
);
COxid( // constructor for local OXIDs
CProcess *pProcess,
OXID_INFO &OxidInfo,
BOOL fApartment
);
~COxid();
void * operator new(size_t s)
{
return OrMemAlloc(s);
}
void operator delete(void * p) // do not inherit this!
{
OrMemFree(p);
}
operator ISearchKey&() // this allows us to be a ISearchKey as well
{
return _Key;
}
DWORD GetTid()
{
return(_info._dwTid);
}
BOOL IsRunning()
{
return(_fRunning);
}
BOOL IsLocal()
{
return(_fLocal);
}
BOOL Apartment()
{
return(_fApartment);
}
MID GetMID()
{
return _Key.Id2();
}
OXID GetOXID()
{
return _Key.Id1();
}
CMid *GetMid()
{
return(OR_FULL_POINTER(CMid,_pMid));
}
SETID GetSetid();
ORSTATUS
COxid::UpdateInfo(OXID_INFO *pInfo)
{
ASSERT(pInfo);
return _info.Assign(*pInfo);
}
ORSTATUS GetInfo(
OUT OXID_INFO *
);
ORSTATUS GetRemoteInfo(
IN USHORT cClientProtseqs,
IN USHORT *aClientProtseqs,
IN USHORT cInstalledProtseqs,
IN USHORT *aInstalledProtseqs,
OUT OXID_INFO *pInfo
);
void RundownOids(USHORT cOids,
OID aOids[],
BYTE aStatus[]);
ORSTATUS LazyUseProtseq(USHORT, USHORT[]);
void StopRunning();
ORSTATUS StartRundownThreadIfNecessary();
ORSTATUS StopRundownThreadIfNecessary();
ORSTATUS StopTimerIfNecessary(); // must be called by owner thread
ORSTATUS OwnOid(COid *pOid)
{
return _MyOids.Add(pOid); // acquires a reference
}
COid * DisownOid(COid *pOid);
void ReleaseAllOids();
private:
friend VOID CALLBACK RundownTimerProc(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime // current system time
);
friend DWORD _stdcall RundownThread(void *self);
friend DWORD _stdcall PingThread(void);
void RundownOidsIfNecessary(IRundown *);
};
DEFINE_TABLE(COxid)
//
// decl for rundown thread function -- the parameter is the self pointer
//
DWORD _stdcall RundownThread(void *pSelf);
//
// Inline COid methods which depend on COxid methods
//
inline
COid::COid( // complete constructor for remote OIDs
OID Oid,
COxid *pOxid
) :
_Key(Oid,pOxid->GetMID()),
_pOxid(OR_BASED_POINTER(COxid,pOxid))
{
ASSERT(_pOxid);
_pOxid->Reference();
}
inline
COid::COid( // simpler constructor for local server allocation
COxid *pOxid
) :
_Key(AllocateId(),pOxid->GetMID()),
_pOxid(OR_BASED_POINTER(COxid,pOxid))
{
ASSERT(_pOxid);
_pOxid->Reference();
}
inline
COid::~COid()
{
ASSERT(_pOxid);
_pOxid->Release();
COid *pt = gpOidTable->Remove(*this); // should really not be there
ASSERT(pt == NULL && "Oid object still in global table during destruct");
}
inline
BOOL
COid::OkToRundown()
{
DWORD dwRefs = References();
ASSERT(dwRefs >= 2);
if (dwRefs > 2)
{
return FALSE;
}
else
{
// Check if the time since creation or last release is less than timeout
if ((CTime() - *this) < BaseTimeoutInterval)
{
return FALSE;
}
}
return TRUE;
}
#endif // __OXID_HXX