⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ffsdrv.h

📁 FSD file system driver
💻 H
📖 第 1 页 / 共 3 页
字号:
/* 
 * FFS File System Driver for Windows
 *
 * ffsdrv.h
 *
 * 2004.5.6 ~
 *
 * Lee Jae-Hong, http://www.pyrasis.com
 *
 */

#ifndef _FFS_HEADER_
#define _FFS_HEADER_

/* include files */
#include "fs.h"
#include "dinode.h"
#include "dir.h"
#include "disklabel.h"
#include <ntdddisk.h>

#pragma pack(1)

/* debug */
#if DBG
	#define FFSBreakPoint()    __asm int 3 //DbgBreakPoint()
#else
	#define FFSBreakPoint()
#endif

/* Structs & Consts */

#define FFSDRV_VERSION  "0.5"

/*
 * ffsdrv build options
 */

/* To build read-only driver */

#define FFS_READ_ONLY  TRUE


/* To support driver dynamics unload */

#define FFS_UNLOAD     TRUE

/*
 * Constants
 */

#define FFS_BLOCK_TYPES                 (0x04)

#define MAXIMUM_RECORD_LENGTH           (0x10000)

#define SECTOR_BITS                     (Vcb->SectorBits)
#define SECTOR_SIZE                     (Vcb->DiskGeometry.BytesPerSector)
#define DEFAULT_SECTOR_SIZE             (0x200)

#define SUPER_BLOCK_OFFSET              (0x2000)
#define SUPER_BLOCK_SIZE                SBLOCKSIZE

#define READ_AHEAD_GRANULARITY          (0x10000)

#define SUPER_BLOCK                     (Vcb->ffs_super_block)
#define FS_VERSION                      (Vcb->FSVersion)

#define BLOCK_SIZE                      (Vcb->BlockSize)
#define BLOCK_BITS                      FFSLog2(Vcb->BlockSize)

#define INODES_COUNT                    (Vcb->ffs_super_block->s_inodes_count)

#define INODES_PER_GROUP                (SUPER_BLOCK->fs_ipg)
#define BLOCKS_PER_GROUP                (SUPER_BLOCK->fs_fpg)
#define TOTAL_BLOCKS                    (SUPER_BLOCK->fs_size)



/* File System Releated */

#define DRIVER_NAME     "FFS"
#define DEVICE_NAME     L"\\FileSystem\\FFS"

/* Registry */

#define PARAMETERS_KEY    L"\\Parameters"

#define WRITING_SUPPORT     L"WritingSupport"
#define CHECKING_BITMAP     L"CheckingBitmap"
#define PARTITION_NUMBER    L"PartitionNumber"

/* To support select BSD partition and ffsdrv unload routine */
#define DOS_DEVICE_NAME L"\\DosDevices\\ffs"

/*
 * Private IOCTL to make the driver ready to unload
 */
#if FFS_UNLOAD
#define IOCTL_PREPARE_TO_UNLOAD \
CTL_CODE(FILE_DEVICE_UNKNOWN, 2048, METHOD_NEITHER, FILE_WRITE_ACCESS)
#endif // FFS_UNLOAD

/*
 * Private IOCTL to select BSD partition.
 */
#define IOCTL_SELECT_BSD_PARTITION \
CTL_CODE(FILE_DEVICE_UNKNOWN, 2049, METHOD_BUFFERED, FILE_WRITE_ACCESS)


#ifndef SetFlag
#define SetFlag(x,f)    ((x) |= (f))
#endif

#ifndef ClearFlag
#define ClearFlag(x,f)  ((x) &= ~(f))
#endif

#define IsFlagOn(a,b) ((BOOLEAN)(FlagOn(a,b) == b))

#define FFSRaiseStatus(IRPCONTEXT,STATUS) {  \
	(IRPCONTEXT)->ExceptionCode = (STATUS); \
	ExRaiseStatus( (STATUS) );                \
}

#define FFSNormalizeAndRaiseStatus(IRPCONTEXT,STATUS) {                        \
	/* (IRPCONTEXT)->ExceptionStatus = (STATUS);  */                            \
	if ((STATUS) == STATUS_VERIFY_REQUIRED) { ExRaiseStatus((STATUS)); }        \
	ExRaiseStatus(FsRtlNormalizeNtstatus((STATUS),STATUS_UNEXPECTED_IO_ERROR)); \
}

/*
 * Define IsEndofFile for read and write operations
 */

