Alex Vlasov

- Move and rewrite FAT in-memory structures to fatstruc.h.
- Remove PACKED_LFN_ENTRY structure.
- Add declarations of VCB functions (init, uninit), and FAT scanning.

svn path=/trunk/; revision=39030
This commit is contained in:
Aleksey Bragin 2009-01-23 09:49:45 +00:00
parent 093e6f6d3c
commit 06abfd926c
4 changed files with 224 additions and 237 deletions

View file

@ -84,7 +84,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
NULL,
NULL,
0,
sizeof(VFATFCB),
sizeof(FCB),
TAG_FCB,
0);

View file

@ -2,189 +2,11 @@
#include <ntdddisk.h>
#include <reactos/helper.h>
#include <debug.h>
/* FAT on-disk data structures */
#include <fat.h>
#include <fatstruc.h>
/* File system types */
#define FAT16 (1)
#define FAT12 (2)
#define FAT32 (3)
#define FATX16 (4)
#define FATX32 (5)
/* VCB Flags */
#define VCB_VOLUME_LOCKED 0x0001
#define VCB_DISMOUNT_PENDING 0x0002
#define VCB_IS_FATX 0x0004
#define VCB_IS_DIRTY 0x4000 /* Volume is dirty */
#define VCB_CLEAR_DIRTY 0x8000 /* Clean dirty flag at shutdown */
typedef struct
{
ULONG VolumeID;
ULONG FATStart;
ULONG FATCount;
ULONG FATSectors;
ULONG rootDirectorySectors;
ULONG rootStart;
ULONG dataStart;
ULONG RootCluster;
ULONG SectorsPerCluster;
ULONG BytesPerSector;
ULONG BytesPerCluster;
ULONG NumberOfClusters;
ULONG FatType;
ULONG Sectors;
BOOLEAN FixedMedia;
} FATINFO, *PFATINFO;
struct _VFATFCB;
struct _VFAT_DIRENTRY_CONTEXT;
typedef struct DEVICE_EXTENSION *PDEVICE_EXTENSION;
typedef struct _DEVICE_EXTENSION
{
ERESOURCE DirResource;
ERESOURCE FatResource;
KSPIN_LOCK FcbListLock;
LIST_ENTRY FcbListHead;
ULONG HashTableSize;
struct _HASHENTRY** FcbHashTable;
PDEVICE_OBJECT StorageDevice;
PFILE_OBJECT FATFileObject;
FATINFO FatInfo;
ULONG LastAvailableCluster;
ULONG AvailableClusters;
BOOLEAN AvailableClustersValid;
ULONG Flags;
struct _VFATFCB * VolumeFcb;
ULONG BaseDateYear;
LIST_ENTRY VolumeListEntry;
} DEVICE_EXTENSION;
typedef struct _FAT_GLOBAL_DATA
{
ERESOURCE Resource;
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT DiskDeviceObject;
NPAGED_LOOKASIDE_LIST NonPagedFcbList;
NPAGED_LOOKASIDE_LIST ResourceList;
NPAGED_LOOKASIDE_LIST IrpContextList;
FAST_IO_DISPATCH FastIoDispatch;
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks;
CACHE_MANAGER_CALLBACKS CacheMgrNoopCallbacks;
} FAT_GLOBAL_DATA, *VFAT_GLOBAL_DATA;
extern FAT_GLOBAL_DATA FatGlobalData;
/* FCB flags */
#define FCB_CACHE_INITIALIZED 0x0001
#define FCB_DELETE_PENDING 0x0002
#define FCB_IS_FAT 0x0004
#define FCB_IS_PAGE_FILE 0x0008
#define FCB_IS_VOLUME 0x0010
#define FCB_IS_DIRTY 0x0020
#define FCB_IS_FATX_ENTRY 0x0040
typedef struct _VFATFCB
{
/* FCB header required by ROS/NT */
FSRTL_COMMON_FCB_HEADER RFCB;
SECTION_OBJECT_POINTERS SectionObjectPointers;
ERESOURCE MainResource;
ERESOURCE PagingIoResource;
/* end FCB header required by ROS/NT */
/* Pointer to attributes in entry */
PUCHAR Attributes;
/* long file name, points into PathNameBuffer */
UNICODE_STRING LongNameU;
/* short file name */
UNICODE_STRING ShortNameU;
/* directory name, points into PathNameBuffer */
UNICODE_STRING DirNameU;
/* path + long file name 260 max*/
UNICODE_STRING PathNameU;
/* buffer for PathNameU */
PWCHAR PathNameBuffer;
/* buffer for ShortNameU */
WCHAR ShortNameBuffer[13];
/* */
LONG RefCount;
/* List of FCB's for this volume */
LIST_ENTRY FcbListEntry;
/* pointer to the parent fcb */
struct _VFATFCB* parentFcb;
/* Flags for the fcb */
ULONG Flags;
/* pointer to the file object which has initialized the fcb */
PFILE_OBJECT FileObject;
/* Directory index for the short name entry */
ULONG dirIndex;
/* Directory index where the long name starts */
ULONG startIndex;
/* Share access for the file object */
SHARE_ACCESS FCBShareAccess;
/* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP */
ULONG OpenHandleCount;
/* List of byte-range locks for this file */
FILE_LOCK FileLock;
/*
* Optimalization: caching of last read/write cluster+offset pair. Can't
* be in VFATCCB because it must be reset everytime the allocated clusters
* change.
*/
FAST_MUTEX LastMutex;
ULONG LastCluster;
ULONG LastOffset;
} VFATFCB, *PVFATFCB;
typedef struct _VFATCCB
{
LARGE_INTEGER CurrentByteOffset;
/* for DirectoryControl */
ULONG Entry;
/* for DirectoryControl */
UNICODE_STRING SearchPattern;
} VFATCCB, *PVFATCCB;
/* Volume Control Block */
typedef struct _VCB
{
FSRTL_ADVANCED_FCB_HEADER VolumeFileHeader;
} VCB, *PVCB;
/* Volume Device Object */
typedef struct _VOLUME_DEVICE_OBJECT
{
DEVICE_OBJECT DeviceObject;
FSRTL_COMMON_FCB_HEADER VolumeHeader;
VCB Vcb; /* Must be the last entry! */
} VOLUME_DEVICE_OBJECT, *PVOLUME_DEVICE_OBJECT;
#define Add2Ptr(P,I,T) ((T)((PUCHAR)(P) + (I)))
#define PtrOffset(B,O) ((ULONG)((ULONG_PTR)(O) - (ULONG_PTR)(B)))
#ifndef TAG
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
@ -194,50 +16,6 @@ typedef struct _VOLUME_DEVICE_OBJECT
#define TAG_FCB TAG('V', 'F', 'C', 'B')
#define TAG_IRP TAG('V', 'I', 'R', 'P')
#define TAG_VFAT TAG('V', 'F', 'A', 'T')
typedef struct __DOSTIME
{
USHORT Second:5;
USHORT Minute:6;
USHORT Hour:5;
}
DOSTIME, *PDOSTIME;
typedef struct __DOSDATE
{
USHORT Day:5;
USHORT Month:4;
USHORT Year:5;
}
DOSDATE, *PDOSDATE;
#define IRPCONTEXT_CANWAIT 0x0001
#define IRPCONTEXT_PENDINGRETURNED 0x0002
#define IRPCONTEXT_STACK_IO_CONTEXT 0x0004
typedef struct _FAT_IRP_CONTEXT
{
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
UCHAR MajorFunction;
UCHAR MinorFunction;
PFILE_OBJECT FileObject;
ULONG Flags;
PVCB Vcb;
ULONG PinCount;
struct _FAT_IO_CONTEXT *FatIoContext;
PDEVICE_EXTENSION DeviceExt;
WORK_QUEUE_ITEM WorkQueueItem;
PIO_STACK_LOCATION Stack;
KEVENT Event;
} FAT_IRP_CONTEXT, *PFAT_IRP_CONTEXT;
typedef struct _FAT_IO_CONTEXT
{
PMDL ZeroMdl;
} _FAT_IO_CONTEXT, *PFAT_IO_CONTEXT;
/* ------------------------------------------------------ shutdown.c */
DRIVER_DISPATCH FatShutdown;
@ -337,6 +115,24 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
/* ----------------------------------------------------------- fat.c */
NTSTATUS
FatInitializeVcb(
IN PVCB Vcb,
IN PDEVICE_OBJECT TargetDeviceObject,
IN PVPB Vpb);
VOID
FatUninitializeVcb(
IN PVCB Vcb);
ULONG
FatScanFat(
IN PFCB Fcb,
IN LONGLONG Vbo, OUT PLONGLONG Lbo,
IN OUT PLONGLONG Length,
OUT PULONG Index,
IN BOOLEAN CanWait);
/* ------------------------------------------------------ device.c */
NTSTATUS NTAPI

