|
|
//+----------------------------------------------------------------------------
//
// Copyright (C) 2000, Microsoft Corporation
//
// File: DfsFolder.hxx
//
// Contents: the base DFS Folder class, this contains the common
// Meta information functionality.
//
// Classes: DfsFolder.
//
// History: Dec. 8 2000, Author: udayh
//
//-----------------------------------------------------------------------------
#ifndef __DFS_FOLDER__
#define __DFS_FOLDER__
#include "DfsGeneric.hxx"
#include "DfsInit.hxx"
#include "dfsreferraldata.h"
//+----------------------------------------------------------------------------
//
// Class: DfsFolder
//
// Synopsis: This class implements a basic DfsFolder class.
//
//-----------------------------------------------------------------------------
//
// Declare DfsFolderReferralData as a class, since we will be including
// a pointer to that class within the DfsFolder class.
//
class DfsFolderReferralData;
//
// The DfsFolder can be in any of the following loaded state.
//
enum DfsFolderLoadState { DfsFolderStateUnknown = 0, DfsFolderLoaded, DfsFolderNotLoaded, DfsFolderLoadInProgress, DfsFolderLoadFailed, };
//
// Definition of some of the bits in the flags field.
//
#define DFS_FOLDER_IN_LOGICAL_TABLE 0x0001
#define DFS_FOLDER_IN_METADATA_TABLE 0x0002
#define DFS_FOLDER_DELETE_IN_PROGRESS 0x0004
#define DFS_FOLDER_INSITE_REFERRALS 0x0008
#define DFS_FOLDER_OUT_OF_DOMAIN 0x0010
#define DFS_FOLDER_COST_BASED_SITE_SELECTION 0x0020 // site-costing enabled on this folder
#define DFS_FOLDER_OFFLINE 0x0040
#define DFS_FOLDER_ROOT 0x1000
class DfsFolder: public DfsGeneric { private: DfsFolder *_pParent; // the root DfsFolder.
UINT64 _LastUSN; //??
ULONG _Timeout; //timeout to send back in referral
ULONG _RetryFailedLoadTimeout; // Fired if the folder data failed to load
public: CRITICAL_SECTION * _pLock; // lock for this folder.
ULONG _Flags; // flags, bits specified above.
DfsFolderReferralData *_pReferralData; // The loaded referral data
UNICODE_STRING _MetadataName; // the metadat name of this folder
UNICODE_STRING _LogicalName; // the dfs logical name of folder
DFSSTATUS _LoadStatus; // Status of last load.
DfsFolderLoadState _LoadState; // current load state of folder
public:
//
// Function DfsFolder: the constructor for the DfsFolder class.
// This initializes all the private and public variables
// of the DfsFolder class.
//
DfsFolder( DfsFolder *pParent, CRITICAL_SECTION *pLock, DfsObjectTypeEnumeration ObType = DFS_OBJECT_TYPE_FOLDER ) : DfsGeneric(ObType) { //
// Initialize the local variables of this class.
// The parent is going to set the logical and metadata name
// for this instance.
//
RtlInitUnicodeString(&_LogicalName, NULL); RtlInitUnicodeString(&_MetadataName, NULL);
_LastUSN = 0;
_LoadStatus = 0; _pReferralData = NULL; _Flags = 0; _Timeout = DFS_DEFAULT_REFERRAL_TIMEOUT; _RetryFailedLoadTimeout = 0; _pLock = pLock; _LoadState = DfsFolderNotLoaded;
// If the parent is not ourselves, acquire a reference on
// the parent so that we can save a pointer to the parent.
// The only exception is the case where there is no parent,
// and we are pointing to ourselves: in that case avoid
// acquiring a reference to ourself since this would cause
// this obect from never being destroyed.
//
if ( pParent != NULL ) { pParent->AcquireReference(); _pParent = pParent; } else { _pParent = this; }
}
//
// The destructor is virtual so that classes derived from this
// class will end up calling the right set of destructors
//
virtual ~DfsFolder() { //
// If we had saved a parent, release our reference at this point.
//
if ( (_pParent != NULL) && (_pParent != this) ) { _pParent->ReleaseReference(); } if (_LogicalName.Buffer != NULL) { DfsFreeUnicodeString(&_LogicalName); } if (_MetadataName.Buffer != NULL) { DfsFreeUnicodeString(&_MetadataName); }
_pParent = NULL; }
//
// Function ReleaseLock: release the folder lock.
//
VOID ReleaseLock() { DfsReleaseLock(_pLock); }
//
// Function AcquireWriteLock: Acquire the folder lock exclusively.
// Currently all locks are exclusive, but this could change.
//
DFSSTATUS AcquireWriteLock() { return DfsAcquireWriteLock( _pLock ); }
//
// Function AcquireReadLock: Acquire the folder lock shared
// Currently all locks are exclusive, but this could change.
//
DFSSTATUS AcquireReadLock() { return DfsAcquireReadLock( _pLock ); }
//
// Function InitializeMetadataName: Set the metadata name of this
// instance to the passed in unicode string name.
//
DFSSTATUS InitializeMetadataName( PUNICODE_STRING pName ) { return DfsCreateUnicodeString( &_MetadataName, pName ); } //
// Function InitializeMetadataName: Set the metadata name of this
// instance to the passed in string name.
//
DFSSTATUS InitializeMetadataName( LPWSTR pNameString ) { return DfsCreateUnicodeStringFromString( &_MetadataName, pNameString ); }
//
// Function InitializeLogicalName: Set the logical name of this
// instance to the passed in unciode string name.
//
DFSSTATUS InitializeLogicalName( PUNICODE_STRING pName ) { return DfsCreateUnicodeString( &_LogicalName, pName ); }
//
// Function LoadReferralData: This is defined virtual and the parent
// DfsRootFolder which is derived from the DfsFolder class is expected
// to override this function.
// Call the parent's LoadReferralData routine.
//
virtual DFSSTATUS LoadReferralData( IN DfsFolderReferralData *pReferralData ) { return _pParent->LoadReferralData( pReferralData ); }
//
// Function UnloadReferralData: This is defined virtual and the parent
// DfsRootFolder which is derived from the DfsFolder class is expected
// to override this function.
// Call the parent's UnloadReferralData routine.
//
virtual DFSSTATUS UnloadReferralData( IN DfsFolderReferralData *pReferralData )
{
return _pParent->UnloadReferralData( pReferralData );
}
//
// Function UpdateRequired: Checks if the passed in USN is greater
// than the one stored by us. If so, return true indicating that
// we need to be updated.
//
BOOLEAN UpdateRequired( UINT64 ModifiedUSN ) { if ( ModifiedUSN > _LastUSN ) return TRUE; else return FALSE; }
//
// Function SetUSN
//
VOID SetUSN( UINT64 ModifiedUSN ) { _LastUSN = ModifiedUSN; return NOTHING; } //
// Function SetFlag
//
VOID SetFlag( ULONG Bits ) { _Flags |= Bits; } //
// Function ResetFlag
//
VOID ResetFlag( ULONG Bits ) { _Flags &= ~Bits; }
//
// Function SetTimeout
//
VOID SetTimeout( ULONG Timeout ) { _Timeout = Timeout; }
ULONG GetTimeout(void) { return _Timeout; }
//
// Function GetFolderMetadataName: Returns the unicode string
// that is this folders metadata name
//
PUNICODE_STRING GetFolderMetadataName() { return &_MetadataName; }
//
// Function GetFolderMetadataNameString:Returns a wide string
// that is this folders metadata name. Note that since the unicode
// string is stored with a null terminiated buffer, we can just
// use the unicode strings buffer.
//
LPWSTR GetFolderMetadataNameString() { return _MetadataName.Buffer; }
//
// Function GetFolderLogicalName: Returns a unicode string that is
// this folders logical name.
//
PUNICODE_STRING GetFolderLogicalName() { return &_LogicalName; }
LPWSTR GetFolderLogicalNameString() { return _LogicalName.Buffer; }
BOOLEAN IsFolderRoot() { return ( (_Flags & DFS_FOLDER_ROOT) == DFS_FOLDER_ROOT ); } BOOLEAN IsFolderInMetadataTable() { return ( (_Flags & DFS_FOLDER_IN_METADATA_TABLE) == DFS_FOLDER_IN_METADATA_TABLE ); }
BOOLEAN IsFolderInLogicalTable() { return ( (_Flags & DFS_FOLDER_IN_LOGICAL_TABLE) == DFS_FOLDER_IN_LOGICAL_TABLE ); }
BOOLEAN IsFolderDeleteInProgress() { return ( (_Flags & DFS_FOLDER_DELETE_IN_PROGRESS) == DFS_FOLDER_DELETE_IN_PROGRESS); }
BOOLEAN IsFolderInSiteReferrals() { return ( (_Flags & DFS_FOLDER_INSITE_REFERRALS) == DFS_FOLDER_INSITE_REFERRALS); } BOOLEAN IsFolderSiteCostingEnabled() { return ( (_Flags & DFS_FOLDER_COST_BASED_SITE_SELECTION) == DFS_FOLDER_COST_BASED_SITE_SELECTION); }
BOOLEAN IsFolderOutOfDomain() { return ( (_Flags & DFS_FOLDER_OUT_OF_DOMAIN) == DFS_FOLDER_OUT_OF_DOMAIN ); } BOOLEAN IsFolderOffline() { return ( (_Flags & DFS_FOLDER_OFFLINE) == DFS_FOLDER_OFFLINE ); }
BOOLEAN IsTimeToRetry(VOID) { ULONG CurrentTime = GetTickCount();
if ((CurrentTime > _RetryFailedLoadTimeout) && ((CurrentTime - _RetryFailedLoadTimeout) > DfsServerGlobalData.RetryFailedReferralLoadInterval)) { return TRUE; } // overflow
if ((CurrentTime < _RetryFailedLoadTimeout) && ((CurrentTime - 0) + (0xFFFFFFFF - _RetryFailedLoadTimeout) > DfsServerGlobalData.RetryFailedReferralLoadInterval)) { return TRUE; }
return FALSE; } //
// Function GetReferralData: Returns the referral data for this
// folder, and indicates if the referral data was cached or needed
// to be loaded.
//
DFSSTATUS GetReferralData( IN DfsFolderReferralData **ppReferralData, OUT BOOLEAN *pCacheHit, IN BOOLEAN AddToLoadedList=TRUE );
//
// Function RemoveReferralData: discards any cached referral data
// from the folder.
//
DFSSTATUS RemoveReferralData( IN DfsFolderReferralData *pRefData, IN PBOOLEAN pRemoved = NULL );
};
#endif // __DFS_FOLDER__
|