#define FILE_WRITE_TO_END_OF_FILE       0xffffffff
#define FILE_USE_FILE_POINTER_POSITION  0xfffffffe

#define IsEndOfFile(Pos) ((Pos.LowPart == FILE_WRITE_TO_END_OF_FILE) && \
                          (Pos.HighPart == FILE_USE_FILE_POINTER_POSITION ))

#define IsDirectory(Fcb) IsFlagOn(Fcb->FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)

/*
 * Bug Check Codes Definitions
 */

#define FFS_FILE_SYSTEM   (FILE_SYSTEM)

#define FFS_BUGCHK_BLOCK               (0x00010000)
#define FFS_BUGCHK_CLEANUP             (0x00020000)
#define FFS_BUGCHK_CLOSE               (0x00030000)
#define FFS_BUGCHK_CMCB                (0x00040000)
#define FFS_BUGCHK_CREATE              (0x00050000)
#define FFS_BUGCHK_DEBUG               (0x00060000)
#define FFS_BUGCHK_DEVCTL              (0x00070000)
#define FFS_BUGCHK_DIRCTL              (0x00080000)
#define FFS_BUGCHK_DISPATCH            (0x00090000)
#define FFS_BUGCHK_EXCEPT              (0x000A0000)
#define FFS_BUGCHK_FFS                 (0x000B0000)
#define FFS_BUGCHK_FASTIO              (0x000C0000)
#define FFS_BUGCHK_FILEINFO            (0x000D0000)
#define FFS_BUGCHK_FLUSH               (0x000E0000)
#define FFS_BUGCHK_FSCTL               (0x000F0000)
#define FFS_BUGCHK_INIT                (0x00100000)
#define FFS_BUGCHK_LOCK                (0x0011000)
#define FFS_BUGCHK_MEMORY              (0x0012000)
#define FFS_BUGCHK_MISC                (0x0013000)
#define FFS_BUGCHK_READ                (0x00140000)
#define FFS_BUGCHK_SHUTDOWN            (0x00150000)
#define FFS_BUGCHK_VOLINFO             (0x00160000)
#define FFS_BUGCHK_WRITE               (0x00170000)

#define FFS_BUGCHK_LAST                (0x00170000)

#define FFSBugCheck(A,B,C,D) { KeBugCheckEx(FFS_FILE_SYSTEM, A | __LINE__, B, C, D ); }


/* FFS file system definions */

/*
 * Structure of a directory entry
 */
#define FFS_NAME_LEN 255

#define FFS_ROOT_INO           2   /* Root inode */


/*
 * FFS_DIR_PAD defines the directory entries boundaries
 *
 * NOTE: It must be a multiple of 4
 */
#define FFS_DIR_PAD		 	4
#define FFS_DIR_ROUND 			(FFS_DIR_PAD - 1)
#define FFS_DIR_REC_LEN(name_len)	(((name_len) + 8 + FFS_DIR_ROUND) & \
					 ~FFS_DIR_ROUND)


/* sys/sys/stat.h */

#define	S_ISDIR(m)  ((m & _S_IFMT) == _S_IFDIR)         /* directory */
#define	S_ISCHR(m)  ((m & _S_IFMT) == _S_IFCHR)         /* char special */
#define	S_ISBLK(m)  ((m & _S_IFMT) == _S_IFBLK)         /* block special */
#define	S_ISREG(m)  ((m & _S_IFMT) == _S_IFREG)         /* regular file */
#define	S_ISFIFO(m) ((m & _S_IFMT) == _S_IFIFO)         /* fifo */
#define	S_ISLNK(m)  ((m & _S_IFMT) == _S_IFLNK)         /* symbolic link */
#define	S_ISSOCK(m) ((m & _S_IFMT) == _S_IFSOCK)        /* socket */
#define	S_ISWHT(m)  ((m & _S_IFMT) == _S_IFWHT)         /* whiteout */


#define S_IPERMISSION_MASK 0x1FF /*  */

#define	S_IRWXU	0000700         /* RWX mask for owner */
#define	S_IRUSR	0000400         /* R for owner */
#define	S_IWUSR	0000200         /* W for owner */
#define	S_IXUSR	0000100         /* X for owner */

#define	S_IRWXG	0000070         /* RWX mask for group */
#define	S_IRGRP	0000040         /* R for group */
#define	S_IWGRP	0000020         /* W for group */
#define	S_IXGRP	0000010         /* X for group */

