Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

459 lines
18 KiB

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
fcb.h
Abstract:
This module describes the structure of the redirector FCB (File Control
Block) structure. All network files are represented as FCB's in the
redirector.
Author:
Larry Osterman (LarryO) 1-Jun-1990
Revision History:
1-Jun-1990 LarryO
Created
--*/
#ifndef _FCB_
#define _FCB_
#define ETHERNET_BANDWIDTH 1000000
#define WRITE_BEHIND_AMOUNT_TIME 30
#define RAW_IO_MAX_TIME 5 // Max # of seconds for raw to take
// for raw operations.
typedef enum _FCB_TYPE {
Unknown,
Redirector, // Connection to redirector itself
NetRoot, // Connection to root of network ("\\")
ServerRoot, // Connection to share ("\\SERVER")
TreeConnect, // Tree connection files ("\\SERVER\SHARE")
DiskFile, // Disk (read/write) files
PrinterFile, // Printer (same as disk) files
Directory, // Directory files.
NamedPipe, // Named pipe
Com, // Remote serial device
Mailslot, // Remote Mailslot
FileOrDirectory, // Either a directory or file.
MaxFcbType // Maximum FCB type.
} FCB_TYPE;
typedef enum _FCB_LOCK_TYPE {
SharedLock, ExclusiveLock, NoLock
} FCB_LOCK_TYPE;
//
// FCB/ICB
//
// The FCB structure is used to hold all file specific information
// about an opened file under NT. Instance specific information is held
// in the ICB (Instance control block) associated with the FCB.
//
// There is a 1-1 mapping between an opened file and it's ICB. It
// contains the instance specific information about the file, such as
// it's FID, flags, the process ID of it's owner, a pointer to the file
// object, etc.
//
// The FCB contains global information about the file, like the file's
// name, it's FID, the connection it was opened on, etc.
//
// The name stored in the FCB is a canonicalized NT name. If
// NT opened:
//
// \Device\LanmanRedirector\Server\Share as file 1
//
// and
//
// \Directory1\Directory2 as file 2 related to file 1
//
// and
//
// \File1 as file 3 related to file 2, then
//
// the FCB->FileName for file 3 will contain:
//
// \Server\Share\Directory1\Directory2\File1
//
// in an appropriately canonicalized format for the name specified.
//
//
// We link the FCB and ICB into the file object as follows:
//
// The ICB is in FileObject->FsContext
// The FCB is in FileObject->FsContext2
//
// This allows the code to access either structure quickly.
//
//
// A couple of notes about Fcb->Resource
//
// Due to the way that close behind is implemented, it is possible that
// a create might come in for a file before the close behind on the
// file has hit the server (or been processed by the server). In order
// to prevent this from being a problem, we acquire the close behind
// for resource for SHARED access when starting a close behind request
// over the network, and acquire it for EXCLUSIVE access (and release
// it when the file is opened) when applying a new reference to the file.
//
// This allows multiple close behind operations to be outstanding on the
// file, while preventing the race condition described above.
//
// This needs to be a resource (instead of a notification event) because
// of the possiblity of multiple closers of the file, if multiple closers
// come in, we want the opener to wait for all closes to complete.
//
//
// For "normal" &X behind operations (like unlock behind), we acquire
// the resource for EXCLUSIVE access, and acquire it for SHARED access
// on normal read/write operations. This allows us to prevent races
// between &X behind operations and normal I/O.
//
// When attempting to acquire the resource for exclusive access (for
// unlockbehind), the acquirer shouldn't block when acquiring the
// resource, instead, if the resource couldn't be acquired, the acquirer
// shouldn't perform the operation. Thus, if it cannot acquire the
// resource for exclusive access, the unlockbehind code should issue
// a synchronous unlock. This is to prevent starvation of the unlock
// operation.
//
//
// The resource is also used to protect the file from being deleted
// while there are other operations outstanding on the file in question.
//
// If there are any other openers of the file, the redirector will prevent
// the delete from proceeding (with STATUS_ACCESS_DENIED), but
// if the file is opened by only one process, it is possible that there
// might be i/o outstanding on the file from another thread that will have
// to be synchronized.
//
struct _NONPAGED_FCB;
struct _FCB;
typedef struct _ICB {
ULONG Signature; // FCB structure signature.
ULONG Flags; // Flags for ICB
struct _FCB *Fcb; // FCB associated with file.
struct _NONPAGED_FCB *NonPagedFcb; // FCB associated with file.
LIST_ENTRY InstanceNext; // Next instance of ICB block.
PSECURITY_ENTRY Se; // Security entry associated with file
PNONPAGED_SECURITY_ENTRY NonPagedSe;// Security entry associated with file
ULONG DeletePending; // Is a delete pending on this file?
ACCESS_MASK GrantedAccess; // Access granted on file create.
USHORT FileId; // Network File IDentifier (FID)
FCB_TYPE Type; // Type of ICB (used for union below)
UNICODE_STRING DeviceName; // Name of redirected device.
ULONG EaIndex; // Next ea to be returned
union {
struct _FILE {
struct _SCB *Scb; // Search Control Block of this handle
PFILE_OBJECT FileObject; // Used when file is cached.
LARGE_INTEGER NextReadOffset; // Used for statistics gathering
LARGE_INTEGER NextWriteOffset; // Used for statistics gathering
BACK_PACK BackOff; // Used for locks to avoid
// flooding the network with failed requests
// when using a poorly written application
LOCKHEAD LockHead; // Head of lock chain for this file.
WRITE_BUFFER_HEAD WriteBufferHead; // Write behind buffer header.
ULONG Flags; // Flags describing open file instance
AND_X_BEHIND AndXBehind; // Structure used for &X behind ops
CCHAR OplockLevel;
BOOLEAN CcReadAhead; // Is the cache manager reading ahead?
BOOLEAN CcReliable; // Is the cache manager allowing write behind
} f;
struct _DIR {
struct _SCB *Scb; // Search Control Block if this handle
AND_X_BEHIND DirCtrlOutstanding;// Set when directory control is outstanding.
ULONG OpenOptions;
USHORT ShareAccess;
ULONG FileAttributes;
ACCESS_MASK DesiredAccess;
ULONG Disposition;
} d;
struct _SPOOL {
PVOID PrintBuffer; // Print buffer
} s;
struct _PIPE {
PFILE_OBJECT FileObject;
BACK_PACK BackOff; // Used for Named pipes to avoid
// flooding the network with failed requests
// when using a poorly written application
LARGE_INTEGER CollectDataTime; // Send characters to the net before
// this elapsed time expires.
LARGE_INTEGER CurrentEndCollectTime; // Time when WriteData.Buffer[0] was written
// plus CollectDataTime.
KTIMER Timer; // Used for CollectDataTime timeouts
KDPC Dpc; // points to RdrNpTimerDispatch
WORK_QUEUE_ITEM WorkEntry; // points to RdrNpTimedOut
KEVENT MessagePipeReadSync; // Synchronizes message pipe reads
KEVENT MessagePipeWriteSync; // Synchronizes message pipe writes
KEVENT TimerDone; // Synchronizes timer cancels
KSPIN_LOCK TimerLock;
struct _WRITE_PIPE_BUFFER {
KSEMAPHORE Semaphore; // Exclusive access only allowed
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} WriteData; // WriteData is for write behind,
struct READ_PIPE_BUFFER {
KSEMAPHORE Semaphore; // Exclusive access only allowed
USHORT Length; // Bytes of data in Buffer
USHORT Offset; // Offset in Buffer of first valid byte
USHORT MaximumLength;
PCHAR Buffer;
} ReadData; // ReadData is for read ahead.
USHORT PipeState; // Pipe state
USHORT MaximumCollectionCount; // When WriteData has at least this much
// data then send contents to the network.
BOOLEAN TimeoutRunning;
BOOLEAN TimeoutCancelled;
} p;
} u;
} ICB, *PICB;
//
// Flags that describe the global state of the open instance and that
// are relevant for all file types.
//
#define ICB_ERROR 0x00000001 // File is in error and cannot be used
#define ICB_FORCECLOSED 0x00000002 // File was force closed.
#define ICB_RENAMED 0x00000004 // File was renamed.
#define ICB_TCONCREATED 0x00000008 // File was created as a tree connect.
#define ICB_HASHANDLE 0x00000010 // Set IFF file has an open handle.
#define ICB_PSEUDOOPENED 0x00000020 // Set if file is pseudo-opened.
#define ICB_DELETE_PENDING 0x00000040 // Set if FileObject->DeletePending set
#define ICB_UNUSED1 0x00000080 //
#define ICB_OPENED 0x00000100 // This ICB was opened (thus the
// backpack has been allocated, etc)
#define ICB_SETDATEONCLOSE 0x00000200 // Set the date and time on the file
// on close (used for core servers)
#define ICB_DEFERREDOPEN 0x00000400 // Set for PRINT and COMM devices that
// are create on first operation
#define ICB_OPEN_TARGET_DIR 0x00000800 // Set if the file is a handle to the target's directory.
#define ICB_SET_DEFAULT_SE 0x00001000 // Set if the file has had a default Se set
#define ICB_USER_SET_TIMES 0x00002000 // Set if the user called SetInformationFile
// to set the file's times
#define ICB_SETATTRONCLOSE 0x00004000 // Update attributes after close.
#define ICB_DELETEONCLOSE 0x00008000 // Delete the file on close.
#define ICB_STORAGE_TYPE 0x000f0000 // Storage type mask
#define ICB_BACKUP_INTENT 0x01000000 // File opened for backup intent.
#define ICB_STORAGE_TYPE_SHIFT 16
//
// Flags that are relevant only to handle based disk files.
//
#define ICBF_OPLOCKED 0x00000001 // Set if file has been oplocked.
#define ICBF_OPENEDOPLOCKED 0x00000002 // Set if file has ever been oplocked.
#define ICBF_OPENEDEXCLUSIVE 0x00000004 // Set if file was opened exclusively.
#ifdef RDRDBG_FCBREF
typedef struct _REFERENCE_HISTORY_ENTRY {
ULONG NewReferenceCount;
ULONG IsDereference;
PVOID Caller;
PVOID CallersCaller;
} REFERENCE_HISTORY_ENTRY, *PREFERENCE_HISTORY_ENTRY;
typedef struct _REFERENCE_HISTORY {
ULONG TotalReferences;
ULONG TotalDereferences;
ULONG NextEntry;
PREFERENCE_HISTORY_ENTRY HistoryTable;
} REFERENCE_HISTORY, *PREFERENCE_HISTORY;
#define REFERENCE_HISTORY_LENGTH 128
#endif
//
// The FCB->Header.FileSize fields are protected by a global lock. We use
// two different lock mechanisms depending on the size of the FCB - when the
// remote filesystem is <4G in size, we use a NOP, when it is >4G in size, we
// use a routine that acquires a global resource protecting these fields.
//
// By doing this, we can move the common FCB header into paged pool.
//
typedef
VOID
(*ACQUIRE_FCB_SIZE_ROUTINE)(
IN struct _FCB *Fcb
);
typedef
VOID
(*RELEASE_FCB_SIZE_ROUTINE)(
IN struct _FCB *Fcb
);
typedef struct _NONPAGED_FCB {
USHORT Signature; // FCB structure signature.
USHORT Size;
struct _FCB *PagedFcb;
#ifdef RDRDBG_FCBREF
REFERENCE_HISTORY ReferenceHistory;
#endif
LONG RefCount; // Number of ICB's that point to FCB
ULONG Flags; // Flags for FCB
FCB_TYPE Type; // Type of file
FILE_TYPE FileType; // Type of file.
struct _FCB *SharingCheckFcb; // Optional Fcb for sharing checks (used for data streams over net).
//
// Memory management (and the cache manager) refer to the section
// object pointers with a spinlock held, so these cannot be pagable.
//
SECTION_OBJECT_POINTERS SectionObjectPointer;
KEVENT CreateComplete; // Signalled when open completes
KEVENT PurgeCacheSynchronizer; // Not-Signalled when purging cache.
//
// The following 3 fields cannot be made pagable, since they MUST be
// accessed in the callback routine.
//
PNONPAGED_SECURITY_ENTRY OplockedSecurityEntry; // Security entry of file if oplocked
ERESOURCE InstanceChainLock;
USHORT OplockedFileId; // FileId of the file if it is oplocked
CCHAR OplockLevel; // Oplock level on file.
} NONPAGED_FCB, *PNONPAGED_FCB;
typedef struct _FCB {
FSRTL_COMMON_FCB_HEADER Header;
PNONPAGED_FCB NonPagedFcb;
struct _CONNECTLISTENTRY *Connection;
//
// The fields from this point down are pagable.
//
LONG NumberOfOpens; // Number of handles that point to FCB
NTSTATUS OpenError; // Open error - Set if open fails.
LIST_ENTRY GlobalNext; // Pointer to next FCB in global chain
LIST_ENTRY ConnectNext; // Per connectlist FCB list
LIST_ENTRY InstanceChain; // Instance chain - ICB list.
UNICODE_STRING FileName; // Fully qualified name of file.
UNICODE_STRING LastFileName; // Last component in file name.
SHARE_ACCESS ShareAccess; // Share access for file.
LARGE_INTEGER CreationTime; // Time that the file was created
LARGE_INTEGER LastAccessTime; // Time that the file was last accessed
LARGE_INTEGER LastWriteTime; // Time that the file was last written
LARGE_INTEGER ChangeTime; // Time that the file was last changed.
ULONG Attribute; // File attribute
//
// The fields from this point down are associated only with files, not
// with directories. These can be overlaid at some point if appropriate.
//
FILE_LOCK FileLock; // FsRtl lock package locking structure
ULONG WriteBehindPages; // Number of write behind pages to allow
ULONG DormantTimeout; // Time after the file has been closed
// that it should be purged from the
// cache
PETHREAD LazyWritingThread; // Lazy writer thread if present.
ULONG ServerFileId; // Server unique file id.
ACQUIRE_FCB_SIZE_ROUTINE AcquireSizeRoutine;
RELEASE_FCB_SIZE_ROUTINE ReleaseSizeRoutine;
ACCESS_MASK GrantedAccess; // Granted access of oplocked file.
USHORT GrantedShareAccess; // Granted share access of oplocked file.
USHORT AccessGranted; // Access actually granted
ULONG UpdatedFile; // Have we performed any operations which update
// file data or attributes?
ULONG HaveSetCacheReadAhead; // Have we detected a trend and told the cache
// manager to read ahead?
} FCB, *PFCB;
//
// FCB Flags.
//
#define FCB_ERROR 0x00000001// File is in error and cannot be used
#define FCB_CLOSING 0x00000002// File is in the process of closing.
#define FCB_IMMUTABLE 0x00000004// File cannot be modified.
#define FCB_DELETEPEND 0x00000008// File has a delete pending on it.
#define FCB_DOESNTEXIST 0x00000010// Set if the file doesn't really exist
#define FCB_OPLOCKED 0x00000020// Set if the file is oplocked.
#define FCB_HASOPLOCKHANDLE 0x00000100// Set if Fcb->OplockedFileId is valid
#define FCB_OPLOCKBREAKING 0x00000200// Set if an oplock is breaking on file
#define FCB_WRITE_THROUGH 0x00000400// Set if a write through handle is open on the file
#define FCB_PAGING_FILE 0x00000800// Set if this is a paging file.
#define FCB_DELETEONCLOSE 0x00001000// Delete the file on close.
#define FCB_DFSFILE 0x00002000// File opened by Dfs
//
// FID values that should not be transmitted. Icb->FileId should have a
// value obtained from the server or one of the values below.
//
#define TREE_CONNECT_FID 0xffff
#define CREATE_DIRECTORY_FID 0xfffe
#define REDIRECTOR_FID 0xfffd
#define OPEN_DIRECTORY_FID 0xfffc
typedef
VOID
(*PFCB_ENUMERATION_ROUTINE) (
IN PFCB Fcb,
IN PVOID Context
);
extern
KSPIN_LOCK
RdrFileSizeLock;
#define LOCK_FILE_SIZES(Fcb, OldIrql) \
Fcb->AcquireSizeRoutine(Fcb);
// ACQUIRE_SPIN_LOCK(&RdrFileSizeLock, &OldIrql);
#define UNLOCK_FILE_SIZES(Fcb, OldIrql) \
Fcb->ReleaseSizeRoutine(Fcb);
// RELEASE_SPIN_LOCK(&RdrFileSizeLock, OldIrql);
#define RdrReleaseFcbLock(Fcb) \
ExReleaseResource((Fcb)->Header.Resource);
#define RdrReleaseFcbLockForThread(Fcb, Thread) \
ExReleaseResourceForThread((Fcb)->Header.Resource, (Thread));
#endif