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.

276 lines
7.6 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include <windef.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <stddef.h>
  9. #include "dfsgeneric.hxx"
  10. #include "dfsinit.hxx"
  11. #include "dsgetdc.h"
  12. #include "lm.h"
  13. #include <dsrole.h>
  14. #include <DfsReferralData.h>
  15. #include <DfsReferral.hxx>
  16. #include <dfsheader.h>
  17. #include <Dfsumr.h>
  18. #include <winsock2.h>
  19. #include <DfsSiteNameSupport.hxx>
  20. #include <DfsSite.hxx>
  21. #include "DfsSiteNameSupport.tmh"
  22. DFSSTATUS
  23. DfsSiteNameSupport::CreateSiteNameData(
  24. IN DfsSite *pNewSite,
  25. OUT PDFS_SITE_NAME_DATA *ppSiteNameData )
  26. {
  27. PDFS_SITE_NAME_DATA SiteStructure = NULL;
  28. DFSSTATUS Status = ERROR_SUCCESS;
  29. *ppSiteNameData = NULL;
  30. do {
  31. SiteStructure = (PDFS_SITE_NAME_DATA) DfsAllocateHashData(sizeof( DFS_SITE_NAME_DATA ));
  32. if (SiteStructure == NULL)
  33. {
  34. Status = ERROR_NOT_ENOUGH_MEMORY;
  35. break;
  36. }
  37. //
  38. // Attach a referenced DfsSite.
  39. //
  40. pNewSite->AcquireReference();
  41. SiteStructure->pDfsSite = pNewSite;
  42. SiteStructure->Header.RefCount = 1;
  43. //
  44. // Index key is the same as the site name embedded inside DfsSite.
  45. //
  46. Status = DfsRtlInitUnicodeStringEx( &SiteStructure->SiteName, pNewSite->SiteNameString() );
  47. if (Status != ERROR_SUCCESS)
  48. {
  49. break;
  50. }
  51. SiteStructure->Header.pvKey = (PVOID)&SiteStructure->SiteName;
  52. SiteStructure->Header.pData = (PVOID)SiteStructure;
  53. SiteStructure->FirstAccessTime = GetTickCount();
  54. *ppSiteNameData = SiteStructure;
  55. } while (FALSE);
  56. //
  57. // We haven't added this to the table yet.
  58. // So, just free the whole thing in case of error.
  59. // Release the DfsSite as well if it's initialized.
  60. //
  61. if (Status != ERROR_SUCCESS && SiteStructure != NULL)
  62. {
  63. DfsDeallocateSiteNameData( SiteStructure );
  64. *ppSiteNameData = NULL;
  65. }
  66. return Status;
  67. }
  68. PSHASH_HEADER
  69. DfsSiteNameSupport::LookupIpInHash(PUNICODE_STRING pSiteName)
  70. {
  71. DFSSTATUS Status = ERROR_SUCCESS;
  72. PSHASH_HEADER pHeader = NULL;
  73. pHeader = SHashLookupKeyEx(_pSiteNameTable,
  74. (void *)pSiteName);
  75. return pHeader;
  76. }
  77. VOID
  78. DfsSiteNameSupport::ReleaseSiteNameData(PDFS_SITE_NAME_DATA pData)
  79. {
  80. DFS_TRACE_LOW( REFERRAL, "Removing Site %ws from SiteNameCache", pData->SiteName.Buffer);
  81. SHashReleaseReference(_pSiteNameTable,
  82. (PSHASH_HEADER) pData );
  83. }
  84. DFSSTATUS
  85. DfsSiteNameSupport::StoreSiteInCache(
  86. DfsSite *pSite)
  87. {
  88. PDFS_SITE_NAME_DATA SiteStructure = NULL;
  89. NTSTATUS NtStatus = STATUS_SUCCESS;
  90. DFSSTATUS Status = ERROR_SUCCESS;
  91. Status = CreateSiteNameData( pSite, &SiteStructure );
  92. if (Status == ERROR_SUCCESS)
  93. {
  94. NtStatus = SHashInsertKey(_pSiteNameTable,
  95. SiteStructure,
  96. (void *)pSite->SiteName(),
  97. SHASH_REPLACE_IFFOUND);
  98. if (NtStatus != STATUS_SUCCESS)
  99. {
  100. DfsDeallocateSiteNameData( SiteStructure );
  101. Status = RtlNtStatusToDosError( NtStatus );
  102. }
  103. else
  104. {
  105. // Just for statistical purposes.
  106. InterlockedIncrement( &DfsServerGlobalData.NumDfsSitesInCache );
  107. DFS_TRACE_LOW( REFERRAL, "Added Site %ws to SiteNameCache", pSite->SiteNameString());
  108. }
  109. }
  110. return Status;
  111. }
  112. DFSSTATUS
  113. DfsSiteNameSupport::Initialize( ULONG NumBuckets )
  114. {
  115. DFSSTATUS Status = ERROR_SUCCESS;
  116. NTSTATUS NtStatus = STATUS_SUCCESS;
  117. SHASH_FUNCTABLE FunctionTable;
  118. ZeroMemory(&FunctionTable, sizeof(FunctionTable));
  119. FunctionTable.NumBuckets = NumBuckets;
  120. FunctionTable.CompareFunc = DfsCompareSiteNames;
  121. FunctionTable.AllocFunc = DfsAllocateHashData;
  122. FunctionTable.FreeFunc = DfsDeallocateHashData;
  123. FunctionTable.AllocHashEntryFunc = DfsAllocateHashData;
  124. FunctionTable.FreeHashEntryFunc = DfsSiteNameSupport::DfsDeallocateSiteNameData;
  125. // We use the default hash function in shash for site names.
  126. NtStatus = ShashInitHashTable(&_pSiteNameTable, &FunctionTable);
  127. Status = RtlNtStatusToDosError(NtStatus);
  128. return Status;
  129. }
  130. //
  131. // Static function meant to differentiate new operator errors
  132. // and Initialization errors.
  133. //
  134. DfsSiteNameSupport *
  135. DfsSiteNameSupport::CreateSiteNameSupport(
  136. DFSSTATUS * pStatus,
  137. ULONG HashBuckets)
  138. {
  139. DfsSiteNameSupport * pSiteTable = NULL;
  140. DFSSTATUS Status = ERROR_SUCCESS;
  141. pSiteTable = new DfsSiteNameSupport();
  142. if(pSiteTable == NULL)
  143. {
  144. Status = ERROR_NOT_ENOUGH_MEMORY;
  145. }
  146. else
  147. {
  148. Status = pSiteTable->Initialize( HashBuckets );
  149. if(Status != ERROR_SUCCESS)
  150. {
  151. delete pSiteTable;
  152. pSiteTable = NULL;
  153. }
  154. }
  155. *pStatus = Status;
  156. return pSiteTable;
  157. }
  158. // Just delete the cache data entry.
  159. VOID
  160. DfsSiteNameSupport::DfsDeallocateSiteNameData(PVOID pPointer )
  161. {
  162. PDFS_SITE_NAME_DATA pSiteStructure = (PDFS_SITE_NAME_DATA)pPointer;
  163. if (pSiteStructure)
  164. {
  165. if (pSiteStructure->pDfsSite != NULL)
  166. {
  167. pSiteStructure->pDfsSite->ReleaseReference();
  168. }
  169. delete [] (PBYTE)pSiteStructure;
  170. }
  171. }
  172. DFSSTATUS
  173. DfsSiteNameSupport::RemoveSiteFromCache(
  174. PUNICODE_STRING pSiteName)
  175. {
  176. NTSTATUS NtStatus;
  177. DFS_TRACE_LOW( REFERRAL, "Removing Site %ws from SiteNameCache", pSiteName->Buffer);
  178. NtStatus = SHashRemoveKey(_pSiteNameTable,
  179. pSiteName,
  180. NULL );
  181. // Stats
  182. if (NtStatus == STATUS_SUCCESS) {
  183. InterlockedDecrement( &DfsServerGlobalData.NumDfsSitesInCache );
  184. }
  185. return RtlNtStatusToDosError( NtStatus );
  186. }
  187. VOID
  188. DfsSiteNameSupport::InvalidateCache(VOID)
  189. {
  190. SHASH_ITERATOR Iter;
  191. PDFS_SITE_NAME_DATA pExistingData = NULL;
  192. ULONG nEntries = 0;
  193. pExistingData = (PDFS_SITE_NAME_DATA) SHashStartEnumerate(&Iter, _pSiteNameTable);
  194. while (pExistingData != NULL)
  195. {
  196. //
  197. // Remove this item. There's nothing we can do if we hit errors
  198. // except to keep going.
  199. //
  200. (VOID)RemoveSiteFromCache( &pExistingData->SiteName );
  201. nEntries++;
  202. pExistingData = (PDFS_SITE_NAME_DATA) SHashNextEnumerate(&Iter, _pSiteNameTable);
  203. }
  204. SHashFinishEnumerate(&Iter, _pSiteNameTable);
  205. DFS_TRACE_LOW( REFERRAL, "SiteName Table %p: invalidated all %d entries\n", this, nEntries);
  206. }
  207. VOID
  208. DfsSiteNameSupport::InvalidateAgedSites( VOID )
  209. {
  210. // go over all the DfsSites in the site name support table and
  211. // throw out their caches if the site has aged (SiteCostSupport->Release()).
  212. SHASH_ITERATOR Iter;
  213. DfsSite *pSite = NULL;
  214. DFSSTATUS Status = ERROR_SUCCESS;
  215. ULONG NumEntriesThrownOut = 0;
  216. pSite = StartSiteEnumerate( &Iter );
  217. while (pSite != NULL)
  218. {
  219. if (pSite->IsSiteCostCacheExpired())
  220. {
  221. (VOID) pSite->DeleteSiteCostCache();
  222. NumEntriesThrownOut++;
  223. }
  224. pSite = NextSiteEnumerate( &Iter );
  225. }
  226. FinishSiteEnumerate( &Iter );
  227. DFS_TRACE_LOW( REFERRAL, "SiteNameSupport: Invalidated %d SiteCostTables out of %d\n",
  228. NumEntriesThrownOut, DfsServerGlobalData.NumSiteCostTables);
  229. return;
  230. }