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.
 
 
 
 
 
 

443 lines
11 KiB

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