#define	S_IRWXO	0000007         /* RWX mask for other */
#define	S_IROTH	0000004         /* R for other */
#define	S_IWOTH	0000002         /* W for other */
#define	S_IXOTH	0000001         /* X for other */

#define S_ISREADABLE(m)    (((m) & S_IPERMISSION_MASK) == (S_IRUSR | S_IRGRP | S_IROTH))
#define S_ISWRITABLE(m)    (((m) & S_IPERMISSION_MASK) == (S_IWUSR | S_IWGRP | S_IWOTH))

#define FFSSetReadable(m) (m) = ((m) | (S_IRUSR | S_IRGRP | S_IROTH))
#define FFSSetWritable(m) (m) = ((m) | (S_IWUSR | S_IWGRP | S_IWOTH))

#define FFSSetReadOnly(m) (m) = ((m) & (~(S_IWUSR | S_IWGRP | S_IWOTH)))
#define FFSIsReadOnly(m)  (!((m) & (S_IWUSR | S_IWGRP | S_IWOTH)))

#define FFS_FIRST_DATA_BLOCK   (Vcb->ffs_super_block->fs_dblkno)

typedef struct fs FFS_SUPER_BLOCK, *PFFS_SUPER_BLOCK;

typedef struct disklabel DISKLABEL, *PDISKLABEL;

typedef struct ufs1_dinode FFSv1_INODE, *PFFSv1_INODE;
typedef struct ufs2_dinode FFSv2_INODE, *PFFSv2_INODE;

typedef struct direct FFS_DIR_ENTRY, *PFFS_DIR_ENTRY;


/*
 * ffsdrv Driver Definitions
 */

/*
 * FFS_IDENTIFIER_TYPE
 *
 * Identifiers used to mark the structures
 */

typedef enum _FFS_IDENTIFIER_TYPE {
	FFSFGD  = ':DGF',
	FFSVCB  = ':BCV',
	FFSFCB  = ':BCF',
	FFSCCB  = ':BCC',
	FFSICX  = ':XCI',
	FFSDRV  = ':VRD',
	FFSMCB  = ':BCM'
} FFS_IDENTIFIER_TYPE;

/*
 * FFS_IDENTIFIER
 *
 * Header used to mark the structures
 */
typedef struct _FFS_IDENTIFIER {
	FFS_IDENTIFIER_TYPE      Type;
	ULONG                    Size;
} FFS_IDENTIFIER, *PFFS_IDENTIFIER;


#define NodeType(Ptr) (*((FFS_IDENTIFIER_TYPE *)(Ptr)))

typedef struct _FFS_MCB  FFS_MCB, *PFFS_MCB;


typedef PVOID   PBCB;

/*
 * REPINNED_BCBS List
 */

#define FFS_REPINNED_BCBS_ARRAY_SIZE         (8)

typedef struct _FFS_REPINNED_BCBS {

	//
	//  A pointer to the next structure contains additional repinned bcbs
	//

	struct _FFS_REPINNED_BCBS *Next;

	//
	//  A fixed size array of pinned bcbs.  Whenever a new bcb is added to
	//  the repinned bcb structure it is added to this array.  If the
	//  array is already full then another repinned bcb structure is allocated
	//  and pointed to with Next.
	//

	PBCB Bcb[ FFS_REPINNED_BCBS_ARRAY_SIZE ];

} FFS_REPINNED_BCBS, *PFFS_REPINNED_BCBS;


/*
 * FFS_BSD_PARTITION
 */
typedef struct _FFS_BSD_PARTITION
{
	ULONG Number;
} FFS_BSD_PARTITION, *PFFS_BSD_PARTITION;


/*
 * FFS_GLOBAL_DATA
 *
 * Data that is not specific to a mounted volume
 */
