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