Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

378 lines
11 KiB

/*==========================================================================
*
* Copyright (C) 2000-2002 Microsoft Corporation. All Rights Reserved.
*
* File: NameTable.h
* Content: NameTable Object Header File
*@@BEGIN_MSINTERNAL
* History:
* Date By Reason
* ==== == ======
* 03/11/00 mjn Created
* 04/09/00 mjn Track outstanding connections in NameTable
* 05/03/00 mjn Implemented GetHostPlayerRef, GetLocalPlayerRef, GetAllPlayersGroupRef
* 07/20/00 mjn Added ClearHostWithDPNID()
* 07/30/00 mjn Added hrReason to CNameTable::EmptyTable()
* 08/23/00 mjn Added CNameTableOp
* 09/05/00 mjn Added m_dpnidMask
* mjn Removed dwIndex from InsertEntry()
* 09/17/00 mjn Split m_bilinkEntries into m_bilinkPlayers and m_bilinkGroups
* mjn Changed AddPlayerToGroup and RemovePlayerFromGroup to use NameTableEntry params
* 09/26/00 mjn Removed locking from SetVersion(),GetNewVersion()
* mjn Changed DWORD GetNewVersion(void) to void GetNewVersion( PDWORD )
* 01/25/01 mjn Fixed 64-bit alignment problem when unpacking NameTable
*@@END_MSINTERNAL
*
***************************************************************************/
#ifndef __NAMETABLE_H__
#define __NAMETABLE_H__
#include "ReadWriteLock.h"
#undef DPF_SUBCOMP
#define DPF_SUBCOMP DN_SUBCOMP_CORE
//
// NameTable
//
// The NameTable consists of:
// - an array of CNameTableEntry pointers
// - short-cuts to the LocalPlayer, Host and AllPlayersGroup
// - a version number
//
// There is a list running through the free entries in the NameTable array.
// When a free entry is required, it is taken from the front of this list,
// and when an entry is released, it is added to the end of the list.
// If a particular entry is required, it must be properly removed from the
// list. This may be a little time-consuming, since the entire list may
// need to be traversed, but this will only happen on non-Host cases and
// is a small price to pay to keep the Host case timely.
//
//
// DPNIDs
//
// DPNIDs are unique identifiers for NameTable entries. They are constructed
// from the NameTable array index and the version number of the entry.
// The value 0x0 is invalid. As a result, we must prevent it from being
// generated. Since the DPNID is constructed from two parts, we can do
// this by ensuring that one of the two parts is never 0. The best
// solution is to ensure that the NameTable array index is never 0.
//
//
// Locking
//
// When locking multiple entries in the NameTable, locks should be taken
// in order based on DPNIDs. e.g. Locking two entries with DPNIDs 200 and
// 101, the lock for 101 should be taken before the lock for 200. Locks for
// groups should be taken before locks for players.
//
//**********************************************************************
// Constant definitions
//**********************************************************************
#define NAMETABLE_INDEX_MASK 0x000FFFFF
#define NAMETABLE_VERSION_MASK 0xFFF00000
#define NAMETABLE_VERSION_SHIFT 20
#define NAMETABLE_ARRAY_ENTRY_FLAG_VALID 0x0001
//**********************************************************************
// Macro definitions
//**********************************************************************
#define CONSTRUCT_DPNID(i,v) (((i & NAMETABLE_INDEX_MASK) | ((v << NAMETABLE_VERSION_SHIFT) & NAMETABLE_VERSION_MASK)) ^ m_dpnidMask)
#define DECODE_INDEX(d) ((d ^ m_dpnidMask) & NAMETABLE_INDEX_MASK)
#define VERIFY_VERSION(d,v) (((d ^ m_dpnidMask) & NAMETABLE_VERSION_MASK) == (v << NAMETABLE_VERSION_SHIFT))
//**********************************************************************
// Structure definitions
//**********************************************************************
class CPackedBuffer;
class CConnection;
class CNameTableEntry;
typedef struct _DIRECTNETOBJECT DIRECTNETOBJECT;
typedef struct _NAMETABLE_ARRAY_ENTRY
{
CNameTableEntry *pNameTableEntry;
DWORD dwFlags;
} NAMETABLE_ARRAY_ENTRY;
typedef struct _DN_NAMETABLE_INFO
{
DPNID dpnid;
DWORD dwVersion;
DWORD dwVersionNotUsed;
DWORD dwEntryCount;
DWORD dwMembershipCount;
} DN_NAMETABLE_INFO;
//**********************************************************************
// Variable definitions
//**********************************************************************
//**********************************************************************
// Function prototypes
//**********************************************************************
//**********************************************************************
// Class prototypes
//**********************************************************************
// class for NameTable
class CNameTable
{
public:
CNameTable() // Constructor
{
m_Sig[0] = 'N';
m_Sig[1] = 'T';
m_Sig[2] = 'B';
m_Sig[3] = 'L';
};
#undef DPF_MODNAME
#define DPF_MODNAME "CNameTable::~CNameTable"
~CNameTable()
{
}; // Destructor
HRESULT CNameTable::Initialize(DIRECTNETOBJECT *const pdnObject);
void CNameTable::Deinitialize( void );
void ReadLock( void )
{
m_RWLock.EnterReadLock();
};
void WriteLock( void )
{
m_RWLock.EnterWriteLock();
};
void Unlock( void )
{
m_RWLock.LeaveLock();
};
#ifdef DBG
void CNameTable::ValidateArray( void );
#endif // DBG
#ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
HRESULT CNameTable::SetNameTableSize( const DWORD dwNumEntries );
#else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
HRESULT CNameTable::GrowNameTable( void );
#endif // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
void CNameTable::ResetNameTable( void );
HRESULT CNameTable::UpdateTable(const DWORD dwIndex,
CNameTableEntry *const pNameTableEntry);
HRESULT CNameTable::InsertEntry(CNameTableEntry *const pNameTableEntry);
void CNameTable::ReleaseEntry(const DWORD dwIndex);
#undef DPF_MODNAME
#define DPF_MODNAME "CNameTable::GetNewVersion"
void GetNewVersion( DWORD *const pdwVersion )
{
DNASSERT( pdwVersion != NULL );
*pdwVersion = ++m_dwVersion;
DPFX(DPFPREP, 8,"Setting new version [%ld]",m_dwVersion);
};
#undef DPF_MODNAME
#define DPF_MODNAME "CNameTable::SetVersion"
void SetVersion( const DWORD dwVersion )
{
m_dwVersion = dwVersion;
DPFX(DPFPREP, 8,"Setting new version [%ld]",m_dwVersion);
};
DWORD GetVersion( void ) const
{
return(m_dwVersion);
};
void CNameTable::EmptyTable( const HRESULT hrReason );
HRESULT CNameTable::FindEntry(const DPNID dpnid,
CNameTableEntry **const ppNameTableEntry);
HRESULT CNameTable::FindDeletedEntry(const DPNID dpnid,
CNameTableEntry **const ppNTEntry);
HRESULT CNameTable::AddEntry(CNameTableEntry *const pNTEntry);
HRESULT CNameTable::DeletePlayer(const DPNID dpnid,
DWORD *const pdwVersion);
HRESULT CNameTable::DeleteGroup(const DPNID dpnid,
DWORD *const pdwVersion);
HRESULT CNameTable::AddPlayerToGroup(CNameTableEntry *const pGroup,
CNameTableEntry *const pPlayer,
DWORD *const pdwVersion);
HRESULT CNameTable::RemovePlayerFromGroup(CNameTableEntry *const pGroup,
CNameTableEntry *const pPlayer,
DWORD *const pdwVersion);
HRESULT CNameTable::RemoveAllPlayersFromGroup(CNameTableEntry *const pGroup);
HRESULT CNameTable::RemoveAllGroupsFromPlayer(CNameTableEntry *const pPlayer);
BOOL CNameTable::IsMember(const DPNID dpnidGroup,
const DPNID dpnidPlayer);
HRESULT CNameTable::PackNameTable(CNameTableEntry *const pTarget,
CPackedBuffer *const pPackedBuffer);
HRESULT CNameTable::UnpackNameTableInfo(UNALIGNED DN_NAMETABLE_INFO *const pdnNTInfo,
BYTE *const pBufferStart,
DPNID *const pdpnid);
CNameTableEntry *GetDefaultPlayer( void )
{
return(m_pDefaultPlayer);
};
void MakeLocalPlayer(CNameTableEntry *const pNameTableEntry);
void CNameTable::ClearLocalPlayer( void );
CNameTableEntry *GetLocalPlayer( void )
{
return(m_pLocalPlayer);
};
HRESULT CNameTable::GetLocalPlayerRef( CNameTableEntry **const ppNTEntry );
void MakeHostPlayer(CNameTableEntry *const pNameTableEntry);
void CNameTable::ClearHostPlayer( void );
BOOL CNameTable::ClearHostWithDPNID( const DPNID dpnid );
void CNameTable::UpdateHostPlayer( CNameTableEntry *const pNewHost );
CNameTableEntry *GetHostPlayer( void )
{
return(m_pHostPlayer);
};
HRESULT CNameTable::GetHostPlayerRef( CNameTableEntry **const ppNTEntry );
void MakeAllPlayersGroup(CNameTableEntry *const pNameTableEntry);
void CNameTable::ClearAllPlayersGroup( void );
CNameTableEntry *GetAllPlayersGroup( void )
{
return(m_pAllPlayersGroup);
};
HRESULT CNameTable::GetAllPlayersGroupRef( CNameTableEntry **const ppNTEntry );
HRESULT CNameTable::PopulateConnection(CConnection *const pConnection);
HRESULT CNameTable::PopulateGroup(CNameTableEntry *const pGroup);
HRESULT CNameTable::AutoCreateGroups(CNameTableEntry *const pPlayer);
HRESULT CNameTable::AutoDestructGroups(const DPNID dpnid);
void CNameTable::SetLatestVersion( const DWORD dwVersion )
{
m_dwLatestVersion = dwVersion;
};
DWORD CNameTable::GetLatestVersion( void ) const
{
return( m_dwLatestVersion );
};
void CNameTable::SetConnectVersion(const DWORD dwVersion)
{
m_dwConnectVersion = dwVersion;
};
DWORD CNameTable::GetConnectVersion( void ) const
{
return(m_dwConnectVersion);
};
#undef DPF_MODNAME
#define DPF_MODNAME "CNameTable::IncOutstandingConnections"
void IncOutstandingConnections( void )
{
long lRefCount;
lRefCount = DNInterlockedIncrement(&m_lOutstandingConnections);
DNASSERT(lRefCount > 0);
};
void SetDPNIDMask( const DPNID dpnidMask )
{
m_dpnidMask = dpnidMask;
};
DPNID GetDPNIDMask( void ) const
{
return( m_dpnidMask );
};
void CNameTable::DecOutstandingConnections( void );
CBilink m_bilinkPlayers;
CBilink m_bilinkGroups;
CBilink m_bilinkDeleted;
CBilink m_bilinkNameTableOps;
private:
BYTE m_Sig[4];
DIRECTNETOBJECT *m_pdnObject;
DPNID m_dpnidMask;
CNameTableEntry *m_pDefaultPlayer;
CNameTableEntry *m_pLocalPlayer;
CNameTableEntry *m_pHostPlayer;
CNameTableEntry *m_pAllPlayersGroup;
NAMETABLE_ARRAY_ENTRY *m_NameTableArray;
DWORD m_dwNameTableSize;
DWORD m_dwFirstFreeEntry;
DWORD m_dwLastFreeEntry;
DWORD m_dwNumFreeEntries;
DWORD m_dwVersion;
DWORD m_dwLatestVersion; // Only used by Host in PEER
DWORD m_dwConnectVersion;
LONG m_lOutstandingConnections;
CReadWriteLock m_RWLock;
};
#undef DPF_MODNAME
#endif // __NAMETABLE_H__