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__
 |