|
|
//+----------------------------------------------------------------------------
//
// Copyright (C) 1992, Microsoft Corporation.
//
// File: dfsstruc.h
//
// Contents:
// This module defines the data structures that make up the major internal
// part of the DFS file system.
//
// Functions:
//
// History: 12 Nov 1991 AlanW Created from CDFS souce.
// 8 May 1992 PeterCo Removed all EP related stuff
// Added stuff to support PKT
// 11 May 1992 PeterCo Added support for attached devices
// 24 April 1993 SudK Added support for KernelToUserMode calls
// Added support for timer functionality.
//-----------------------------------------------------------------------------
#ifndef _DFSSTRUC_
#define _DFSSTRUC_
typedef enum { DFS_UNKNOWN = 0, DFS_CLIENT = 1, DFS_SERVER = 2, DFS_ROOT_SERVER = 3, } DFS_MACHINE_STATE;
typedef enum { LV_UNINITIALIZED = 0, LV_INITSCHEDULED, LV_INITINPROGRESS, LV_INITIALIZED, LV_VALIDATED } DFS_LV_STATE;
//
// The DFS_DATA record is the top record in the DFS file system in-memory
// data structure. This structure must be allocated from non-paged pool.
//
typedef struct _DFS_DATA {
//
// The type and size of this record (must be DSFS_NTC_DATA_HEADER)
//
NODE_TYPE_CODE NodeTypeCode; NODE_BYTE_SIZE NodeByteSize;
//
// A queue of all the logical roots that are known by the file system.
//
LIST_ENTRY VcbQueue;
//
// A list of all the deleted logical roots that still have files open
// on them.
//
LIST_ENTRY DeletedVcbQueue;
//
// A queue of all the DRT (Deviceless roots) that are known.
//
LIST_ENTRY DrtQueue;
//
// A list of all the user-defined credentials
//
LIST_ENTRY Credentials;
//
// A list of all the deleted credentials. They will be destroyed once
// their ref count goes to 0
//
LIST_ENTRY DeletedCredentials;
//
// A list of all the offline roots
//
LIST_ENTRY OfflineRoots;
//
// A pointer to the Driver object we were initialized with
//
PDRIVER_OBJECT DriverObject;
//
// A pointer to the \Dfs device object
//
PDEVICE_OBJECT FileSysDeviceObject;
//
// A pointer to an array of provider records
//
struct _PROVIDER_DEF *pProvider; int cProvider, maxProvider;
//
// A resource variable to control access to the global data record
//
ERESOURCE Resource;
//
// A spin lock to control access to the global data record; handy for
// Interlocked operations.
//
KSPIN_LOCK DfsLock;
//
// A pointer to our EPROCESS struct, which is a required input to the
// Cache Management subsystem. This field is simply set each time an
// FSP thread is started, since it is easiest to do while running in the
// Fsp.
//
PEPROCESS OurProcess;
//
// Lookaside list for IRP contexts
//
NPAGED_LOOKASIDE_LIST IrpContextLookaside;
//
// Device name prefix for the logical root devices.
// E.g., `\Device\WinDfs\'.
//
UNICODE_STRING LogRootDevName;
//
// The state of the machine - DC, Server, Client etc.
//
DFS_MACHINE_STATE MachineState;
//
// The system wide Partition Knowledge Table (PKT)
//
DFS_PKT Pkt;
//
// DNR has been designed so that resources (like the Pkt above) are not
// locked across network calls. This is critical to prevent inter-machine
// deadlocks and for other functionality. To regulate access to these
// resources, we use the following two events.
//
// This notify event is used to indicate that some thread is waiting to
// write into the Pkt. If this event is !RESET!, it means that a thread
// is waiting to write, and other threads trying to enter DNR should
// hold off.
//
KEVENT PktWritePending;
//
// This semaphone is used to indicate that some thread(s) have currently
// gone to get a referral. Another thread that wants to get a referral
// should wait till this semaphone is SIGNALLED before attempting to go
// get its own referral.
//
KSEMAPHORE PktReferralRequests;
//
// A hash table for associating DFS_FCBs with file objects
//
struct _FCB_HASH_TABLE *FcbHashTable;
//
// EA buffer used to diffrentiate CSC opens from others
//
PFILE_FULL_EA_INFORMATION CSCEaBuffer; ULONG CSCEaBufferLength;
} DFS_DATA, *PDFS_DATA;
#define MAX_PROVIDERS 5 // number of pre-allocated provider records
//
// A PROVIDER_DEF is a structure that abstracts an underlying redirector.
//
typedef struct _PROVIDER_DEF {
//
// The type and size of this record (must be DSFS_NTC_PROVIDER)
//
NODE_TYPE_CODE NodeTypeCode; NODE_BYTE_SIZE NodeByteSize;
//
// Provider ID and Capabilities, same as in the DS_REFERRAL structure.
//
USHORT eProviderId; USHORT fProvCapability;
//
// The following field gives the name of the device for the provider.
//
UNICODE_STRING DeviceName;
//
// Referenced pointers to the associated file and device objects
//
PDEVICE_OBJECT DeviceObject; PFILE_OBJECT FileObject;
} PROVIDER_DEF, *PPROVIDER_DEF;
//
// The Vcb (Volume Control Block) record corresponds to every volume
// (ie, a net use) mounted by the file system. They are ordered in a
// queue off of DfsData.VcbQueue.
//
// For the DFS file system, `volumes' correspond to DFS logical roots.
// These records are an extension of a corresponding device object.
//
typedef struct _DFS_VCB {
//
// The type and size of this record (must be DSFS_NTC_VCB)
//
NODE_TYPE_CODE NodeTypeCode; NODE_BYTE_SIZE NodeByteSize;
//
// The links for the device queue off of DfsData.VcbQueue
//
LIST_ENTRY VcbLinks;
//
// The internal state of the device. This is a collection of FSD device
// state flags.
//
USHORT VcbState;
//
// The logical root corresponding to this volume. Forms part of the
// path name in the NT object name space. This string will be something
// like L"org", or L"dom" etc.
//
UNICODE_STRING LogicalRoot;
//
// The LogRootPrefix has a prefix that needs to be prepended to file
// names being opened via this logical root before their name can
// be resolved.
//
UNICODE_STRING LogRootPrefix;
//
// The credentials associated with this logical root
//
struct _DFS_CREDENTIALS *Credentials;
//
// A count of the number of file objects that have opened the volume
// for direct access, and their share access state.
//
CLONG DirectAccessOpenCount; SHARE_ACCESS ShareAccess;
//
// A count of the number of file objects that have any file/directory
// opened on this volume, not including direct access.
//
CLONG OpenFileCount; PFILE_OBJECT FileObjectWithVcbLocked;
#ifdef TERMSRV
ULONG SessionID;
#endif // TERMSRV
LUID LogonID; PDFS_PKT_ENTRY pktEntry; } DFS_VCB; typedef DFS_VCB *PDFS_VCB;
#define VCB_STATE_FLAG_LOCKED (0x0001)
#define VCB_STATE_FLAG_ALLOC_FCB (0x0002)
#define VCB_STATE_CSCAGENT_VOLUME (0x0004)
//#define VCB_STATE_FLAG_DEVICE_ONLY (0x0008)
#ifdef TERMSRV
//
// This SessionId indicates that the device name should not be suffixed
// with :SessionID, and that no matching on SessionID should be done.
//
#define INVALID_SESSIONID 0xffffffff
#endif
//
// A CREDENTIAL_RECORD is a user-supplied set of credentials that should
// be used when accessing a particular Dfs. They are ordered in a queue
// off of DfsData.Credentials;
//
typedef struct _DFS_CREDENTIALS {
//
// The links for the credentials queue off of DfsData.Credentials
//
LIST_ENTRY Link;
//
// A flags field to keep state about this credential record.
//
ULONG Flags;
//
// A ref count to keep this credential record from going away while
// it is being used.
//
ULONG RefCount;
//
// A count of the number of net uses that refer to these credentials
//
ULONG NetUseCount;
//
// The root of the Dfs for which these credentials apply.
//
UNICODE_STRING ServerName; UNICODE_STRING ShareName;
//
// The domain name, user name and password to use when accessing the
// Dfs rooted at ServerName\ShareName
//
UNICODE_STRING DomainName; UNICODE_STRING UserName; UNICODE_STRING Password;
#ifdef TERMSRV
ULONG SessionID;
#endif // TERMSRV
LUID LogonID; //
// When setting up a Tree connect using these credentials, we'll need
// to form an EA Buffer to pass in with the ZwCreateFile call. So, we
// form one here.
//
ULONG EaLength; PUCHAR EaBuffer[1];
} DFS_CREDENTIALS; typedef DFS_CREDENTIALS *PDFS_CREDENTIALS;
#define CRED_HAS_DEVICE 0x1
#define CRED_IS_DEVICELESS 0x2
//
// The DFS_FCB record corresponds to every open file and directory.
//
typedef struct _DFS_FCB {
//
// Type and size of this record (must be DSFS_NTC_FCB or DSFS_NTC_DCB)
//
NODE_TYPE_CODE NodeTypeCode; NODE_BYTE_SIZE NodeByteSize;
//
// A list entry for the hash table chain.
//
LIST_ENTRY HashChain;
//
// A pointer to the Logical root device, through which this DFS_FCB
// was opened.
//
PDFS_VCB Vcb;
//
// The following field is the fully qualified file name for this DFS_FCB/DCB
// starting from the logical root.
//
union { UNICODE_STRING FullFileName; DFS_NAME_CONTEXT DfsNameContext; };
UNICODE_STRING AlternateFileName;
//
// The following fields give the file and devices on which this DFS_FCB
// have been opened. The DFS driver will pass through requests for
// the file object to the target device below.
//
PFILE_OBJECT FileObject;
//
// The destinatation FSD device object through which I/O will be done.
//
PDEVICE_OBJECT TargetDevice;
//
// The provider def that opened this file
//
USHORT ProviderId;
//
// The DFS_MACHINE_ENTRY through which this file was opened. We need
// to maintain a reference for each file on a DFS_MACHINE_ENTRY in
// case we have authenticated connections to the server; we don't want
// to tear down the authenticated connection if files are open.
//
PDFS_MACHINE_ENTRY DfsMachineEntry;
WORK_QUEUE_ITEM WorkQueueItem;
} DFS_FCB, *PDFS_FCB;
//
// The Logical Root Device Object is an I/O system device object
// created as a result of creating a DFS logical root.
// Logical roots are in many ways analogous to volumes
// for a local file system.
//
// There is a DFS_VCB record appended to the end.
//
typedef struct _LOGICAL_ROOT_DEVICE_OBJECT {
DEVICE_OBJECT DeviceObject;
//
// This is the file system specific volume control block.
//
DFS_VCB Vcb;
} LOGICAL_ROOT_DEVICE_OBJECT, *PLOGICAL_ROOT_DEVICE_OBJECT;
//
// The Irp Context record is allocated for every orginating Irp. It
// is created by the Fsd dispatch routines, and deallocated by the
// DfsCompleteRequest routine
//
typedef struct _IRP_CONTEXT {
//
// Type and size of this record (must be DSFS_NTC_IRP_CONTEXT)
//
NODE_TYPE_CODE NodeTypeCode; NODE_BYTE_SIZE NodeByteSize;
//
// This structure is used for posting to the Ex worker threads.
//
WORK_QUEUE_ITEM WorkQueueItem;
//
// A pointer to the originating Irp.
//
PIRP OriginatingIrp;
//
// A pointer to function dependent context.
//
PVOID Context;
//
// Major and minor function codes copied from the Irp
//
UCHAR MajorFunction; UCHAR MinorFunction;
//
// The following flags field indicates if we can wait/block for a resource
// or I/O, if we are to do everything write through, and if this
// entry into the Fsd is a recursive call
//
USHORT Flags;
//
// The following field contains the NTSTATUS value used when we are
// unwinding due to an exception
//
NTSTATUS ExceptionStatus;
} IRP_CONTEXT; typedef IRP_CONTEXT *PIRP_CONTEXT;
//
// Values for the Irp context Flags field.
//
//#define IRP_CONTEXT_FLAG_FROM_POOL (0x00000001) // replaced by lookaside list
#define IRP_CONTEXT_FLAG_WAIT (0x00000002)
#define IRP_CONTEXT_FLAG_IN_FSD (0x00000004)
//
// This context is used by the DfsIoTimer routine. We can expand on this
// whenever new functionality needs to be added to the Timer function.
//
typedef struct _DFS_TIMER_CONTEXT {
//
// TickCount. To keep track of how many times the timer routine was
// called. The timer uses this to do things at a coarser granularity.
//
ULONG TickCount;
//
// InUse. This field is used to denote that this CONTEXT is in use
// by some function to which the Timer routine has passed it off. This
// is used in a simple way to control access to this context.
//
BOOLEAN InUse;
//
// ValidateLocalPartitions. This field is used to denote that the
// local volumes should be validated at this time.
//
BOOLEAN ValidateLocalPartitions;
//
// This is used to schedule DfsAgePktEntries.
//
WORK_QUEUE_ITEM WorkQueueItem;
//
// This is used to schedule DfsDeleteDevices.
//
WORK_QUEUE_ITEM DeleteQueueItem;
} DFS_TIMER_CONTEXT, *PDFS_TIMER_CONTEXT;
//
// The following constant is the number of seconds between any two scans
// through the PKT to get rid of old PKT entries.
//
#define DFS_MAX_TICKS 240
//
// The following constant is the number of seconds that a referral will
// remain in cache (PKT).
//
#define MAX_REFERRAL_LIFE_TIME 300
//
// The followin constants are the starting timeout (in seconds) between
// special referrals. The start value is doubled after every retry until it
// reaches the max.
//
#define SPECIAL_TIMEOUT_START (5*60) // 5 min
#define SPECIAL_TIMEOUT_MAX (60*60) // 60 min
//
// The Drt (Devless Root) record corresponds to every net use.
// They are ordered in a queue off of DfsData.VcbQueue.
//
//
typedef struct _DFS_DEVLESS_ROOT {
//
// The type and size of this record (must be DSFS_NTC_DRT)
//
NODE_TYPE_CODE NodeTypeCode; NODE_BYTE_SIZE NodeByteSize;
//
// The links for the device queue off of DfsData.DrtQueue
//
LIST_ENTRY DrtLinks;
//
// The pathname corresponding to this entry.
//
UNICODE_STRING DevlessPath;
//
// The credentials associated with this logical root
//
struct _DFS_CREDENTIALS *Credentials;
#ifdef TERMSRV
ULONG SessionID;
#endif // TERMSRV
LUID LogonID; PDFS_PKT_ENTRY pktEntry; } DFS_DEVLESS_ROOT;
typedef DFS_DEVLESS_ROOT *PDFS_DEVLESS_ROOT;
#endif // _DFSSTRUC_
|