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.

285 lines
6.3 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999 - 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: vnametbl.h
  6. * Content: Voice Name Table Routines
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 03/26/00 rodtoll Created
  12. * 06/02/00 rodtoll Updated so host migration algorithm returns ID as well as order ID
  13. * 06/21/2000 rodtoll Fixed bug in error handling (not yet encountered -- but good to fix).
  14. * 07/01/2000 rodtoll Bug #38280 - DVMSGID_DELETEVOICEPLAYER messages are being sent in non-peer to peer sessions
  15. * Nametable will now only unravel with messages if session is peer to peer.
  16. * 07/09/2000 rodtoll Added signature bytes
  17. * 08/28/2000 masonb Voice Merge: Changed classhash.h to classhashvc.h
  18. * 04/09/2001 rodtoll WINBUG #364126 - DPVoice : Memory leak when Initializing 2 Voice Servers with same DPlay transport
  19. * 02/28/2002 rodtoll WINBUG #549943 - SECURITY: DPVOICE: Possible corruption of voice server state
  20. * - Addition of single operation return and delete operation to allow for protection against second
  21. * spoofed delete player message from crashing the server.
  22. *
  23. ***************************************************************************/
  24. #ifndef __NAMETABLE_H
  25. #define __NAMETABLE_H
  26. #undef DPF_SUBCOMP
  27. #define DPF_SUBCOMP DN_SUBCOMP_VOICE
  28. #define VSIG_VOICENAMETABLE 'BTNV'
  29. #define VSIG_VOICENAMETABLE_FREE 'BTN_'
  30. #undef DPF_MODNAME
  31. #define DPF_MODNAME "ClassHash_Hash"
  32. inline DWORD_PTR ClassHash_Hash( const DVID &dvidKey, UINT_PTR HashBitCount )
  33. {
  34. DWORD_PTR hashResult;
  35. hashResult = dvidKey;
  36. // Clear upper bits
  37. hashResult <<= ((sizeof(DWORD_PTR)*8)-HashBitCount);
  38. // Restore value
  39. hashResult >>= ((sizeof(DWORD_PTR)*8)-HashBitCount);
  40. return hashResult;
  41. }
  42. #define VOICE_NAMETABLE_START_BITDEPTH 6
  43. #define VOICE_NAMETABLE_GROW_BITDEPTH 2
  44. volatile class CVoiceNameTable
  45. {
  46. public:
  47. #undef DPF_MODNAME
  48. #define DPF_MODNAME "CVoiceNameTable::CVoiceNameTable"
  49. CVoiceNameTable( )
  50. {
  51. m_dwSignature = VSIG_VOICENAMETABLE;
  52. m_fInitialized = FALSE;
  53. };
  54. #undef DPF_MODNAME
  55. #define DPF_MODNAME "CVoiceNameTable::~CVoiceNameTable"
  56. ~CVoiceNameTable()
  57. {
  58. DeInitialize(FALSE, NULL, NULL);
  59. m_dwSignature = VSIG_VOICENAMETABLE_FREE;
  60. }
  61. HRESULT DeInitialize(BOOL fUnRavel, PVOID pvContext, LPDVMESSAGEHANDLER pvMessageHandler);
  62. #undef DPF_MODNAME
  63. #define DPF_MODNAME "CVoiceNameTable::Initialize"
  64. inline HRESULT Initialize()
  65. {
  66. BOOL fResult;
  67. if (!DNInitializeCriticalSection( &m_csTableLock ))
  68. {
  69. return DVERR_OUTOFMEMORY;
  70. }
  71. fResult = m_nameTable.Initialize( VOICE_NAMETABLE_START_BITDEPTH, VOICE_NAMETABLE_GROW_BITDEPTH );
  72. if( !fResult )
  73. {
  74. DPFX(DPFPREP, 0, "Failed to initialize hash table" );
  75. DNDeleteCriticalSection( &m_csTableLock );
  76. return DVERR_GENERIC;
  77. }
  78. m_fInitialized = TRUE;
  79. return DV_OK;
  80. };
  81. DWORD GetLowestHostOrderID(DVID *pdvidHost);
  82. #undef DPF_MODNAME
  83. #define DPF_MODNAME "CVoiceNameTable::IsEntry"
  84. BOOL IsEntry( const DVID dvidID )
  85. {
  86. BOOL fResult;
  87. CVoicePlayer *pEntry;
  88. Lock();
  89. fResult = m_nameTable.Find( dvidID, &pEntry );
  90. UnLock();
  91. return fResult;
  92. }
  93. #undef DPF_MODNAME
  94. #define DPF_MODNAME "CVoiceNameTable::GetEntry"
  95. inline HRESULT GetEntry( const DVID dvidID, CVoicePlayer **ppEntry, BOOL fAddReference )
  96. {
  97. BOOL fFound;
  98. Lock();
  99. fFound = m_nameTable.Find( dvidID, ppEntry );
  100. if( !fFound )
  101. {
  102. *ppEntry = NULL;
  103. UnLock();
  104. return DVERR_INVALIDPLAYER;
  105. }
  106. DNASSERT( *ppEntry != NULL );
  107. if( fAddReference )
  108. {
  109. (*ppEntry)->AddRef();
  110. }
  111. UnLock();
  112. return DV_OK;
  113. }
  114. #undef DPF_MODNAME
  115. #define DPF_MODNAME "CVoiceNameTable::AddEntry"
  116. inline HRESULT AddEntry( const DVID dvidID, CVoicePlayer *pEntry )
  117. {
  118. BOOL fFound;
  119. CVoicePlayer *pTmpEntry;
  120. Lock();
  121. fFound = m_nameTable.Find( dvidID, &pTmpEntry );
  122. if( fFound )
  123. {
  124. UnLock();
  125. return DVERR_GENERIC;
  126. }
  127. pEntry->AddRef();
  128. fFound = m_nameTable.Insert( dvidID, pEntry );
  129. if( !fFound )
  130. {
  131. pEntry->Release();
  132. UnLock();
  133. return DVERR_GENERIC;
  134. }
  135. UnLock();
  136. return DV_OK;
  137. }
  138. #undef DPF_MODNAME
  139. #define DPF_MODNAME "CVoiceNameTable::DeleteAndReturnEntry"
  140. //
  141. // This function removes and returns a record from the nametable, if one exists.
  142. // The player object returned will have the nametable's reference on the player
  143. // so the calling function MUST call release on the object to see it destroyed.
  144. //
  145. // After this function returns the player will no longer be available.
  146. //
  147. inline HRESULT DeleteAndReturnEntry( const DVID dvidID, CVoicePlayer **pTarget )
  148. {
  149. BOOL fFound;
  150. CVoicePlayer *pTmpEntry;
  151. Lock();
  152. fFound = m_nameTable.Find( dvidID, &pTmpEntry );
  153. if( !fFound )
  154. {
  155. UnLock();
  156. return DVERR_GENERIC;
  157. }
  158. if( pTmpEntry == NULL )
  159. {
  160. DNASSERT( FALSE );
  161. UnLock();
  162. return DVERR_GENERIC;
  163. }
  164. m_nameTable.Remove( dvidID );
  165. // Returning the object from the table, no release
  166. // called therefore giving the reference to the caller.
  167. *pTarget = pTmpEntry;
  168. UnLock();
  169. return DV_OK;
  170. }
  171. #undef DPF_MODNAME
  172. #define DPF_MODNAME "CVoiceNameTable::DeleteEntry"
  173. inline HRESULT DeleteEntry( const DVID dvidID )
  174. {
  175. BOOL fFound;
  176. CVoicePlayer *pTmpEntry;
  177. Lock();
  178. fFound = m_nameTable.Find( dvidID, &pTmpEntry );
  179. if( !fFound )
  180. {
  181. UnLock();
  182. return DVERR_GENERIC;
  183. }
  184. m_nameTable.Remove( dvidID );
  185. DNASSERT( pTmpEntry != NULL );
  186. // Regardless of if it was found..
  187. // Drop the reference count
  188. pTmpEntry->Release();
  189. if( !fFound )
  190. {
  191. UnLock();
  192. return DVERR_GENERIC;
  193. }
  194. UnLock();
  195. return DV_OK;
  196. }
  197. #undef DPF_MODNAME
  198. #define DPF_MODNAME "CVoiceNameTable::Lock"
  199. inline void Lock()
  200. {
  201. DNEnterCriticalSection( &m_csTableLock );
  202. }
  203. #undef DPF_MODNAME
  204. #define DPF_MODNAME "CVoiceNameTable::UnLock"
  205. inline void UnLock()
  206. {
  207. DNLeaveCriticalSection( &m_csTableLock );
  208. }
  209. protected:
  210. DWORD m_dwSignature;
  211. CClassHash<CVoicePlayer,DVID> m_nameTable;
  212. DNCRITICAL_SECTION m_csTableLock;
  213. BOOL m_fInitialized;
  214. };
  215. #undef DPF_MODNAME
  216. #endif