windows-nt/Source/XPSP1/NT/com/ole32/dcomss/objex/sset.hxx
2020-09-26 16:20:57 +08:00

288 lines
7 KiB
C++

/*++
Copyright (c) 1995-96 Microsoft Corporation
Module Name:
ssets.hxx
Abstract:
CServerSet objects represent sets of CServerOids which are owned by
a particular client. The same CServerOids may appear in a large
number of sets.
CServerSets are mangaged by an instance of the CServerSetTable
class. This object (pServerSets) can be used to allocate (exclusive lock)
and lookup (shared lock) sets. It can also be used (shared lock) by
the worker thread to rundowns old CServerSet's.
Author:
Mario Goertzel [MarioGo]
Revision History:
MarioGo 02-27-95 Bits 'n pieces
MarioGo 04-04-95 Split client and server.
MarioGo 01-06-96 Locally unique Ids, added new management class
--*/
#ifndef __SSET_HXX
#define __SSET_HXX
class CServerSet
/*++
Class Description:
Each instance for this class represtents a set of oids which are being
used by a particular client. This client may or may not be making secure
calls to this objext resolver. If the calls are secure, the SID of the
client is remembered and compared during any operation changing the
contents of the set.
Members:
_timeout - The time at which this set should rundown.
_blistOids - List of pointers to all the CServerOids in this set.
_psid - Security ID of the client. NULL for non-secure set.
_sequence - The sequence number of the last good ping. Used to
avoid problems with multiple execution since pings are idempotent.
_period - Power of two multipler for timeout period. Not implemented.
_psid - Pointer to the sid of the client or NULL.
_fLocal - (need 1 bit) non-zero if the client is on this machine.
--*/
{
private:
CTime _timeout;
PSID _psid;
CBList _blistOids;
USHORT _sequence;
USHORT _pings;
USHORT _fLocal:8; // free bits
// Free USHORT
BOOL ValidateObjects(BOOL fShared);
public:
CServerSet(USHORT sequence,
PSID psid,
BOOL fLocal) :
_blistOids(8),
_sequence(sequence - 1),
_psid(psid),
_fLocal((USHORT) fLocal)
{
_timeout += BaseTimeoutInterval; // * factor
}
~CServerSet()
{
#if DBG
CTime now;
ASSERT(now > _timeout);
#endif
if (!_fLocal)
{
ASSERT(gpPingSetQuotaManager);
gpPingSetQuotaManager->ManageQuotaForUser(_psid, FALSE);
}
delete _psid;
}
BOOL
Ping(BOOL fShared)
{
_timeout.SetNow();
_timeout += BaseTimeoutInterval; // * factor
_pings++;
if (_pings % BaseNumberOfPings == 0)
{
return(ValidateObjects(fShared));
}
return(fShared);
}
BOOL
CheckAndUpdateSequenceNumber(USHORT sequence)
{
// note: this handles overflow cases, too.
USHORT diff = sequence - _sequence;
if (diff && diff <= BaseNumberOfPings)
{
_sequence = sequence;
return(TRUE);
}
return(FALSE);
}
BOOL
CheckSecurity(HANDLE hRpc)
{
// Local calls are secure
if (0 == hRpc)
{
ASSERT(0 == _psid );
return(TRUE);
}
// No security on the set
if (0 == _psid)
{
return(TRUE);
}
BOOL f;
RPC_STATUS status;
HANDLE hT;
status = RpcImpersonateClient(hRpc);
if (status == RPC_S_OK)
{
f = OpenThreadToken(GetCurrentThread(),
TOKEN_IMPERSONATE | TOKEN_QUERY,
TRUE,
&hT);
if (!f)
{
return(FALSE);
}
}
else
{
#if DBG
SetLastError(status);
#endif
return(FALSE);
}
ULONG needed = DEBUG_MIN(1, 24);
PTOKEN_USER ptu;
do
{
ptu = (PTOKEN_USER)alloca(needed);
ASSERT(ptu);
f = GetTokenInformation(hT,
TokenUser,
(PBYTE)ptu,
needed,
&needed);
}
while( FALSE == f && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
CloseHandle(hT);
if (FALSE != f)
{
ASSERT(needed > sizeof(SID));
f = EqualSid(_psid, ptu->User.Sid);
return(f);
}
return(FALSE);
}
ORSTATUS AddObject(OID &oid);
void RemoveObject(OID &oid);
BOOL ShouldRundown() { CTime now; return(now > _timeout); }
BOOL Rundown();
};
class CServerSetTable
/*++
Class Description:
Management class for allocating and looking up CServerSets.
Each set is associated with an ID which is made up of an index
and a sequence number. The index is used to index into _pElements
and the sequence number is used to avoid problems with old set ID
and a new server.
Members:
_pElements - An array (size _cMax) of IndexElement structures
IndexElement-
_sequence - A sequence number used to detect invalid
referneces to a slot which has rundown and been realloc'd.
_pSet - A pointer to the actual CServerSet. If the
slot is free it is 0x80000000 & index of next free slot.
_cMax - The number of slots in _pElements.
_cAllocated - The number of slots in use.
_iFirstFree - (Hint) A starting place of where to look when trying
to insert. No elements < _iFirstFree are free.
_iRundown - Index of the rundown checker. It is written
to with a shared lock held. This is okay.
--*/
{
struct IndexElement {
DWORD _sequence;
CServerSet *_pSet;
};
public:
CServerSetTable(ORSTATUS &status) :
_cMax(DEBUG_MIN(16,4)),
_cAllocated(0),
_iFirstFree(0),
_iRundown(0)
{
_pElements = new IndexElement[_cMax];
if (!_pElements)
{
status = OR_NOMEM;
}
else
{
OrMemorySet(_pElements, 0, sizeof(IndexElement) * _cMax);
status = OR_OK;
}
}
CServerSet *Allocate(IN USHORT sequence,
IN PSID psid,
IN BOOL fLocal,
OUT ID &setid);
CServerSet *Lookup(IN ID setid);
DWORD Size() {
return(_cAllocated);
}
// Used for set cleanup by worker and SimplePing.
ID CheckForRundowns();
BOOL RundownSetIfNeeded(SETID id);
void PingAllSets();
private:
IndexElement *_pElements;
DWORD _cMax;
DWORD _cAllocated;
DWORD _iFirstFree;
DWORD _iRundown;
};
#endif // __SSET_HXX