typedef struct _FFS_GLOBAL {

	// Identifier for this structure
	FFS_IDENTIFIER              Identifier;

	// Syncronization primitive for this structure
	ERESOURCE                   Resource;

	// Syncronization primitive for Counting
	ERESOURCE                   CountResource;

	// Syncronization primitive for LookAside Lists
	ERESOURCE                   LAResource;

	// Table of pointers to the fast I/O entry points
	FAST_IO_DISPATCH            FastIoDispatch;

	// Table of pointers to the Cache Manager callbacks
	CACHE_MANAGER_CALLBACKS     CacheManagerCallbacks;
	CACHE_MANAGER_CALLBACKS     CacheManagerNoOpCallbacks;

	// Pointer to the driver object
	PDRIVER_OBJECT              DriverObject;

	// Pointer to the main device object
	PDEVICE_OBJECT              DeviceObject;

	// List of mounted volumes
	LIST_ENTRY                  VcbList;

	// Look Aside table of IRP_CONTEXT, FCB, MCB, CCB
	USHORT                      MaxDepth;
	NPAGED_LOOKASIDE_LIST       FFSIrpContextLookasideList;
	NPAGED_LOOKASIDE_LIST       FFSFcbLookasideList;
	NPAGED_LOOKASIDE_LIST       FFSCcbLookasideList;
	PAGED_LOOKASIDE_LIST        FFSMcbLookasideList;

	// Mcb Count ...
	USHORT                      McbAllocated;

#if DBG
	// Fcb Count
	USHORT                      FcbAllocated;

	// IRP_MJ_CLOSE : FCB
	USHORT                      IRPCloseCount;
#endif

	// Global flags for the driver
	ULONG                       Flags;

	ULONGLONG                   FSOffset[MAXPARTITIONS];

	ULONG                       RootPartition;

	ULONG                       PartitionNumber;

} FFS_GLOBAL, *PFFS_GLOBAL;

/*
 * Flags for FFS_GLOBAL_DATA
 */
#define FFS_UNLOAD_PENDING     0x00000001
#define FFS_SUPPORT_WRITING    0x00000002
#define FFS_CHECKING_BITMAP    0x00000008

/*
 * Driver Extension define
 */
typedef struct {
	FFS_GLOBAL FFSGlobal;
} FFS_EXT, *PFFS_EXT;


typedef struct _FFS_FCBVCB {

	// FCB header required by NT
	FSRTL_COMMON_FCB_HEADER         CommonFCBHeader;
	SECTION_OBJECT_POINTERS         SectionObject;
	ERESOURCE                       MainResource;
	ERESOURCE                       PagingIoResource;
	// end FCB header required by NT

	// Identifier for this structure
	FFS_IDENTIFIER                  Identifier;
} FFS_FCBVCB, *PFFS_FCBVCB;

/*
 * FFS_VCB Volume Control Block
 *
 * Data that represents a mounted logical volume
 * It is allocated as the device extension of the volume device object
 */
typedef struct _FFS_VCB {

	// FCB header required by NT
	// The VCB is also used as an FCB for file objects
	// that represents the volume itself
	FSRTL_COMMON_FCB_HEADER     Header;
	SECTION_OBJECT_POINTERS     SectionObject;
	ERESOURCE                   MainResource;
	ERESOURCE                   PagingIoResource;
	// end FCB header required by NT

	// Identifier for this structure
	FFS_IDENTIFIER              Identifier;

	LIST_ENTRY                  Next;

	// Share Access for the file object
	SHARE_ACCESS                ShareAccess;

	// Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP
	// for files on this volume.
	ULONG                       OpenFileHandleCount;

	// Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLOSE
	// for both files on this volume and open instances of the
	// volume itself.
	ULONG                       ReferenceCount;
	ULONG                       OpenHandleCount;

	//
	// Disk change count
	//

	ULONG                       ChangeCount;

	// Pointer to the VPB in the target device object
	PVPB                        Vpb;

	// The FileObject of Volume used to lock the volume
	PFILE_OBJECT                LockFile;

	// List of FCBs for open files on this volume
	LIST_ENTRY                  FcbList;

	// List of IRPs pending on directory change notify requests
	LIST_ENTRY                  NotifyList;

	// Pointer to syncronization primitive for this list
	PNOTIFY_SYNC                NotifySync;

	// This volumes device object
	PDEVICE_OBJECT              DeviceObject;

	// The physical device object (the disk)
	PDEVICE_OBJECT              TargetDeviceObject;

	// The physical device object (the disk)
	PDEVICE_OBJECT              RealDevice;

	// Information about the physical device object
	DISK_GEOMETRY               DiskGeometry;
	PARTITION_INFORMATION       PartitionInformation;

	// File System Super Block
	PFFS_SUPER_BLOCK            ffs_super_block;

	// File System version
	ULONG                       FSVersion;

	// Number of Group Decsciptions
	ULONG                       ffs_groups;
	/*
	// Bitmap Block per group
	PRTL_BITMAP                 BlockBitMaps;
	PRTL_BITMAP                 InodeBitMaps;
	*/
	// Block / Cluster size
	ULONG                       BlockSize;

	// Sector size in bits
	ULONG                       SectorBits;

	ULONG                       dwData[FFS_BLOCK_TYPES];
	ULONG                       dwMeta[FFS_BLOCK_TYPES];

	// Flags for the volume
	ULONG                       Flags;

	// Streaming File Object
	PFILE_OBJECT                StreamObj;

	// Resource Lock for Mcb
	ERESOURCE                   McbResource;

	// Dirty Mcbs of modifications for volume stream
	LARGE_MCB                   DirtyMcbs;

	// Entry of Mcb Tree (Root Node)
	PFFS_MCB                    McbTree;
	LIST_ENTRY                  McbList;

} FFS_VCB, *PFFS_VCB;

