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
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__
|
|
|
|
|