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

#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;
}