/*
 * Flags for FFS_VCB
 */
#define VCB_INITIALIZED         0x00000001
#define VCB_VOLUME_LOCKED       0x00000002
#define VCB_MOUNTED             0x00000004
#define VCB_DISMOUNT_PENDING    0x00000008
#define VCB_READ_ONLY           0x00000010

#define VCB_WRITE_PROTECTED     0x10000000
#define VCB_FLOPPY_DISK         0x20000000
#define VCB_REMOVAL_PREVENTED   0x40000000
#define VCB_REMOVABLE_MEDIA     0x80000000


#define IsMounted(Vcb)    (IsFlagOn(Vcb->Flags, VCB_MOUNTED))


/*
 * FFS_FCB File Control Block
 *
 * Data that represents an open file
 * There is a single instance of the FCB for every open file
 */
typedef struct _FFS_FCB {

	// FCB header required by NT
	FSRTL_COMMON_FCB_HEADER         Header;
	SECTION_OBJECT_POINTERS         SectionObject;
	ERESOURCE                       MainResource;
	ERESOURCE                       PagingIoResource;
	// end FCB header required by NT

	// Identifier for this structure
	FFS_IDENTIFIER                  Identifier;

	// List of FCBs for this volume
	LIST_ENTRY                      Next;

	// Share Access for the file object
	SHARE_ACCESS                    ShareAccess;

	// List of byte-range locks for this file
	FILE_LOCK                       FileLockAnchor;

	// Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP
	ULONG                           OpenHandleCount;

	// Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLOSE
	ULONG                           ReferenceCount;

	// Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP
	// But only for Files with FO_NO_INTERMEDIATE_BUFFERING flag
	ULONG                           NonCachedOpenCount;

	// Flags for the FCB
	ULONG                           Flags;

	// Pointer to the inode
	PFFSv1_INODE                    dinode1;
	PFFSv2_INODE                    dinode2;

	// Hint block for next allocation
	ULONG                           BlkHint;

	// Vcb

	PFFS_VCB                        Vcb;

	// Mcb Node ...
	PFFS_MCB                        FFSMcb;

	// Full Path Name
	UNICODE_STRING                  LongName;

#if DBG
	// The Ansi Filename for debugging
	OEM_STRING                      AnsiFileName;   
#endif


} FFS_FCB, *PFFS_FCB;


//
// Flags for FFS_FCB
//
#define FCB_FROM_POOL               0x00000001
#define FCB_PAGE_FILE               0x00000002
#define FCB_DELETE_ON_CLOSE         0x00000004
#define FCB_DELETE_PENDING          0x00000008
#define FCB_FILE_DELETED            0x00000010
#define FCB_FILE_MODIFIED           0x00000020

// Mcb Node

struct _FFS_MCB {

	// Identifier for this structure
	FFS_IDENTIFIER                  Identifier;

	// Flags
	ULONG                           Flags;

	// Link List Info

	PFFS_MCB                        Parent; // Parent
	PFFS_MCB                        Child;  // Children
	PFFS_MCB                        Next;   // Brothers

	// Mcb Node Info

	// -> Fcb
	PFFS_FCB                        FFSFcb;

	// Short name
	UNICODE_STRING                  ShortName;

	// Inode number
	ULONG                           Inode;

	// Dir entry offset in parent
	ULONG                           DeOffset;

	// File attribute
	ULONG                           FileAttr;

	// List Link to Vcb->McbList
	LIST_ENTRY                      Link;
};

/*
 * Flags for MCB
 */
#define MCB_FROM_POOL               0x00000001
#define MCB_IN_TREE                 0x00000002
#define MCB_IN_USE                  0x00000004

#define IsMcbUsed(Mcb) IsFlagOn(Mcb->Flags, MCB_IN_USE)


/*
 * FFS_CCB Context Control Block
 *
 * Data that represents one instance of an open file
 * There is one instance of the CCB for every instance of an open file
 */
typedef struct _FFS_CCB {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -