438 lines
8.0 KiB
C++
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
|