|
|
//+----------------------------------------------------------------------------
//
// Copyright (C) 2001, Microsoft Corporation
//
// File: DfsDomainInformation.cxx
//
// Contents: the Dfs domain info class
//
// Classes: DfsDomainInformation
//
// History: apr. 8 2001, Author: udayh
//
//-----------------------------------------------------------------------------
#include "DfsGeneric.hxx"
#include "Align.h"
#include "dsgetdc.h"
#include "DfsTrustedDomain.hxx"
#include "DfsReferralData.h"
#include "dfsdomainInformation.hxx"
#include "dfsxforest.hxx"
#include "dfsdomainInformation.tmh"
DfsDomainInformation::DfsDomainInformation( DFSSTATUS *pStatus, DFSSTATUS *pXforestStatus) : DfsGeneric( DFS_OBJECT_TYPE_DOMAIN_INFO) {
ULONG DsDomainCount = 0; PDS_DOMAIN_TRUSTS pDsDomainTrusts = NULL; DFSSTATUS Status = ERROR_SUCCESS; DFSSTATUS XforestInitStatus = ERROR_SUCCESS; LPWSTR ServerName = NULL; ULONG Index = 0;
DfsXForest XForestInfo;
_pTrustedDomains = NULL; _DomainCount = 0; _fCritInit = FALSE; _DomainReferralLength = 0; _pLock = new CRITICAL_SECTION; if ( _pLock == NULL ) { Status = ERROR_NOT_ENOUGH_MEMORY; } else { _fCritInit = InitializeCriticalSectionAndSpinCount( _pLock, DFS_CRIT_SPIN_COUNT ); if(!_fCritInit) { Status = GetLastError(); DFS_TRACE_ERROR_HIGH(Status, REFERRAL_SERVER, "DfsDomainInformation::DfsDomainInformation InitializeCriticalSectionAndSpinCount Status %d\n", Status); } }
if (Status == ERROR_SUCCESS) { ULONG ValidDomainCount = 0; DfsTrustedDomain *pUseDomain = NULL;
//
// We ignore Xforest initialization errors temporarily
// but propagate them back to the DcLoop thread so
// it can retry.
//
Status = XForestInfo.Initialize( pXforestStatus );
if (Status == ERROR_SUCCESS) { ValidDomainCount = XForestInfo.GetCount(); }
if ( (Status == ERROR_SUCCESS) && (ValidDomainCount > 0) ) { _DomainCount = ValidDomainCount; _pTrustedDomains = new DfsTrustedDomain[ _DomainCount ];
if (_pTrustedDomains == NULL) { Status = ERROR_NOT_ENOUGH_MEMORY;
DFS_TRACE_ERROR_HIGH(Status, REFERRAL_SERVER, "DfsDomainInformation - _pTrustedDomains is NULL Status %d\n", Status); }
ValidDomainCount = 0;
if (Status == ERROR_SUCCESS) { PDFS_DOMAIN_NAME_INFO pDomainInfo; do {
pDomainInfo = XForestInfo.GetNextDomainInfo(); if (pDomainInfo != NULL) { pUseDomain = &_pTrustedDomains[ValidDomainCount]; pUseDomain->Initialize(_pLock );
if (pDomainInfo->UseBindDomain) { Status = pUseDomain->SetBindDomainName( &pDomainInfo->BindDomainName); }
if (Status == ERROR_SUCCESS) { Status = pUseDomain->SetDomainName( &pDomainInfo->DomainName, pDomainInfo->Netbios); }
if (Status == ERROR_SUCCESS) { _DomainReferralLength += (pUseDomain->GetDomainName())->Length; } else { break; } ValidDomainCount++; } } while ( pDomainInfo != NULL );
}
if (Status == ERROR_SUCCESS) { _SkippedDomainCount = XForestInfo.GetSkippedDomainCount(); DFS_TRACE_LOW(REFERRAL_SERVER, "DfsDomainInformation, with %d domains, (%d domains skipped)\n", ValidDomainCount, _SkippedDomainCount); } } }
*pStatus = Status; //
// XForestInfo goes out of scope and is destroyed
//
}
DFSSTATUS DfsDomainInformation::GenerateDomainReferral( REFERRAL_HEADER ** ppReferralHeader) { DFSSTATUS Status = ERROR_SUCCESS; ULONG TotalSize = 0; ULONG NextEntry = 0; ULONG LastEntry = 0; ULONG CurrentEntryLength = 0; ULONG LastEntryLength = 0; ULONG BaseLength = 0; ULONG HeaderBaseLength = 0; ULONG CurrentNameLength =0; PUCHAR Buffer = NULL; PUCHAR pDomainBuffer = NULL; PWCHAR ReturnedName = NULL; PREFERRAL_HEADER pHeader = NULL;
HeaderBaseLength = FIELD_OFFSET( REFERRAL_HEADER, LinkName[0] ); //calculate size of base replica structure
BaseLength = FIELD_OFFSET( REPLICA_INFORMATION, ReplicaName[0] );
TotalSize = ROUND_UP_COUNT(HeaderBaseLength, ALIGN_LONG);
for (ULONG Index = 0; Index < _DomainCount; Index++) { PUNICODE_STRING pDomainName = (&_pTrustedDomains[Index])->GetDomainName(); TotalSize += ROUND_UP_COUNT(pDomainName->Length + BaseLength, ALIGN_LONG); }
//allocate the buffer
Buffer = new BYTE[TotalSize]; if(Buffer == NULL) { Status = ERROR_NOT_ENOUGH_MEMORY;
DFS_TRACE_ERROR_HIGH(Status, REFERRAL_SERVER, "DfsDomainInformation:GenerateDomainReferral allocation failure Status %d\n", Status); return Status; }
RtlZeroMemory( Buffer, TotalSize ); //setup the header
pHeader = (PREFERRAL_HEADER) Buffer; pHeader->VersionNumber = CURRENT_DFS_REPLICA_HEADER_VERSION; pHeader->ReplicaCount = 0; pHeader->OffsetToReplicas = ROUND_UP_COUNT((HeaderBaseLength), ALIGN_LONG); pHeader->LinkNameLength = 0; pHeader->TotalSize = TotalSize; pHeader->ReferralFlags = DFS_REFERRAL_DATA_DOMAIN_REFERRAL;
pDomainBuffer = Buffer + pHeader->OffsetToReplicas;
for (ULONG Index = 0; Index < _DomainCount; Index++) { PUNICODE_STRING pDomainName = (&_pTrustedDomains[Index])->GetDomainName(); if (pDomainName->Length == 0) { continue; } pHeader->ReplicaCount++; NextEntry += (ULONG)( CurrentEntryLength );
ReturnedName = (PWCHAR) &pDomainBuffer[NextEntry + BaseLength]; CurrentNameLength = 0;
#if 0
//
// Start with the leading path seperator
//
ReturnedName[ CurrentNameLength / sizeof(WCHAR) ] = UNICODE_PATH_SEP; CurrentNameLength += sizeof(UNICODE_PATH_SEP); #endif
//
// next copy the server name.
//
RtlMoveMemory( &ReturnedName[ CurrentNameLength / sizeof(WCHAR) ], pDomainName->Buffer, pDomainName->Length); CurrentNameLength += pDomainName->Length; ((PREPLICA_INFORMATION)&pDomainBuffer[NextEntry])->ReplicaFlags = 0; ((PREPLICA_INFORMATION)&pDomainBuffer[NextEntry])->ReplicaCost = 0; ((PREPLICA_INFORMATION)&pDomainBuffer[NextEntry])->ReplicaNameLength = CurrentNameLength;
CurrentEntryLength = ROUND_UP_COUNT((CurrentNameLength + BaseLength), ALIGN_LONG);
//setup the offset to the next entry
*((PULONG)(&pDomainBuffer[NextEntry])) = pHeader->OffsetToReplicas + NextEntry + CurrentEntryLength; }
*((PULONG)(&pDomainBuffer[NextEntry])) = 0; *ppReferralHeader = pHeader;
return Status; }
VOID DfsDomainInformation::PurgeDCReferrals() { ULONG Index;
for (Index = 0; Index < _DomainCount; Index++) { DFSSTATUS DiscardStatus;
DiscardStatus = _pTrustedDomains[Index].RemoveDcReferralData( NULL, NULL); } return NOTHING;
}
|