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.

336 lines
8.2 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name :
  4. shash.hxx
  5. Abstract:
  6. This file contains type definitions hash table support
  7. Author:
  8. Revision History:
  9. Rohan Phillips (RohanP) MARCH-08-1997 - modified for SMTP
  10. --*/
  11. #ifndef _SHASH_H_
  12. #define _SHASH_H_
  13. #include <limits.h>
  14. #define TURN_DATA_SIGNATURE_VALID 'TDSV'
  15. #define TURN_DATA_SIGNATURE_FREE 'TDSF'
  16. #define LAST_SMTP_ACTION ((DOMAIN_ROUTE_ACTION_TYPE)BitFlag(1)|BitFlag(2) | BitFlag(3))
  17. class CSMTP_HASH_TABLE;
  18. class CTurnData;
  19. class CHASH_ENTRY
  20. {
  21. protected:
  22. DWORD m_Signature;
  23. LONG m_RefCount;
  24. BOOL m_InList;
  25. CSMTP_HASH_TABLE * m_MyTable;
  26. private:
  27. DWORD m_NumAccess;
  28. BOOL m_fWildCard;
  29. public:
  30. LIST_ENTRY m_ListEntry;
  31. CHASH_ENTRY(DWORD Signature)
  32. {
  33. m_Signature = Signature;
  34. m_RefCount = 0;
  35. m_InList = FALSE;
  36. m_NumAccess = 0;
  37. m_MyTable = NULL;
  38. m_fWildCard = FALSE;
  39. }
  40. void SetWildCard(void) { m_fWildCard = TRUE; }
  41. void ClearWildCard(void) { m_fWildCard = FALSE; }
  42. BOOL IsWildCard(void) {return m_fWildCard;}
  43. LIST_ENTRY & QueryListEntry(void) {return ( m_ListEntry);}
  44. void SetTableEntry(CSMTP_HASH_TABLE * ThisTable) { m_MyTable = ThisTable;}
  45. void SetInList(void) { m_InList = TRUE;}
  46. void ClearInList(void) { m_InList = FALSE;}
  47. BOOL GetInList(void) { return m_InList;}
  48. LONG QueryRefCount(void){return m_RefCount;}
  49. virtual LONG IncRefCount(void){return InterlockedIncrement(&m_RefCount);}
  50. virtual void DecRefCount(void)
  51. {
  52. if(InterlockedDecrement(&m_RefCount) == 0)
  53. {
  54. //we should not be in the list if the ref
  55. //count is zero
  56. _ASSERT(m_InList == FALSE);
  57. delete this;
  58. }
  59. }
  60. void IncAccessCount(void)
  61. {
  62. InterlockedIncrement((LPLONG) &m_NumAccess);
  63. }
  64. BOOL IncAndCheckMaxAccess(DWORD MaxConnectionCount)
  65. {
  66. LONG OldAccessValue;
  67. BOOL fRet = TRUE;
  68. TraceFunctEnterEx((LPARAM)this, "CHASH_ENTRY::IsMaxAccessReached");
  69. OldAccessValue = InterlockedExchangeAdd((LPLONG) &m_NumAccess, 1);
  70. if((MaxConnectionCount > 0) && (OldAccessValue >= (LONG) MaxConnectionCount))
  71. {
  72. fRet = FALSE;
  73. }
  74. TraceFunctLeaveEx((LPARAM)this);
  75. return fRet;
  76. }
  77. void DecAccessCount(void)
  78. {
  79. InterlockedDecrement((LPLONG) &m_NumAccess);
  80. }
  81. DWORD GetAccessCount(void)
  82. {
  83. return m_NumAccess;
  84. }
  85. virtual char * GetData(void) = 0;
  86. virtual ~CHASH_ENTRY(){}
  87. };
  88. typedef struct HASH_BUCKET_ENTRY
  89. {
  90. DWORD m_NumEntries;
  91. LONG m_RefNum;
  92. LIST_ENTRY m_ListHead;
  93. CShareLockNH m_Lock;
  94. HASH_BUCKET_ENTRY (void)
  95. {
  96. InitializeListHead(&m_ListHead);
  97. m_NumEntries = 0;
  98. m_RefNum = 0;
  99. }
  100. }BUCKET_ENTRY, *PBUCKET_ENTRY;
  101. #define BITS_IN_int (sizeof(int) * CHAR_BIT)
  102. #define THREE_QUARTERS ((int) ((BITS_IN_int * 3) / 4))
  103. #define ONE_EIGHTH ((int) (BITS_IN_int / 8))
  104. #define HIGH_BITS (~((unsigned int)(~0) >> ONE_EIGHTH))
  105. #define TABLE_SIZE 241
  106. class CSMTP_HASH_TABLE
  107. {
  108. protected:
  109. DWORD m_Signature;
  110. LONG m_TotalEntries;
  111. DWORD m_CacheHits;
  112. DWORD m_CacheMisses;
  113. BOOL m_fWildCard;
  114. BOOL m_fDupesAllowed;
  115. HASH_BUCKET_ENTRY m_HashTable[TABLE_SIZE];
  116. public:
  117. CSMTP_HASH_TABLE::CSMTP_HASH_TABLE()
  118. {
  119. m_TotalEntries = 0;
  120. m_CacheHits = 0;
  121. m_CacheMisses = 0;
  122. m_fWildCard = FALSE;
  123. m_fDupesAllowed = FALSE;
  124. }
  125. virtual ~CSMTP_HASH_TABLE();
  126. virtual DWORD PrimaryCompareFunction(const char * SearchData, CHASH_ENTRY * pExistingEntry)
  127. {
  128. DWORD Result = 0;
  129. Result = lstrcmpi(SearchData, pExistingEntry->GetData());
  130. return Result;
  131. }
  132. virtual DWORD SecondaryCompareFunction(const char * SearchData, CHASH_ENTRY * pExistingEntry)
  133. {
  134. return 0;
  135. }
  136. virtual void MultiszFunction(CHASH_ENTRY * pExistingEntry, MULTISZ* pMsz)
  137. {
  138. }
  139. void RemoveAllEntries(void);
  140. void RemoveThisEntry(CHASH_ENTRY * pHashEntry, DWORD BucketNum);
  141. virtual void PrintAllEntries(void);
  142. virtual BOOL RemoveFromTable(const char * SearchData);
  143. virtual BOOL RemoveFromTableNoDecRef(const char * SearchData);
  144. virtual BOOL InsertIntoTable (CHASH_ENTRY * pHashEntry);
  145. virtual BOOL InsertIntoTableEx (CHASH_ENTRY * pHashEntry, char * szDefaultDomain);
  146. CHASH_ENTRY * FindHashData(const char * SearchData, BOOL fUseShareLock = TRUE, MULTISZ* pmsz = NULL);
  147. CHASH_ENTRY * UnSafeFindHashData(const char * SearchData);
  148. CHASH_ENTRY * WildCardFindHashData(const char * DomainName);
  149. void SetDupesAllowed(void){m_fDupesAllowed = TRUE;}
  150. void SetWildCard(void){m_fWildCard = TRUE;}
  151. void ClearWildCard(void) {m_fWildCard = FALSE;}
  152. BOOL IsWildCard(void) {return m_fWildCard;}
  153. BOOL IsDupesAllowed(void) {return m_fDupesAllowed;}
  154. BOOL IsTableEmpty(void) const {return (m_TotalEntries == 0);}
  155. //An adaptation of Peter Weinberger's (PJW) generic
  156. //hashing algorithm based on Allen Holub's version.
  157. //Code from Practical Algorithms for Programmers
  158. //by Andrew Binstock
  159. unsigned int HashFunction (const char * String)
  160. {
  161. unsigned int HashValue = 0;
  162. unsigned int i = 0;
  163. _ASSERT(String != NULL);
  164. for (HashValue = 0; String && *String; ++String)
  165. {
  166. HashValue = (HashValue << ONE_EIGHTH) + * String;
  167. if((i = HashValue & HIGH_BITS) != 0)
  168. {
  169. HashValue = (HashValue ^ (i >> THREE_QUARTERS)) & ~ HIGH_BITS;
  170. }
  171. }
  172. HashValue %= TABLE_SIZE;
  173. return HashValue;
  174. }
  175. LIST_ENTRY & GetBucketHead(DWORD BucketNum)
  176. {
  177. return m_HashTable[BucketNum].m_ListHead;
  178. }
  179. //this must be called with a lock if you
  180. //want it to be accurate!!!!!!!
  181. DWORD GetBucketRefNum(DWORD BucketNum)
  182. {
  183. DWORD RefNum;
  184. RefNum = m_HashTable[BucketNum].m_RefNum;
  185. return RefNum;
  186. }
  187. void ShareLockBucket(DWORD BucketNumber)
  188. {
  189. m_HashTable[BucketNumber].m_Lock.ShareLock();
  190. }
  191. void ShareUnLockBucket(DWORD BucketNumber)
  192. {
  193. m_HashTable[BucketNumber].m_Lock.ShareUnlock();
  194. }
  195. };
  196. class CTurnData : public CHASH_ENTRY
  197. {
  198. private:
  199. char m_UserName[MAX_INTERNET_NAME + 1];
  200. char m_DomainName[AB_MAX_DOMAIN + 1];
  201. public:
  202. virtual char * GetData(void)
  203. {
  204. return m_UserName;
  205. }
  206. CTurnData()
  207. :CHASH_ENTRY (TURN_DATA_SIGNATURE_VALID)
  208. {
  209. m_UserName[0] = '\0';
  210. m_DomainName[0] = '\0';
  211. }
  212. CTurnData(const char * szUserName, char * szDomainName)
  213. :CHASH_ENTRY (TURN_DATA_SIGNATURE_VALID)
  214. {
  215. lstrcpyn(m_UserName, szUserName, MAX_INTERNET_NAME);
  216. CharLowerBuff(m_UserName, lstrlen(m_UserName));
  217. lstrcpyn(m_DomainName, szDomainName, AB_MAX_DOMAIN);
  218. CharLowerBuff(m_DomainName, lstrlen(m_DomainName));
  219. }
  220. virtual ~CTurnData()
  221. {
  222. m_Signature = TURN_DATA_SIGNATURE_FREE;
  223. }
  224. char * GetRouteDomainName(void)
  225. {
  226. return m_DomainName;
  227. }
  228. };
  229. class CTURN_ACCESS_TABLE : public CSMTP_HASH_TABLE
  230. {
  231. public:
  232. CTURN_ACCESS_TABLE()
  233. {
  234. }
  235. virtual DWORD SecondaryCompareFunction(char * SearchData, CHASH_ENTRY * pExistingEntry)
  236. {
  237. DWORD Result = 0;
  238. CTurnData * pTurnData = (CTurnData *)pExistingEntry;
  239. if(pExistingEntry == NULL)
  240. {
  241. return 1;
  242. }
  243. if(SearchData == NULL)
  244. {
  245. return 1;
  246. }
  247. Result = lstrcmpi(SearchData, pTurnData->GetRouteDomainName());
  248. return Result;
  249. }
  250. virtual void MultiszFunction(CHASH_ENTRY * pExistingEntry, MULTISZ* pMsz)
  251. {
  252. CTurnData * pTurnData = (CTurnData *)pExistingEntry;
  253. pMsz->Append(pTurnData->GetRouteDomainName());
  254. }
  255. ~CTURN_ACCESS_TABLE(){}
  256. };
  257. #endif