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
276 lines
7.6 KiB
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <windef.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stddef.h>
|
|
|
|
#include "dfsgeneric.hxx"
|
|
#include "dfsinit.hxx"
|
|
#include "dsgetdc.h"
|
|
#include "lm.h"
|
|
#include <dsrole.h>
|
|
#include <DfsReferralData.h>
|
|
#include <DfsReferral.hxx>
|
|
#include <dfsheader.h>
|
|
#include <Dfsumr.h>
|
|
#include <winsock2.h>
|
|
#include <DfsSiteNameSupport.hxx>
|
|
#include <DfsSite.hxx>
|
|
|
|
#include "DfsSiteNameSupport.tmh"
|
|
|
|
|
|
DFSSTATUS
|
|
DfsSiteNameSupport::CreateSiteNameData(
|
|
IN DfsSite *pNewSite,
|
|
OUT PDFS_SITE_NAME_DATA *ppSiteNameData )
|
|
{
|
|
PDFS_SITE_NAME_DATA SiteStructure = NULL;
|
|
DFSSTATUS Status = ERROR_SUCCESS;
|
|
|
|
*ppSiteNameData = NULL;
|
|
|
|
do {
|
|
SiteStructure = (PDFS_SITE_NAME_DATA) DfsAllocateHashData(sizeof( DFS_SITE_NAME_DATA ));
|
|
if (SiteStructure == NULL)
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Attach a referenced DfsSite.
|
|
//
|
|
pNewSite->AcquireReference();
|
|
SiteStructure->pDfsSite = pNewSite;
|
|
SiteStructure->Header.RefCount = 1;
|
|
|
|
//
|
|
// Index key is the same as the site name embedded inside DfsSite.
|
|
//
|
|
Status = DfsRtlInitUnicodeStringEx( &SiteStructure->SiteName, pNewSite->SiteNameString() );
|
|
if (Status != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
|
|
SiteStructure->Header.pvKey = (PVOID)&SiteStructure->SiteName;
|
|
SiteStructure->Header.pData = (PVOID)SiteStructure;
|
|
|
|
SiteStructure->FirstAccessTime = GetTickCount();
|
|
*ppSiteNameData = SiteStructure;
|
|
} while (FALSE);
|
|
|
|
//
|
|
// We haven't added this to the table yet.
|
|
// So, just free the whole thing in case of error.
|
|
// Release the DfsSite as well if it's initialized.
|
|
//
|
|
if (Status != ERROR_SUCCESS && SiteStructure != NULL)
|
|
{
|
|
DfsDeallocateSiteNameData( SiteStructure );
|
|
*ppSiteNameData = NULL;
|
|
}
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
PSHASH_HEADER
|
|
DfsSiteNameSupport::LookupIpInHash(PUNICODE_STRING pSiteName)
|
|
{
|
|
DFSSTATUS Status = ERROR_SUCCESS;
|
|
PSHASH_HEADER pHeader = NULL;
|
|
|
|
pHeader = SHashLookupKeyEx(_pSiteNameTable,
|
|
(void *)pSiteName);
|
|
return pHeader;
|
|
}
|
|
|
|
VOID
|
|
DfsSiteNameSupport::ReleaseSiteNameData(PDFS_SITE_NAME_DATA pData)
|
|
{
|
|
DFS_TRACE_LOW( REFERRAL, "Removing Site %ws from SiteNameCache", pData->SiteName.Buffer);
|
|
SHashReleaseReference(_pSiteNameTable,
|
|
(PSHASH_HEADER) pData );
|
|
|
|
}
|
|
|
|
DFSSTATUS
|
|
DfsSiteNameSupport::StoreSiteInCache(
|
|
DfsSite *pSite)
|
|
{
|
|
PDFS_SITE_NAME_DATA SiteStructure = NULL;
|
|
NTSTATUS NtStatus = STATUS_SUCCESS;
|
|
DFSSTATUS Status = ERROR_SUCCESS;
|
|
|
|
Status = CreateSiteNameData( pSite, &SiteStructure );
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
NtStatus = SHashInsertKey(_pSiteNameTable,
|
|
SiteStructure,
|
|
(void *)pSite->SiteName(),
|
|
SHASH_REPLACE_IFFOUND);
|
|
if (NtStatus != STATUS_SUCCESS)
|
|
{
|
|
DfsDeallocateSiteNameData( SiteStructure );
|
|
Status = RtlNtStatusToDosError( NtStatus );
|
|
}
|
|
else
|
|
{
|
|
// Just for statistical purposes.
|
|
InterlockedIncrement( &DfsServerGlobalData.NumDfsSitesInCache );
|
|
DFS_TRACE_LOW( REFERRAL, "Added Site %ws to SiteNameCache", pSite->SiteNameString());
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
DFSSTATUS
|
|
DfsSiteNameSupport::Initialize( ULONG NumBuckets )
|
|
{
|
|
DFSSTATUS Status = ERROR_SUCCESS;
|
|
NTSTATUS NtStatus = STATUS_SUCCESS;
|
|
SHASH_FUNCTABLE FunctionTable;
|
|
|
|
ZeroMemory(&FunctionTable, sizeof(FunctionTable));
|
|
|
|
FunctionTable.NumBuckets = NumBuckets;
|
|
FunctionTable.CompareFunc = DfsCompareSiteNames;
|
|
FunctionTable.AllocFunc = DfsAllocateHashData;
|
|
FunctionTable.FreeFunc = DfsDeallocateHashData;
|
|
FunctionTable.AllocHashEntryFunc = DfsAllocateHashData;
|
|
FunctionTable.FreeHashEntryFunc = DfsSiteNameSupport::DfsDeallocateSiteNameData;
|
|
// We use the default hash function in shash for site names.
|
|
|
|
NtStatus = ShashInitHashTable(&_pSiteNameTable, &FunctionTable);
|
|
Status = RtlNtStatusToDosError(NtStatus);
|
|
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Static function meant to differentiate new operator errors
|
|
// and Initialization errors.
|
|
//
|
|
DfsSiteNameSupport *
|
|
DfsSiteNameSupport::CreateSiteNameSupport(
|
|
DFSSTATUS * pStatus,
|
|
ULONG HashBuckets)
|
|
{
|
|
DfsSiteNameSupport * pSiteTable = NULL;
|
|
DFSSTATUS Status = ERROR_SUCCESS;
|
|
|
|
pSiteTable = new DfsSiteNameSupport();
|
|
if(pSiteTable == NULL)
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
Status = pSiteTable->Initialize( HashBuckets );
|
|
if(Status != ERROR_SUCCESS)
|
|
{
|
|
delete pSiteTable;
|
|
pSiteTable = NULL;
|
|
}
|
|
}
|
|
*pStatus = Status;
|
|
return pSiteTable;
|
|
}
|
|
|
|
// Just delete the cache data entry.
|
|
VOID
|
|
DfsSiteNameSupport::DfsDeallocateSiteNameData(PVOID pPointer )
|
|
{
|
|
PDFS_SITE_NAME_DATA pSiteStructure = (PDFS_SITE_NAME_DATA)pPointer;
|
|
|
|
if (pSiteStructure)
|
|
{
|
|
if (pSiteStructure->pDfsSite != NULL)
|
|
{
|
|
pSiteStructure->pDfsSite->ReleaseReference();
|
|
}
|
|
delete [] (PBYTE)pSiteStructure;
|
|
}
|
|
}
|
|
|
|
DFSSTATUS
|
|
DfsSiteNameSupport::RemoveSiteFromCache(
|
|
PUNICODE_STRING pSiteName)
|
|
{
|
|
NTSTATUS NtStatus;
|
|
DFS_TRACE_LOW( REFERRAL, "Removing Site %ws from SiteNameCache", pSiteName->Buffer);
|
|
|
|
NtStatus = SHashRemoveKey(_pSiteNameTable,
|
|
pSiteName,
|
|
NULL );
|
|
// Stats
|
|
if (NtStatus == STATUS_SUCCESS) {
|
|
|
|
InterlockedDecrement( &DfsServerGlobalData.NumDfsSitesInCache );
|
|
}
|
|
|
|
return RtlNtStatusToDosError( NtStatus );
|
|
}
|
|
|
|
VOID
|
|
DfsSiteNameSupport::InvalidateCache(VOID)
|
|
{
|
|
SHASH_ITERATOR Iter;
|
|
PDFS_SITE_NAME_DATA pExistingData = NULL;
|
|
ULONG nEntries = 0;
|
|
|
|
pExistingData = (PDFS_SITE_NAME_DATA) SHashStartEnumerate(&Iter, _pSiteNameTable);
|
|
while (pExistingData != NULL)
|
|
{
|
|
//
|
|
// Remove this item. There's nothing we can do if we hit errors
|
|
// except to keep going.
|
|
//
|
|
|
|
(VOID)RemoveSiteFromCache( &pExistingData->SiteName );
|
|
nEntries++;
|
|
pExistingData = (PDFS_SITE_NAME_DATA) SHashNextEnumerate(&Iter, _pSiteNameTable);
|
|
}
|
|
SHashFinishEnumerate(&Iter, _pSiteNameTable);
|
|
|
|
DFS_TRACE_LOW( REFERRAL, "SiteName Table %p: invalidated all %d entries\n", this, nEntries);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
DfsSiteNameSupport::InvalidateAgedSites( VOID )
|
|
{
|
|
// go over all the DfsSites in the site name support table and
|
|
// throw out their caches if the site has aged (SiteCostSupport->Release()).
|
|
|
|
SHASH_ITERATOR Iter;
|
|
DfsSite *pSite = NULL;
|
|
DFSSTATUS Status = ERROR_SUCCESS;
|
|
ULONG NumEntriesThrownOut = 0;
|
|
|
|
pSite = StartSiteEnumerate( &Iter );
|
|
while (pSite != NULL)
|
|
{
|
|
if (pSite->IsSiteCostCacheExpired())
|
|
{
|
|
(VOID) pSite->DeleteSiteCostCache();
|
|
NumEntriesThrownOut++;
|
|
}
|
|
pSite = NextSiteEnumerate( &Iter );
|
|
}
|
|
|
|
FinishSiteEnumerate( &Iter );
|
|
|
|
DFS_TRACE_LOW( REFERRAL, "SiteNameSupport: Invalidated %d SiteCostTables out of %d\n",
|
|
NumEntriesThrownOut, DfsServerGlobalData.NumSiteCostTables);
|
|
return;
|
|
}
|
|
|