413 lines
8.0 KiB
C++
413 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
|
|
|
|
|
|
class COxid; // forward decl
|
|
|
|
//
|
|
// The following package is given to a rundown thread when it is created.
|
|
// The pSelf pointer is used to do actual rundowns of owned Oids.
|
|
// The flag fKeepRunning is used by the owner COxid to signal the
|
|
// thread to stop running when the COxid dies.
|
|
//
|
|
|
|
struct SRundownThreadInfo
|
|
{
|
|
COxid *pSelf;
|
|
BOOL fKeepRunning;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct COxidInfo
|
|
{
|
|
OXID_INFO _oxidInfo; // bindings pointer is defunct
|
|
CDSA _dsaBindings; // bindings are kept separately
|
|
|
|
COxidInfo(const OXID_INFO& OxidInfo)
|
|
|
|
: _oxidInfo(OxidInfo),
|
|
_dsaBindings(OxidInfo.psa) // bindings are process-wide, except for remote OXIDs
|
|
{}
|
|
|
|
operator OXID_INFO()
|
|
{
|
|
_oxidInfo.psa = _dsaBindings;
|
|
return _oxidInfo;
|
|
}
|
|
|
|
ORSTATUS Assign(const OXID_INFO& 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 * _pOxid;
|
|
CId2Key _Key;
|
|
|
|
// declare the members needed for a page static allocator
|
|
DECL_PAGE_ALLOCATOR
|
|
|
|
public :
|
|
|
|
COid(
|
|
COxid *pOxid,
|
|
OID Oid
|
|
);
|
|
|
|
~COid();
|
|
|
|
// declare the page-allocator-based new and delete operators
|
|
DECL_NEW_AND_DELETE
|
|
|
|
COid():_Key(0,0){}
|
|
|
|
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 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 (i.e., an apartment).
|
|
|
|
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 *_pProcess;
|
|
COxidInfo _info;
|
|
CMid *_pMid;
|
|
CId2Key _Key;
|
|
USHORT _protseq;
|
|
BOOL _fApartment;
|
|
BOOL _fRunning;
|
|
BOOL _fLocal;
|
|
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
DWORD _dwTimeStamp;
|
|
} _remote;
|
|
|
|
struct
|
|
{
|
|
BOOL _fRundownThreadStarted;
|
|
HANDLE _hRundownThread;
|
|
BOOL *_pfRundownThreadKeepRunning;
|
|
} _local;
|
|
} _optional;
|
|
|
|
COidTable _MyOids;
|
|
|
|
// declare the members needed for a page static allocator
|
|
DECL_PAGE_ALLOCATOR
|
|
|
|
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();
|
|
|
|
// declare the page-allocator-based new and delete operators
|
|
DECL_NEW_AND_DELETE
|
|
|
|
operator ISearchKey&() // this allows us to be a ISearchKey as well
|
|
{
|
|
return _Key;
|
|
}
|
|
|
|
DWORD GetTid()
|
|
{
|
|
return(_info._oxidInfo.dwTid);
|
|
}
|
|
|
|
BOOL IsRunning()
|
|
{
|
|
return(_fRunning);
|
|
}
|
|
|
|
BOOL IsLocal()
|
|
{
|
|
return(_fLocal);
|
|
}
|
|
|
|
BOOL IsApartment()
|
|
{
|
|
return(_fApartment);
|
|
}
|
|
|
|
MID GetMID()
|
|
{
|
|
return _Key.Id2();
|
|
}
|
|
|
|
OXID GetOXID()
|
|
{
|
|
return _Key.Id1();
|
|
}
|
|
|
|
CMid *GetMid()
|
|
{
|
|
return _pMid;
|
|
}
|
|
|
|
CProcess *GetProcess()
|
|
{
|
|
return _pProcess;
|
|
}
|
|
|
|
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);
|
|
|
|
COid * DisownOid(COid *pOid);
|
|
|
|
void ReleaseAllOids();
|
|
|
|
BOOL HasExpired();
|
|
|
|
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 *pRundownInfo);
|
|
|
|
friend DWORD _stdcall PingThread(void);
|
|
|
|
void RundownOidsIfNecessary(IRundown *);
|
|
};
|
|
|
|
|
|
DEFINE_TABLE(COxid)
|
|
DEFINE_LIST(COxid)
|
|
|
|
//
|
|
// decl for rundown thread function -- the parameter is the rundown info
|
|
//
|
|
|
|
DWORD _stdcall RundownThread(void *pRundownInfo);
|
|
|
|
|
|
|
|
//
|
|
// Inline COid methods which depend on COxid methods
|
|
//
|
|
|
|
|
|
inline
|
|
COid::COid(
|
|
COxid *pOxid,
|
|
OID Oid = AllocateId() // default applies to local Oids
|
|
) :
|
|
_Key(Oid,pOxid->GetMID()),
|
|
_pOxid(pOxid)
|
|
{
|
|
ASSERT(_pOxid);
|
|
_pOxid->Reference();
|
|
}
|
|
|
|
|
|
inline
|
|
COid::~COid()
|
|
{
|
|
|
|
#if DBG
|
|
// This object has already been removed from gpOidTable
|
|
// However, the same OID/MID may have been subsequently
|
|
// unmarshalled and inserted again into gpOidTable.
|
|
// So we use pointer identity to make sure this
|
|
// object is not still in the table.
|
|
COid *pt = gpOidTable->Lookup(*this);
|
|
ASSERT(pt != this && "Oid object still in global table during destruct");
|
|
#endif
|
|
|
|
ASSERT(_pOxid);
|
|
_pOxid->Release();
|
|
|
|
}
|
|
|
|
#endif // __OXID_HXX
|