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

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: NameTable.h
  6. * Content: NameTable Object Header File
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 03/11/00 mjn Created
  12. * 04/09/00 mjn Track outstanding connections in NameTable
  13. * 05/03/00 mjn Implemented GetHostPlayerRef, GetLocalPlayerRef, GetAllPlayersGroupRef
  14. * 07/20/00 mjn Added ClearHostWithDPNID()
  15. * 07/30/00 mjn Added hrReason to CNameTable::EmptyTable()
  16. * 08/23/00 mjn Added CNameTableOp
  17. * 09/05/00 mjn Added m_dpnidMask
  18. * mjn Removed dwIndex from InsertEntry()
  19. * 09/17/00 mjn Split m_bilinkEntries into m_bilinkPlayers and m_bilinkGroups
  20. * mjn Changed AddPlayerToGroup and RemovePlayerFromGroup to use NameTableEntry params
  21. * 09/26/00 mjn Removed locking from SetVersion(),GetNewVersion()
  22. * mjn Changed DWORD GetNewVersion(void) to void GetNewVersion( PDWORD )
  23. * 01/25/01 mjn Fixed 64-bit alignment problem when unpacking NameTable
  24. *@@END_MSINTERNAL
  25. *
  26. ***************************************************************************/
  27. #ifndef __NAMETABLE_H__
  28. #define __NAMETABLE_H__
  29. #include "ReadWriteLock.h"
  30. #undef DPF_SUBCOMP
  31. #define DPF_SUBCOMP DN_SUBCOMP_CORE
  32. //
  33. // NameTable
  34. //
  35. // The NameTable consists of:
  36. // - an array of CNameTableEntry pointers
  37. // - short-cuts to the LocalPlayer, Host and AllPlayersGroup
  38. // - a version number
  39. //
  40. // There is a list running through the free entries in the NameTable array.
  41. // When a free entry is required, it is taken from the front of this list,
  42. // and when an entry is released, it is added to the end of the list.
  43. // If a particular entry is required, it must be properly removed from the
  44. // list. This may be a little time-consuming, since the entire list may
  45. // need to be traversed, but this will only happen on non-Host cases and
  46. // is a small price to pay to keep the Host case timely.
  47. //
  48. //
  49. // DPNIDs
  50. //
  51. // DPNIDs are unique identifiers for NameTable entries. They are constructed
  52. // from the NameTable array index and the version number of the entry.
  53. // The value 0x0 is invalid. As a result, we must prevent it from being
  54. // generated. Since the DPNID is constructed from two parts, we can do
  55. // this by ensuring that one of the two parts is never 0. The best
  56. // solution is to ensure that the NameTable array index is never 0.
  57. //
  58. //
  59. // Locking
  60. //
  61. // When locking multiple entries in the NameTable, locks should be taken
  62. // in order based on DPNIDs. e.g. Locking two entries with DPNIDs 200 and
  63. // 101, the lock for 101 should be taken before the lock for 200. Locks for
  64. // groups should be taken before locks for players.
  65. //
  66. //**********************************************************************
  67. // Constant definitions
  68. //**********************************************************************
  69. #define NAMETABLE_INDEX_MASK 0x000FFFFF
  70. #define NAMETABLE_VERSION_MASK 0xFFF00000
  71. #define NAMETABLE_VERSION_SHIFT 20
  72. #define NAMETABLE_ARRAY_ENTRY_FLAG_VALID 0x0001
  73. //**********************************************************************
  74. // Macro definitions
  75. //**********************************************************************
  76. #define CONSTRUCT_DPNID(i,v) (((i & NAMETABLE_INDEX_MASK) | ((v << NAMETABLE_VERSION_SHIFT) & NAMETABLE_VERSION_MASK)) ^ m_dpnidMask)
  77. #define DECODE_INDEX(d) ((d ^ m_dpnidMask) & NAMETABLE_INDEX_MASK)
  78. #define VERIFY_VERSION(d,v) (((d ^ m_dpnidMask) & NAMETABLE_VERSION_MASK) == (v << NAMETABLE_VERSION_SHIFT))
  79. //**********************************************************************
  80. // Structure definitions
  81. //**********************************************************************
  82. class CPackedBuffer;
  83. class CConnection;
  84. class CNameTableEntry;
  85. typedef struct _DIRECTNETOBJECT DIRECTNETOBJECT;
  86. typedef struct _NAMETABLE_ARRAY_ENTRY
  87. {
  88. CNameTableEntry *pNameTableEntry;
  89. DWORD dwFlags;
  90. } NAMETABLE_ARRAY_ENTRY;
  91. typedef struct _DN_NAMETABLE_INFO
  92. {
  93. DPNID dpnid;
  94. DWORD dwVersion;
  95. DWORD dwVersionNotUsed;
  96. DWORD dwEntryCount;
  97. DWORD dwMembershipCount;
  98. } DN_NAMETABLE_INFO;
  99. //**********************************************************************
  100. // Variable definitions
  101. //**********************************************************************
  102. //**********************************************************************
  103. // Function prototypes
  104. //**********************************************************************
  105. //**********************************************************************
  106. // Class prototypes
  107. //**********************************************************************
  108. // class for NameTable
  109. class CNameTable
  110. {
  111. public:
  112. CNameTable() // Constructor
  113. {
  114. m_Sig[0] = 'N';
  115. m_Sig[1] = 'T';
  116. m_Sig[2] = 'B';
  117. m_Sig[3] = 'L';
  118. };
  119. #undef DPF_MODNAME
  120. #define DPF_MODNAME "CNameTable::~CNameTable"
  121. ~CNameTable()
  122. {
  123. }; // Destructor
  124. HRESULT CNameTable::Initialize(DIRECTNETOBJECT *const pdnObject);
  125. void CNameTable::Deinitialize( void );
  126. void ReadLock( void )
  127. {
  128. m_RWLock.EnterReadLock();
  129. };
  130. void WriteLock( void )
  131. {
  132. m_RWLock.EnterWriteLock();
  133. };
  134. void Unlock( void )
  135. {
  136. m_RWLock.LeaveLock();
  137. };
  138. #ifdef DBG
  139. void CNameTable::ValidateArray( void );
  140. #endif // DBG
  141. #ifdef DPNBUILD_PREALLOCATEDMEMORYMODEL
  142. HRESULT CNameTable::SetNameTableSize( const DWORD dwNumEntries );
  143. #else // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  144. HRESULT CNameTable::GrowNameTable( void );
  145. #endif // ! DPNBUILD_PREALLOCATEDMEMORYMODEL
  146. void CNameTable::ResetNameTable( void );
  147. HRESULT CNameTable::UpdateTable(const DWORD dwIndex,
  148. CNameTableEntry *const pNameTableEntry);
  149. HRESULT CNameTable::InsertEntry(CNameTableEntry *const pNameTableEntry);
  150. void CNameTable::ReleaseEntry(const DWORD dwIndex);
  151. #undef DPF_MODNAME
  152. #define DPF_MODNAME "CNameTable::GetNewVersion"
  153. void GetNewVersion( DWORD *const pdwVersion )
  154. {
  155. DNASSERT( pdwVersion != NULL );
  156. *pdwVersion = ++m_dwVersion;
  157. DPFX(DPFPREP, 8,"Setting new version [%ld]",m_dwVersion);
  158. };
  159. #undef DPF_MODNAME
  160. #define DPF_MODNAME "CNameTable::SetVersion"
  161. void SetVersion( const DWORD dwVersion )
  162. {
  163. m_dwVersion = dwVersion;
  164. DPFX(DPFPREP, 8,"Setting new version [%ld]",m_dwVersion);
  165. };
  166. DWORD GetVersion( void ) const
  167. {
  168. return(m_dwVersion);
  169. };
  170. void CNameTable::EmptyTable( const HRESULT hrReason );
  171. HRESULT CNameTable::FindEntry(const DPNID dpnid,
  172. CNameTableEntry **const ppNameTableEntry);
  173. HRESULT CNameTable::FindDeletedEntry(const DPNID dpnid,
  174. CNameTableEntry **const ppNTEntry);
  175. HRESULT CNameTable::AddEntry(CNameTableEntry *const pNTEntry);
  176. HRESULT CNameTable::DeletePlayer(const DPNID dpnid,
  177. DWORD *const pdwVersion);
  178. HRESULT CNameTable::DeleteGroup(const DPNID dpnid,
  179. DWORD *const pdwVersion);
  180. HRESULT CNameTable::AddPlayerToGroup(CNameTableEntry *const pGroup,
  181. CNameTableEntry *const pPlayer,
  182. DWORD *const pdwVersion);
  183. HRESULT CNameTable::RemovePlayerFromGroup(CNameTableEntry *const pGroup,
  184. CNameTableEntry *const pPlayer,
  185. DWORD *const pdwVersion);
  186. HRESULT CNameTable::RemoveAllPlayersFromGroup(CNameTableEntry *const pGroup);
  187. HRESULT CNameTable::RemoveAllGroupsFromPlayer(CNameTableEntry *const pPlayer);
  188. BOOL CNameTable::IsMember(const DPNID dpnidGroup,
  189. const DPNID dpnidPlayer);
  190. HRESULT CNameTable::PackNameTable(CNameTableEntry *const pTarget,
  191. CPackedBuffer *const pPackedBuffer);
  192. HRESULT CNameTable::UnpackNameTableInfo(UNALIGNED DN_NAMETABLE_INFO *const pdnNTInfo,
  193. BYTE *const pBufferStart,
  194. DPNID *const pdpnid);
  195. CNameTableEntry *GetDefaultPlayer( void )
  196. {
  197. return(m_pDefaultPlayer);
  198. };
  199. void MakeLocalPlayer(CNameTableEntry *const pNameTableEntry);
  200. void CNameTable::ClearLocalPlayer( void );
  201. CNameTableEntry *GetLocalPlayer( void )
  202. {
  203. return(m_pLocalPlayer);
  204. };
  205. HRESULT CNameTable::GetLocalPlayerRef( CNameTableEntry **const ppNTEntry );
  206. void MakeHostPlayer(CNameTableEntry *const pNameTableEntry);
  207. void CNameTable::ClearHostPlayer( void );
  208. BOOL CNameTable::ClearHostWithDPNID( const DPNID dpnid );
  209. void CNameTable::UpdateHostPlayer( CNameTableEntry *const pNewHost );
  210. CNameTableEntry *GetHostPlayer( void )
  211. {
  212. return(m_pHostPlayer);
  213. };
  214. HRESULT CNameTable::GetHostPlayerRef( CNameTableEntry **const ppNTEntry );
  215. void MakeAllPlayersGroup(CNameTableEntry *const pNameTableEntry);
  216. void CNameTable::ClearAllPlayersGroup( void );
  217. CNameTableEntry *GetAllPlayersGroup( void )
  218. {
  219. return(m_pAllPlayersGroup);
  220. };
  221. HRESULT CNameTable::GetAllPlayersGroupRef( CNameTableEntry **const ppNTEntry );
  222. HRESULT CNameTable::PopulateConnection(CConnection *const pConnection);
  223. HRESULT CNameTable::PopulateGroup(CNameTableEntry *const pGroup);
  224. HRESULT CNameTable::AutoCreateGroups(CNameTableEntry *const pPlayer);
  225. HRESULT CNameTable::AutoDestructGroups(const DPNID dpnid);
  226. void CNameTable::SetLatestVersion( const DWORD dwVersion )
  227. {
  228. m_dwLatestVersion = dwVersion;
  229. };
  230. DWORD CNameTable::GetLatestVersion( void ) const
  231. {
  232. return( m_dwLatestVersion );
  233. };
  234. void CNameTable::SetConnectVersion(const DWORD dwVersion)
  235. {
  236. m_dwConnectVersion = dwVersion;
  237. };
  238. DWORD CNameTable::GetConnectVersion( void ) const
  239. {
  240. return(m_dwConnectVersion);
  241. };
  242. #undef DPF_MODNAME
  243. #define DPF_MODNAME "CNameTable::IncOutstandingConnections"
  244. void IncOutstandingConnections( void )
  245. {
  246. long lRefCount;
  247. lRefCount = DNInterlockedIncrement(&m_lOutstandingConnections);
  248. DNASSERT(lRefCount > 0);
  249. };
  250. void SetDPNIDMask( const DPNID dpnidMask )
  251. {
  252. m_dpnidMask = dpnidMask;
  253. };
  254. DPNID GetDPNIDMask( void ) const
  255. {
  256. return( m_dpnidMask );
  257. };
  258. void CNameTable::DecOutstandingConnections( void );
  259. CBilink m_bilinkPlayers;
  260. CBilink m_bilinkGroups;
  261. CBilink m_bilinkDeleted;
  262. CBilink m_bilinkNameTableOps;
  263. private:
  264. BYTE m_Sig[4];
  265. DIRECTNETOBJECT *m_pdnObject;
  266. DPNID m_dpnidMask;
  267. CNameTableEntry *m_pDefaultPlayer;
  268. CNameTableEntry *m_pLocalPlayer;
  269. CNameTableEntry *m_pHostPlayer;
  270. CNameTableEntry *m_pAllPlayersGroup;
  271. NAMETABLE_ARRAY_ENTRY *m_NameTableArray;
  272. DWORD m_dwNameTableSize;
  273. DWORD m_dwFirstFreeEntry;
  274. DWORD m_dwLastFreeEntry;
  275. DWORD m_dwNumFreeEntries;
  276. DWORD m_dwVersion;
  277. DWORD m_dwLatestVersion; // Only used by Host in PEER
  278. DWORD m_dwConnectVersion;
  279. LONG m_lOutstandingConnections;
  280. CReadWriteLock m_RWLock;
  281. };
  282. #undef DPF_MODNAME
  283. #endif // __NAMETABLE_H__