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.
 
 
 
 
 
 

265 lines
8.0 KiB

//+----------------------------------------------------------------------------
//
// 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;
}