View file

@ -283,15 +283,4 @@ typedef struct _LONG_FILE_NAME_ENTRY {
FAT_DIRENT_ATTR_SYSTEM | \
FAT_DIRENT_ATTR_VOLUME_ID)
typedef struct _PACKED_LFN_DIRENT {
UCHAR Ordinal; // offset = 0
UCHAR Name1[10]; // offset = 1 (Really 5 chars, but not WCHAR aligned)
UCHAR Attributes; // offset = 11
UCHAR Type; // offset = 12
UCHAR Checksum; // offset = 13
WCHAR Name2[6]; // offset = 14
USHORT MustBeZero; // offset = 26
WCHAR Name3[2]; // offset = 28
} PACKED_LFN_DIRENT; // sizeof = 32
#endif//__FAT_H__

View file

@ -0,0 +1,202 @@
#ifndef __STRUCT_H__
#define __STRUCT_H__
typedef struct _FAT_SCAN_CONTEXT *PFAT_SCAN_CONTEXT;
typedef struct _FAT_IO_CONTEXT *PFAT_IO_CONTEXT;
typedef PVOID PBCB;
typedef struct _FAT_GLOBAL_DATA
{
ERESOURCE Resource;
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT DiskDeviceObject;
LIST_ENTRY VcbListHead;
NPAGED_LOOKASIDE_LIST NonPagedFcbList;
NPAGED_LOOKASIDE_LIST ResourceList;
NPAGED_LOOKASIDE_LIST IrpContextList;
FAST_IO_DISPATCH FastIoDispatch;
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks;
CACHE_MANAGER_CALLBACKS CacheMgrNoopCallbacks;
BOOLEAN Win31FileSystem;
/* Jan 1, 1980 System Time */
LARGE_INTEGER DefaultFileTime;
} FAT_GLOBAL_DATA;
#define IRPCONTEXT_CANWAIT 0x0001
#define IRPCONTEXT_PENDINGRETURNED 0x0002
#define IRPCONTEXT_STACK_IO_CONTEXT 0x0004
#define IRPCONTEXT_WRITETHROUGH 0x0008
#define IRPCONTEXT_TOPLEVEL 0x0010
typedef struct _FAT_IRP_CONTEXT
{
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
UCHAR MajorFunction;
UCHAR MinorFunction;
PFILE_OBJECT FileObject;
ULONG Flags;
struct _VCB *Vcb;
ULONG PinCount;
struct _FAT_IO_CONTEXT *FatIoContext;
WORK_QUEUE_ITEM WorkQueueItem;
PIO_STACK_LOCATION Stack;
KEVENT Event;
} FAT_IRP_CONTEXT, *PFAT_IRP_CONTEXT;
typedef struct _FAT_IO_CONTEXT
{
PMDL ZeroMdl;
PIRP MasterIrp;
LONG IrpCount;
union
{
struct
{
PERESOURCE Resource;
PERESOURCE PagingIoResource;
ERESOURCE_THREAD ResourceThreadId;
ULONG RequestedByteCount;
PFILE_OBJECT FileObject;
BOOLEAN ReadOperation;
} Async;
KEVENT SyncEvent;
} Wait;
PIRP Irp[0];
} FAT_IO_CONTEXT;
typedef ULONG (*PFAT_SCANFAT_FOR_CONTINOUS_RUN_ROUTINE) (struct _FAT_SCAN_CONTEXT*, PULONG, BOOLEAN);
typedef ULONG (*PFAT_SETFAT_CONTINOUS_RUN_ROUTINE) (PFAT_SCAN_CONTEXT, ULONG, ULONG, BOOLEAN);
typedef ULONG (*PFAT_SCANFAT_FOR_VALUE_RUN_ROUTINE) (PFAT_SCAN_CONTEXT, PULONG, ULONG, BOOLEAN);
typedef ULONG (*PFAT_SETFAT_VALUE_RUN_ROUTINE) (PFAT_SCAN_CONTEXT, ULONG, ULONG, ULONG, BOOLEAN);
typedef struct _FAT_METHODS {
PFAT_SCANFAT_FOR_CONTINOUS_RUN_ROUTINE ScanContinousRun;
PFAT_SETFAT_CONTINOUS_RUN_ROUTINE SetContinousRun;
PFAT_SCANFAT_FOR_VALUE_RUN_ROUTINE ScanValueRun;
PFAT_SETFAT_VALUE_RUN_ROUTINE SetValueRun;
} FAT_METHODS, *PFAT_METHODS;
#define FAT_NTC_VCB (USHORT) 'VF'
/* Volume Control Block */
typedef struct _VCB
{
FSRTL_ADVANCED_FCB_HEADER Header;
FAST_MUTEX HeaderMutex;
SECTION_OBJECT_POINTERS SectionObjectPointers;
PFILE_OBJECT VolumeFileObject;
PDEVICE_OBJECT TargetDeviceObject;
LIST_ENTRY VcbLinks;
/* Volume Characteristics: */
ULONG SerialNumber;
BIOS_PARAMETER_BLOCK Bpb;
ULONG BytesPerClusterLog;
ULONG BytesPerCluster;
ULONG SectorsPerFat;
ULONG DataArea;
ULONG Sectors;
ULONG Clusters;
ULONG IndexDepth;
ULONG RootDirent;
ULONG RootDirentSectors;
LONGLONG BeyoundLastClusterInFat;
FAT_METHODS Methods;
/* Root Directory Fcb: */
struct _FCB *RootFcb;
} VCB, *PVCB;
#define VcbToVolumeDeviceObject(xVcb) \
CONTAINING_RECORD((xVcb), VOLUME_DEVICE_OBJECT, Vcb))
#define VcbToDeviceObject(xVcb) \
&(VcbToVolumeDeviceObject(xVcb)->DeviceObject)
#define SectorsToBytes(xVcb, xSectrors) \
((xVcb)->Bpb.BytesPerSector * (xSectrors))
#define BytesToSectors(xVcb, xBytes) \
((xBytes + (xVcb)->Bpb.BytesPerSector - 1) / (xVcb)->Bpb.BytesPerSector)
#define SectorsToClusters(xVcb, xSectors) \
((xSectors + (xVcb)->Bpb.SectorsPerCluster - 1) / (xVcb)->Bpb.SectorsPerCluster)
#define VCB_FAT_BITMAP_SIZE 0x10000
#define VcbFatBitmapIndex(xCluster) ((xCluster)/VCB_FAT_BITMAP_SIZE)
/* Volume Device Object */
typedef struct _VOLUME_DEVICE_OBJECT
{
DEVICE_OBJECT DeviceObject;
union {
FSRTL_COMMON_FCB_HEADER VolumeHeader;
VCB Vcb; /* Must be the last entry! */
};
} VOLUME_DEVICE_OBJECT, *PVOLUME_DEVICE_OBJECT;
//
// Short name always exists in FAT
//
enum _FCB_NAME_TYPE {
FcbShortName = 0x0,
FcbLongName
} FCB_NAME_TYPE;
typedef struct _FCB_NAME_LINK {
RTL_SPLAY_LINKS Links;
UNICODE_STRING String;
UCHAR Type;
} FCB_NAME_LINK, *PFCB_NAME_LINK;
#define FAT_NTC_FCB (USHORT) 'CF'
#define FAT_NTC_DCB (USHORT) 'DF'
typedef struct _FCB
{
FSRTL_ADVANCED_FCB_HEADER Header;
/*
* Later we might want to move the next four fields
* into a separate structureif we decide to split
* FCB into paged and non paged parts
* (as it is done in MS implementation
*/
FAST_MUTEX HeaderMutex;
SECTION_OBJECT_POINTERS SectionObjectPointers;
ERESOURCE Resource;
ERESOURCE PagingIoResource;
FILE_LOCK Lock;
/* Reference to the Parent Dcb*/
struct _FCB *ParentFcb;
/* Pointer to a Vcb */
PVCB Vcb;
/* Mcb mapping Vbo->Lbo */
LARGE_MCB Mcb;
ULONG FirstCluster;
/* Links into FCB Trie */
FCB_NAME_LINK FileName[0x2];
/* Buffer for the short name */
WCHAR ShortNameBuffer[0xc];
union
{
struct
{
/* Bitmap to search for free dirents. */
/* RTL_BITMAP Bitmap; */
PRTL_SPLAY_LINKS SplayLinks;
} Dcb;
};
} FCB, *PFCB;
typedef struct _CCB
{
LARGE_INTEGER CurrentByteOffset;
ULONG Entry;
UNICODE_STRING SearchPattern;
} CCB, *PCCB;
extern FAT_GLOBAL_DATA FatGlobalData;
#endif//__STRUCT_H__