mirror of
https://github.com/reactos/reactos.git
synced 2024-11-10 00:34:39 +00:00
4f0b8d3db0
svn path=/branches/ntvdm/; revision=59241
684 lines
25 KiB
C
684 lines
25 KiB
C
/*************************************************************************
|
|
*
|
|
* File: struct.h
|
|
*
|
|
* Module: Ext2 File System Driver (Kernel mode execution only)
|
|
*
|
|
* Description:
|
|
* This file contains structure definitions for the sample file system
|
|
* driver. Note that all structures are prefixed with the letters
|
|
* "Ext2". The structures are all aligned using normal alignment
|
|
* used by the compiler (typically quad-word aligned).
|
|
*
|
|
* Author: Manoj Paul Joseph
|
|
*
|
|
*
|
|
*************************************************************************/
|
|
|
|
#ifndef _EXT2_STRUCTURES_H_
|
|
#define _EXT2_STRUCTURES_H_
|
|
|
|
/**************************************************************************
|
|
some useful definitions
|
|
**************************************************************************/
|
|
typedef CHAR int8;
|
|
typedef SHORT int16;
|
|
typedef LONG int32;
|
|
|
|
typedef UCHAR uint8;
|
|
typedef USHORT uint16;
|
|
typedef ULONG uint32;
|
|
|
|
typedef PVOID PBCB;
|
|
|
|
//
|
|
// This is a huge hack that will create a broken driver for GCC.
|
|
// The driver should use PSEH2.
|
|
//
|
|
#ifdef _MSC_VER
|
|
#define try __try
|
|
#define except __except
|
|
#define finally __finally
|
|
#else
|
|
#define try if (1)
|
|
#define except(x) if (0 && (x))
|
|
#define finally if (1)
|
|
#define GetExceptionInformation() 0
|
|
#define GetExceptionCode() 0
|
|
#endif
|
|
|
|
// we will use the LARGE_INTEGER structure as defined by NT
|
|
|
|
/**************************************************************************
|
|
some empty typedefs defined here so we can reference them easily
|
|
**************************************************************************/
|
|
struct _Ext2Identifier;
|
|
struct _Ext2ObjectName;
|
|
struct _Ext2ContextControlBlock;
|
|
struct _Ext2NTRequiredFCB;
|
|
struct _Ext2DiskDependentFCB;
|
|
struct _Ext2FileControlBlock;
|
|
struct _Ext2FileByteLocks;
|
|
struct _Ext2VolumeControlBlock;
|
|
struct _Ext2IrpContext;
|
|
struct _Ext2Data;
|
|
|
|
/**************************************************************************
|
|
each structure has a unique "node type" or signature associated with it
|
|
**************************************************************************/
|
|
#define EXT2_NODE_TYPE_OBJECT_NAME (0xfdecba01)
|
|
#define EXT2_NODE_TYPE_CCB (0xfdecba02)
|
|
#define EXT2_NODE_TYPE_FCB (0xfdecba03)
|
|
#define EXT2_NODE_TYPE_LOCKS (0xfdecba04)
|
|
#define EXT2_NODE_TYPE_VCB (0xfdecba05)
|
|
#define EXT2_NODE_TYPE_IRP_CONTEXT (0xfdecba06)
|
|
#define EXT2_NODE_TYPE_GLOBAL_DATA (0xfdecba07)
|
|
#define EXT2_NODE_TYPE_IO_CONTEXT (0xfdecba08)
|
|
#define EXT2_NODE_TYPE_SAVED_BCB (0xfdecba09)
|
|
#define EXT2_NODE_TYPE_FREED (0x10101010)
|
|
#define EXT2_NODE_TYPE_INVALID (0x10101010)
|
|
|
|
/**************************************************************************
|
|
every structure has a node type, and a node size associated with it.
|
|
The node type serves as a signature field. The size is used for
|
|
consistency checking ...
|
|
**************************************************************************/
|
|
typedef struct _Ext2Identifier {
|
|
uint32 NodeType; // a 32 bit identifier for the structure
|
|
uint32 NodeSize; // computed as sizeof(structure)
|
|
} Ext2Identifier, *PtrExt2Identifier;
|
|
|
|
/**************************************************************************
|
|
Structures for byte-range lock support.
|
|
**************************************************************************/
|
|
typedef struct Ext2FileLockAnchor {
|
|
LIST_ENTRY GrantedFileLockList;
|
|
LIST_ENTRY PendingFileLockList;
|
|
} Ext2FileLockAnchor, *PtrExt2FileLockAnchor;
|
|
|
|
typedef struct Ext2FileLockInfo {
|
|
Ext2Identifier NodeIdentifier;
|
|
uint32 FileLockFlags;
|
|
PVOID OwningProcess;
|
|
LARGE_INTEGER StartingOffset;
|
|
LARGE_INTEGER Length;
|
|
LARGE_INTEGER EndingOffset;
|
|
ULONG Key;
|
|
BOOLEAN ExclusiveLock;
|
|
PIRP PendingIRP;
|
|
LIST_ENTRY NextFileLockEntry;
|
|
} Ext2FileLockInfo, *PtrExt2FileLockInfo;
|
|
|
|
#define EXT2_BYTE_LOCK_NOT_FROM_ZONE (0x80000000)
|
|
#define EXT2_BYTE_LOCK_IS_PENDING (0x00000001)
|
|
|
|
/**************************************************************************
|
|
Every open on-disk object must have a name associated with it
|
|
This name has two components:
|
|
(a) the path-name (prefix) that leads to this on-disk object
|
|
(b) the name of the object itself
|
|
Note that with multiply linked objects, a single object might be
|
|
associated with more than one name structure.
|
|
This sample FSD does not correctly support multiply linked objects.
|
|
|
|
This structure must be quad-word aligned because it is zone allocated.
|
|
**************************************************************************/
|
|
typedef struct _Ext2ObjectName {
|
|
Ext2Identifier NodeIdentifier;
|
|
uint32 ObjectNameFlags;
|
|
// an absolute pathname of the object is stored below
|
|
UNICODE_STRING ObjectName;
|
|
} Ext2ObjectName, *PtrExt2ObjectName;
|
|
|
|
#define EXT2_OB_NAME_NOT_FROM_ZONE (0x80000000)
|
|
|
|
/**************************************************************************
|
|
Each file open instance is represented by a context control block.
|
|
For each successful create/open request; a file object and a CCB will
|
|
be created.
|
|
For open operations performed internally by the FSD, there may not
|
|
exist file objects; but a CCB will definitely be created.
|
|
|
|
This structure must be quad-word aligned because it is zone allocated.
|
|
**************************************************************************/
|
|
typedef struct _Ext2ContextControlBlock {
|
|
Ext2Identifier NodeIdentifier;
|
|
// ptr to the associated FCB
|
|
struct _Ext2FileControlBlock *PtrFCB;
|
|
// all CCB structures for a FCB are linked together
|
|
LIST_ENTRY NextCCB;
|
|
// each CCB is associated with a file object
|
|
PFILE_OBJECT PtrFileObject;
|
|
// flags (see below) associated with this CCB
|
|
uint32 CCBFlags;
|
|
// current byte offset is required sometimes
|
|
LARGE_INTEGER CurrentByteOffset;
|
|
// if this CCB represents a directory object open, we may
|
|
// need to maintain a search pattern
|
|
|
|
// PSTRING DirectorySearchPattern;
|
|
UNICODE_STRING DirectorySearchPattern;
|
|
|
|
// The full path name for the file...
|
|
UNICODE_STRING AbsolutePathName;
|
|
|
|
// Rename/Link Target file name
|
|
// Used only in a Rename/Link operation
|
|
UNICODE_STRING RenameLinkTargetFileName;
|
|
|
|
// we must maintain user specified file time values
|
|
uint32 UserSpecifiedTime;
|
|
|
|
|
|
} Ext2CCB, *PtrExt2CCB;
|
|
|
|
|
|
/**************************************************************************
|
|
the following CCBFlags values are relevant. These flag
|
|
values are bit fields; therefore we can test whether
|
|
a bit position is set (1) or not set (0).
|
|
**************************************************************************/
|
|
|
|
// some on-disk file/directories are opened by EXT2 itself
|
|
// as opposed to being opened on behalf of a user process
|
|
#define EXT2_CCB_OPENED_BY_EXT2 (0x00000001)
|
|
// the file object specified synchronous access at create/open time.
|
|
// this implies that EXT2 must maintain the current byte offset
|
|
#define EXT2_CCB_OPENED_FOR_SYNC_ACCESS (0x00000002)
|
|
// file object specified sequential access for this file
|
|
#define EXT2_CCB_OPENED_FOR_SEQ_ACCESS (0x00000004)
|
|
// the CCB has had an IRP_MJ_CLEANUP issued on it. we must
|
|
// no longer allow the file object / CCB to be used in I/O requests.
|
|
#define EXT2_CCB_CLEANED (0x00000008)
|
|
// if we were invoked via the fast i/o path to perform file i/o;
|
|
// we should set the CCB access/modification time at cleanup
|
|
#define EXT2_CCB_ACCESSED (0x00000010)
|
|
#define EXT2_CCB_MODIFIED (0x00000020)
|
|
// if an application process set the file date time, we must
|
|
// honor that request and *not* overwrite the values at cleanup
|
|
#define EXT2_CCB_ACCESS_TIME_SET (0x00000040)
|
|
#define EXT2_CCB_MODIFY_TIME_SET (0x00000080)
|
|
#define EXT2_CCB_CREATE_TIME_SET (0x00000100)
|
|
|
|
#define EXT2_CCB_NOT_FROM_ZONE (0x80000000)
|
|
|
|
// this CCB was allocated for a "volume open" operation
|
|
#define EXT2_CCB_VOLUME_OPEN (0x00000100)
|
|
|
|
/**************************************************************************
|
|
each open file/directory/volume is represented by a file control block.
|
|
NOTE: Currently, EXT2 does not handle multiply linked files correctly.
|
|
In your FSD implementation, you must be careful about handling
|
|
such on-disk files correctly i.e. a single (unique) FCB must
|
|
represent an on-disk file/directory regardless of the path used
|
|
to access the on-disk object.
|
|
With the current EXT2 implementation, an on-disk file object
|
|
with more than a single (hard) link will be treated incorrectly!
|
|
|
|
Each FCB can logically be divided into two:
|
|
(a) a structure that must have a field of type FSRTL_COMMON_FCB_HEADER
|
|
as the first field in the structure.
|
|
This portion should also contain other structures/resources required
|
|
by the NT Cache Manager
|
|
We will call this structure the "NT Required" FCB. Note that this
|
|
portion of the FCB must be allocated from non-paged pool.
|
|
(b) the remainder of the FCB is dependent upon the particular FSD
|
|
requirements.
|
|
This portion of the FCB could possibly be allocated from paged
|
|
memory, though in the sample FSD, it will always be allocated
|
|
from non-paged pool.
|
|
|
|
FCB structures are protected by the MainResource as well as the
|
|
PagingIoResource. Of course, if your FSD implementation requires
|
|
it, you can associate other syncronization structures with the
|
|
FCB.
|
|
|
|
This structure must be quad-word aligned because it is zone allocated.
|
|
**************************************************************************/
|
|
typedef struct _Ext2NTRequiredFCB
|
|
{
|
|
FSRTL_COMMON_FCB_HEADER CommonFCBHeader;
|
|
SECTION_OBJECT_POINTERS SectionObject;
|
|
ERESOURCE MainResource;
|
|
ERESOURCE PagingIoResource;
|
|
} Ext2NTRequiredFCB, *PtrExt2NTRequiredFCB;
|
|
|
|
typedef struct _Ext2DiskDependentFCB
|
|
{
|
|
// although the sample FSD does not maintain on-disk data structures,
|
|
// this structure serves as a reminder of the logical separation that
|
|
// your FSD can maintain between the disk dependent and the disk
|
|
// independent portions of the FCB.
|
|
uint16 DummyField; // placeholder
|
|
} Ext2DiskDependentFCB, *PtrExt2DiskDependentFCB;
|
|
|
|
typedef struct _Ext2FileControlBlock
|
|
{
|
|
Ext2Identifier NodeIdentifier;
|
|
// we will go ahead and embed the "NT Required FCB" right here.
|
|
// Note though that it is just as acceptable to simply allocate
|
|
// memory separately for the other half of the FCB and store a
|
|
// pointer to the "NT Required" portion here instead of embedding
|
|
// it ...
|
|
Ext2NTRequiredFCB NTRequiredFCB;
|
|
// the disk dependent portion of the FCB is embedded right here
|
|
Ext2DiskDependentFCB DiskDependentFCB;
|
|
// this FCB belongs to some mounted logical volume
|
|
struct _Ext2VolumeControlBlock *PtrVCB;
|
|
// to be able to access all open file(s) for a volume, we will
|
|
// link all FCB structures for a logical volume together
|
|
LIST_ENTRY NextFCB;
|
|
|
|
// to be used if this FCB is on the Closable FCB List...
|
|
struct _ClosableFCBs
|
|
{
|
|
LIST_ENTRY ClosableFCBList;
|
|
BOOLEAN OnClosableFCBList;
|
|
}ClosableFCBs;
|
|
|
|
// some state information for the FCB is maintained using the
|
|
// flags field
|
|
uint32 FCBFlags;
|
|
// all CCB's for this particular FCB are linked off the following
|
|
// list head.
|
|
LIST_ENTRY CCBListHead;
|
|
// NT requires that a file system maintain and honor the various
|
|
// SHARE_ACCESS modes ...
|
|
SHARE_ACCESS FCBShareAccess;
|
|
// to identify the lazy writer thread(s) we will grab and store
|
|
// the thread id here when a request to acquire resource(s)
|
|
// arrives ..
|
|
uint32 LazyWriterThreadID;
|
|
// whenever a file stream has a create/open operation performed,
|
|
// the Reference count below is incremented AND the OpenHandle count
|
|
// below is also incremented.
|
|
// When an IRP_MJ_CLEANUP is received, the OpenHandle count below
|
|
// is decremented.
|
|
// When an IRP_MJ_CLOSE is received, the Reference count below is
|
|
// decremented.
|
|
// When the Reference count goes down to zero, the FCB can be de-allocated.
|
|
// Note that a zero Reference count implies a zero OpenHandle count.
|
|
// This invariant must always hold true ... (if it is really an invariant,
|
|
// shoudn't the previous statement be redundant ... hmmm!!!)
|
|
LONG ReferenceCount;
|
|
LONG OpenHandleCount;
|
|
// for the sample fsd, there exists a 1-1 correspondence between an
|
|
// object name structure and a FCB
|
|
PtrExt2ObjectName FCBName;
|
|
// we will maintain some time information here to make our life easier
|
|
LARGE_INTEGER CreationTime;
|
|
LARGE_INTEGER LastAccessTime;
|
|
LARGE_INTEGER LastWriteTime;
|
|
// Byte-range file lock support (we roll our own)
|
|
Ext2FileLockAnchor FCBByteRangeLock;
|
|
// The OPLOCK support package requires the following structure
|
|
OPLOCK FCBOplock;
|
|
|
|
// The I-Node no of this file / folder
|
|
ULONG INodeNo;
|
|
ULONG ParentINodeNo;
|
|
// Pointers to blocks
|
|
uint32 IBlock[EXT2_N_BLOCKS];
|
|
|
|
USHORT LinkCount;
|
|
union _DCBFCB
|
|
{
|
|
struct
|
|
{
|
|
PFILE_OBJECT PtrDirFileObject;
|
|
} Dcb;
|
|
|
|
struct _FCB
|
|
{
|
|
PFILE_OBJECT PtrDirFileObject;
|
|
// FCB specific stuff go here...
|
|
} Fcb;
|
|
|
|
}DcbFcb;
|
|
|
|
} Ext2FCB, *PtrExt2FCB, Ext2DCB, *PtrExt2DCB;
|
|
|
|
/**************************************************************************
|
|
the following FCBFlags values are relevant. These flag
|
|
values are bit fields; therefore we can test whether
|
|
a bit position is set (1) or not set (0).
|
|
**************************************************************************/
|
|
#define EXT2_FCB_IN_INIT (0x00000001)
|
|
#define EXT2_FCB_IN_TEARDOWN (0x00000002)
|
|
#define EXT2_FCB_PAGE_FILE (0x00000004)
|
|
#define EXT2_FCB_DIRECTORY (0x00000008)
|
|
#define EXT2_FCB_ROOT_DIRECTORY (0x00000018)
|
|
#define EXT2_FCB_WRITE_THROUGH (0x00000020)
|
|
#define EXT2_FCB_MAPPED (0x00000040)
|
|
#define EXT2_FCB_FAST_IO_READ_IN_PROGESS (0x00000080)
|
|
#define EXT2_FCB_FAST_IO_WRITE_IN_PROGESS (0x00000100)
|
|
#define EXT2_FCB_DELETE_ON_CLOSE (0x00000200)
|
|
#define EXT2_FCB_MODIFIED (0x00000400)
|
|
#define EXT2_FCB_ACCESSED (0x00000800)
|
|
#define EXT2_FCB_READ_ONLY (0x00001000)
|
|
|
|
#define EXT2_INITIALIZED_MAIN_RESOURCE (0x00002000)
|
|
#define EXT2_INITIALIZED_PAGING_IO_RESOURCE (0x00004000)
|
|
#define EXT2_FCB_BLOCKS_INITIALIZED (0x00008000)
|
|
#define EXT2_FCB_SPECIAL_FILE (0x00010000)
|
|
#define EXT2_FCB_HIDDEN_FILE (0x00020000)
|
|
#define EXT2_FCB_NOT_FROM_ZONE (0x80000000)
|
|
|
|
|
|
typedef struct _GroupDescriptors
|
|
{
|
|
uint32 InodeTablesBlock; /* Inodes table block => bg_inode_table */
|
|
uint32 InodeBitmapBlock; /* Inodes bitmap block => bg_inode_bitmap */
|
|
uint32 BlockBitmapBlock; /* Blocks bitmap block => bg_block_bitmap */
|
|
uint32 FreeBlocksCount;
|
|
uint32 FreeInodesCount;
|
|
}Ext2GroupDescriptors, *PtrExt2GroupDescriptors;
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
A logical volume is represented using the following structure.
|
|
This structure is allocated as part of the device extension
|
|
for a device object that this sample FSD will create, to represent
|
|
the mounted logical volume.
|
|
|
|
NOTE: If you were to extend this sample FSD to be a "real" FSD,
|
|
you would be worried about allocated clusters/sectiors,
|
|
bitmaps providing such information for the mounted volume,
|
|
dirty/modified clusters/sectiors etc.
|
|
This sample FSD does not maintain such information in the
|
|
in-memory VCB, though you may wish to consider it.
|
|
**************************************************************************/
|
|
typedef struct _Ext2VolumeControlBlock
|
|
{
|
|
Ext2Identifier NodeIdentifier;
|
|
|
|
// Required to use the Cache Manager.
|
|
FSRTL_COMMON_FCB_HEADER CommonVCBHeader;
|
|
SECTION_OBJECT_POINTERS SectionObject;
|
|
// a resource to protect the fields contained within the VCB
|
|
ERESOURCE VCBResource;
|
|
|
|
// a resource to synchronise paging io
|
|
ERESOURCE PagingIoResource;
|
|
|
|
// Pointer to a stream file object created for the volume information
|
|
// to be more easily read from secondary storage (with the support of
|
|
// the NT Cache Manager).
|
|
PFILE_OBJECT PtrStreamFileObject;
|
|
|
|
// each VCB is accessible off a global linked list
|
|
LIST_ENTRY NextVCB;
|
|
|
|
// each VCB points to a VPB structure created by the NT I/O Manager
|
|
PVPB PtrVPB;
|
|
|
|
// a set of flags that might mean something useful
|
|
uint32 VCBFlags;
|
|
|
|
// A count of the number of open files/directories
|
|
// As long as the count is != 0, the volume cannot
|
|
// be dismounted or locked.
|
|
uint32 VCBOpenCount;
|
|
|
|
// a global list of all FCB structures associated with the VCB
|
|
LIST_ENTRY FCBListHead;
|
|
|
|
//
|
|
// a list of FCBs created at the FSD's initiative...
|
|
// These FCBs have a reference count of 0
|
|
// This list should never be allowed to cross a limit...
|
|
//
|
|
struct Ext2ClosableFCB
|
|
{
|
|
LIST_ENTRY ClosableFCBListHead;
|
|
ULONG Count;
|
|
}ClosableFCBs;
|
|
// we will maintain a global list of IRP's that are pending
|
|
// because of a directory notify request.
|
|
LIST_ENTRY NextNotifyIRP;
|
|
// the above list is protected only by the mutex declared below
|
|
KMUTEX NotifyIRPMutex;
|
|
// for each mounted volume, we create a device object. Here then
|
|
// is a back pointer to that device object
|
|
PDEVICE_OBJECT VCBDeviceObject;
|
|
// We also retain a pointer to the physical device object on which we
|
|
// have mounted ourselves. The I/O Manager passes us a pointer to this
|
|
// device object when requesting a mount operation.
|
|
PDEVICE_OBJECT TargetDeviceObject;
|
|
// the volume structure contains a pointer to the root directory FCB
|
|
PtrExt2FCB PtrRootDirectoryFCB;
|
|
// the complete name of the user visible drive letter we serve
|
|
uint8 *PtrVolumePath;
|
|
// For volume open operations, we do not create a FCB (we use the VCB
|
|
// directly instead). Therefore, all CCB structures for the volume
|
|
// open operation are linked directly off the VCB
|
|
LIST_ENTRY VolumeOpenListHead;
|
|
|
|
|
|
// Volume information
|
|
ULONG BlocksCount;
|
|
ULONG InodesCount;
|
|
ULONG ReservedBlocksCount;
|
|
ULONG FreeBlocksCount;
|
|
ULONG FreeInodesCount;
|
|
ULONG LogBlockSize; // Block size = 1024 << LogBlockSize
|
|
ULONG InodeSize;
|
|
|
|
// Group Information Saved up in the VCB...
|
|
PtrExt2GroupDescriptors PtrGroupDescriptors;
|
|
ULONG NoOfGroups;
|
|
|
|
uint32 InodesPerGroup;
|
|
uint32 BlocksPerGroup;
|
|
|
|
} Ext2VCB, *PtrExt2VCB;
|
|
|
|
// some valid flags for the VCB
|
|
#define EXT2_VCB_FLAGS_VOLUME_MOUNTED (0x00000001)
|
|
#define EXT2_VCB_FLAGS_VOLUME_LOCKED (0x00000002)
|
|
#define EXT2_VCB_FLAGS_BEING_DISMOUNTED (0x00000004)
|
|
#define EXT2_VCB_FLAGS_SHUTDOWN (0x00000008)
|
|
#define EXT2_VCB_FLAGS_VOLUME_READ_ONLY (0x00000010)
|
|
|
|
#define EXT2_VCB_FLAGS_VCB_INITIALIZED (0x00000020)
|
|
|
|
typedef struct _EXT2_IO_CONTEXT
|
|
{
|
|
Ext2Identifier NodeIdentifier;
|
|
ULONG ReadWriteLength;
|
|
LONG Count;
|
|
PIRP PtrMasterIrp;
|
|
PKEVENT PtrSyncEvent;
|
|
|
|
} EXT2_IO_CONTEXT, *PEXT2_IO_CONTEXT;
|
|
|
|
|
|
typedef struct _Ext2SavedBCBs
|
|
{
|
|
Ext2Identifier NodeIdentifier;
|
|
PBCB PtrBCB;
|
|
LIST_ENTRY SavedBCBsListEntry;
|
|
|
|
} EXT2_SAVED_BCBS, *PEXT2_SAVED_BCBS;
|
|
|
|
|
|
/**************************************************************************
|
|
The IRP context encapsulates the current request. This structure is
|
|
used in the "common" dispatch routines invoked either directly in
|
|
the context of the original requestor, or indirectly in the context
|
|
of a system worker thread.
|
|
**************************************************************************/
|
|
typedef struct _Ext2IrpContext
|
|
{
|
|
Ext2Identifier NodeIdentifier;
|
|
uint32 IrpContextFlags;
|
|
// copied from the IRP
|
|
uint8 MajorFunction;
|
|
// copied from the IRP
|
|
uint8 MinorFunction;
|
|
|
|
// to queue this IRP for asynchronous processing
|
|
WORK_QUEUE_ITEM WorkQueueItem;
|
|
// the IRP for which this context structure was created
|
|
PIRP Irp;
|
|
// the target of the request (obtained from the IRP)
|
|
PDEVICE_OBJECT TargetDeviceObject;
|
|
// if an exception occurs, we will store the code here
|
|
NTSTATUS SavedExceptionCode;
|
|
|
|
// This list entry is used if asnchronous processing is required...
|
|
LIST_ENTRY ThreadQueueListEntry;
|
|
|
|
// This list entry is used if BCBs are to be saved and then flushed...
|
|
// Could have been put somewhere else...
|
|
LIST_ENTRY SavedBCBsListHead;
|
|
ULONG SavedCount;
|
|
|
|
} Ext2IrpContext, *PtrExt2IrpContext;
|
|
|
|
#define EXT2_IRP_CONTEXT_CAN_BLOCK (0x00000001)
|
|
#define EXT2_IRP_CONTEXT_WRITE_THROUGH (0x00000002)
|
|
#define EXT2_IRP_CONTEXT_EXCEPTION (0x00000004)
|
|
#define EXT2_IRP_CONTEXT_DEFERRED_WRITE (0x00000008)
|
|
#define EXT2_IRP_CONTEXT_ASYNC_PROCESSING (0x00000010)
|
|
#define EXT2_IRP_CONTEXT_NOT_TOP_LEVEL (0x00000020)
|
|
|
|
#define EXT2_IRP_CONTEXT_NOT_FROM_ZONE (0x80000000)
|
|
|
|
typedef struct _Ext2ThreadQueue
|
|
{
|
|
HANDLE QueueHandlerThread;
|
|
|
|
LIST_ENTRY ThreadQueueListHead; // This holds the Contexts
|
|
// that are to be scheduled
|
|
KSPIN_LOCK SpinLock; // To synchronize access to
|
|
// the list
|
|
KEVENT QueueEvent; // The Worker thread queue
|
|
// package waits on this event
|
|
} Ext2ThreadQueue;
|
|
|
|
/**************************************************************************
|
|
we will store all of our global variables in one structure.
|
|
Global variables are not specific to any mounted volume BUT
|
|
by definition are required for successful operation of the
|
|
FSD implementation.
|
|
**************************************************************************/
|
|
typedef struct _Ext2Data
|
|
{
|
|
Ext2Identifier NodeIdentifier;
|
|
// the fields in this list are protected by the following resource
|
|
ERESOURCE GlobalDataResource;
|
|
// each driver has a driver object created for it by the NT I/O Mgr.
|
|
// we are no exception to this rule.
|
|
PDRIVER_OBJECT Ext2DriverObject;
|
|
// we will create a device object for our FSD as well ...
|
|
// Although not really required, it helps if a helper application
|
|
// writen by us wishes to send us control information via
|
|
// IOCTL requests ...
|
|
PDEVICE_OBJECT Ext2DeviceObject;
|
|
// we will keep a list of all logical volumes for our sample FSD
|
|
LIST_ENTRY NextVCB;
|
|
// the NT Cache Manager, the I/O Manager and we will conspire
|
|
// to bypass IRP usage using the function pointers contained
|
|
// in the following structure
|
|
FAST_IO_DISPATCH Ext2FastIoDispatch;
|
|
// The NT Cache Manager uses the following call backs to ensure
|
|
// correct locking hierarchy is maintained
|
|
CACHE_MANAGER_CALLBACKS CacheMgrCallBacks;
|
|
// structures allocated from a zone need some fields here. Note
|
|
// that under version 4.0, it might be better to use lookaside
|
|
// lists
|
|
KSPIN_LOCK ZoneAllocationSpinLock;
|
|
ZONE_HEADER ObjectNameZoneHeader;
|
|
ZONE_HEADER CCBZoneHeader;
|
|
ZONE_HEADER FCBZoneHeader;
|
|
ZONE_HEADER ByteLockZoneHeader;
|
|
ZONE_HEADER IrpContextZoneHeader;
|
|
void *ObjectNameZone;
|
|
void *CCBZone;
|
|
void *FCBZone;
|
|
void *ByteLockZone;
|
|
void *IrpContextZone;
|
|
|
|
// currently, there is a single default zone size value used for
|
|
// all zones. This should ideally be changed by you to be 1 per
|
|
// type of zone (e.g. a default size for the FCB zone might be
|
|
// different from the default size for the ByteLock zone).
|
|
|
|
// Of course, you will need to use different values (min/max)
|
|
// for lookaside lists (if you decide to use them instead)
|
|
uint32 DefaultZoneSizeInNumStructs;
|
|
|
|
// some state information is maintained in the flags field
|
|
uint32 Ext2Flags;
|
|
|
|
// Handle returned by the MUP is stored here.
|
|
HANDLE MupHandle;
|
|
|
|
// Time difference
|
|
LARGE_INTEGER TimeDiff;
|
|
|
|
// The Worker Thread package uses this structure...
|
|
Ext2ThreadQueue ThreadQueue;
|
|
|
|
}Ext2Data, *PtrExt2Data;
|
|
|
|
// valid flag values for the global data structure
|
|
#define EXT2_DATA_FLAGS_RESOURCE_INITIALIZED (0x00000001)
|
|
#define EXT2_DATA_FLAGS_ZONES_INITIALIZED (0x00000002)
|
|
|
|
// a default size of the number of pages of non-paged pool allocated
|
|
// for each of the zones ...
|
|
|
|
// Note that the values are absolutely arbitrary, the only information
|
|
// worth using from the values themselves is that they increase for
|
|
// larger systems (i.e. systems with more memory)
|
|
#define EXT2_DEFAULT_ZONE_SIZE_SMALL_SYSTEM (0x4)
|
|
#define EXT2_DEFAULT_ZONE_SIZE_MEDIUM_SYSTEM (0x8)
|
|
#define EXT2_DEFAULT_ZONE_SIZE_LARGE_SYSTEM (0xc)
|
|
|
|
// another simplistic (brain dead ? :-) method used is to simply double
|
|
// the values for a "server" machine
|
|
|
|
// So, for all you guys who "modified" the registry ;-) to change the
|
|
// wkstation into a server, tough luck !
|
|
#define EXT2_NTAS_MULTIPLE (0x2)
|
|
|
|
/***************************************************************************
|
|
The following locking hierarchy is maintained in this sample filesystem
|
|
driver:
|
|
|
|
(a) the global structure resource can be acquired at any time. However,
|
|
it is an "end resource" i.e. once acquired, no other resource can
|
|
be obtained until the global structure resource is released.
|
|
(b) the logical volume resource must be acquired (if required) before
|
|
any of the other resources are acquired.
|
|
(c) a file control block can be acquired next (if required). If two
|
|
FCB structures need to be acquired, the FCB "higher" in the directory
|
|
tree must be acquired first.
|
|
For a FCB, the "main resource" must be acquired first before a
|
|
"paging i/o" resource is acquired.
|
|
|
|
Whenever a file is opened, the logical volume structure is referenced.
|
|
This ensures that the volume cannot be dismounted while any file is open.
|
|
|
|
***************************************************************************/
|
|
|
|
typedef struct _IO_RUN
|
|
{
|
|
UINT LogicalBlock;
|
|
UINT StartOffset;
|
|
UINT EndOffset;
|
|
PIRP PtrAssociatedIrp;
|
|
|
|
} EXT2_IO_RUN, *PEXT2_IO_RUN;
|
|
|
|
typedef struct _SIBlocks
|
|
{
|
|
PBCB PtrBCB;
|
|
ULONG * PtrSIBlocks;
|
|
} EXT2_SIBLOCKS, *PEXT2_SIBLOCKS;
|
|
|
|
#endif // has this file been included?
|
|
|