295 lines
9.5 KiB
C++
295 lines
9.5 KiB
C++
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 2001, Microsoft Corporation
|
|
//
|
|
// File: DfsDomainInformation.hxx
|
|
//
|
|
// Contents: the Dfs domain info class
|
|
//
|
|
// Classes: DfsDomainInformation
|
|
//
|
|
// History: apr. 8 2001, Author: udayh
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
#ifndef __DFS_DOMAIN_INFORMATION__
|
|
#define __DFS_DOMAIN_INFORMATION__
|
|
|
|
#include "DfsGeneric.hxx"
|
|
#include "Align.h"
|
|
#include "dsgetdc.h"
|
|
#include "DfsTrustedDomain.hxx"
|
|
#include "DfsReferralData.h"
|
|
#include "ntlsa.h"
|
|
|
|
class DfsDomainInformation: public DfsGeneric
|
|
{
|
|
|
|
private:
|
|
DfsTrustedDomain *_pTrustedDomains;
|
|
ULONG _DomainCount;
|
|
PCRITICAL_SECTION _pLock;
|
|
ULONG _DomainReferralLength;
|
|
|
|
public:
|
|
|
|
DfsDomainInformation( DFSSTATUS *pStatus) :
|
|
DfsGeneric( DFS_OBJECT_TYPE_DOMAIN_INFO)
|
|
{
|
|
|
|
ULONG DsDomainCount = 0;
|
|
PDS_DOMAIN_TRUSTS pDsDomainTrusts;
|
|
DFSSTATUS Status = ERROR_SUCCESS;
|
|
LPWSTR ServerName = NULL;
|
|
ULONG Index;
|
|
|
|
_pTrustedDomains = NULL;
|
|
_DomainCount = 0;
|
|
_DomainReferralLength = 0;
|
|
|
|
_pLock = new CRITICAL_SECTION;
|
|
if ( _pLock == NULL )
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
InitializeCriticalSection( _pLock );
|
|
}
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
#if defined (TESTING)
|
|
ServerName = L"ntdev-dc-01";
|
|
#endif
|
|
Status = DsEnumerateDomainTrusts( ServerName,
|
|
DS_DOMAIN_VALID_FLAGS,
|
|
&pDsDomainTrusts,
|
|
&DsDomainCount );
|
|
|
|
ULONG ValidDomainCount = 0;
|
|
for (Index = 0; Index < DsDomainCount; Index++)
|
|
{
|
|
if (pDsDomainTrusts[Index].TrustType == TRUST_TYPE_DOWNLEVEL)
|
|
continue;
|
|
if (IsEmptyString(pDsDomainTrusts[Index].NetbiosDomainName) == FALSE)
|
|
{
|
|
ValidDomainCount++;
|
|
}
|
|
if (IsEmptyString(pDsDomainTrusts[Index].DnsDomainName) == FALSE)
|
|
{
|
|
ValidDomainCount++;
|
|
}
|
|
}
|
|
|
|
if ( (Status == ERROR_SUCCESS) &&
|
|
(ValidDomainCount > 0) )
|
|
{
|
|
_DomainCount = ValidDomainCount;
|
|
_pTrustedDomains = new DfsTrustedDomain[ _DomainCount ];
|
|
|
|
if (_pTrustedDomains == NULL)
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
ValidDomainCount = 0;
|
|
DfsTrustedDomain *pUseDomain;
|
|
for (Index = 0; Index < DsDomainCount; Index++)
|
|
{
|
|
if (pDsDomainTrusts[Index].TrustType == TRUST_TYPE_DOWNLEVEL)
|
|
continue;
|
|
if (IsEmptyString(pDsDomainTrusts[Index].NetbiosDomainName) == FALSE)
|
|
{
|
|
pUseDomain = &_pTrustedDomains[ValidDomainCount];
|
|
pUseDomain->Initialize(_pLock, this);
|
|
|
|
Status = pUseDomain->SetDomainName( pDsDomainTrusts[Index].NetbiosDomainName,
|
|
TRUE );
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
_DomainReferralLength += (pUseDomain->GetDomainName())->Length;
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
ValidDomainCount++;
|
|
}
|
|
if (IsEmptyString(pDsDomainTrusts[Index].DnsDomainName) == FALSE)
|
|
{
|
|
pUseDomain = &_pTrustedDomains[ValidDomainCount];
|
|
pUseDomain->Initialize(_pLock, this);
|
|
Status = pUseDomain->SetDomainName( pDsDomainTrusts[Index].DnsDomainName,
|
|
TRUE );
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
_DomainReferralLength += (pUseDomain->GetDomainName())->Length;
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
ValidDomainCount++;
|
|
|
|
}
|
|
}
|
|
}
|
|
NetApiBufferFree(pDsDomainTrusts);
|
|
}
|
|
}
|
|
*pStatus = Status;
|
|
}
|
|
|
|
virtual
|
|
~DfsDomainInformation()
|
|
{
|
|
if (_pTrustedDomains != NULL)
|
|
{
|
|
delete [] _pTrustedDomains;
|
|
}
|
|
if (_pLock != NULL)
|
|
{
|
|
DeleteCriticalSection(_pLock);
|
|
delete _pLock;
|
|
}
|
|
}
|
|
|
|
#if defined (TESTING)
|
|
ULONG
|
|
GetDomainCount()
|
|
{
|
|
return _DomainCount;
|
|
|
|
}
|
|
|
|
DfsTrustedDomain *
|
|
GetTrustedDomainForIndex(
|
|
ULONG Index )
|
|
{
|
|
return (&_pTrustedDomains[Index]);
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
DFSSTATUS
|
|
GetDomainDcReferralInfo(
|
|
PUNICODE_STRING pDomain,
|
|
DfsReferralData **ppReferralData,
|
|
PBOOLEAN pCacheHit )
|
|
{
|
|
DFSSTATUS Status = ERROR_NOT_FOUND;
|
|
ULONG Index;
|
|
|
|
for (Index = 0; Index < _DomainCount; Index++)
|
|
{
|
|
if ((&_pTrustedDomains[Index])->IsMatchingDomainName( pDomain) == TRUE)
|
|
{
|
|
Status = (&_pTrustedDomains[Index])->GetDcReferralData( ppReferralData,
|
|
pCacheHit );
|
|
break;
|
|
}
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
DFSSTATUS
|
|
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;
|
|
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;
|
|
}
|
|
};
|
|
|
|
#endif // __DFS_DOMAIN_INFORMATION__
|