X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=drivers%2Ffilesystems%2Ffastfat%2Fvfat.h;h=1f2939577c7afb78a02ed464ea65ddab1c9e6a9c;hp=28a047a5b1eef2069750e55d3efe7dfcbbb29770;hb=3c3ebe33207a05c0b5b11ffd2d753c69690dc2fb;hpb=8db8073cbb2ceddf2cd8ffa6fbe0893c95941034 diff --git a/drivers/filesystems/fastfat/vfat.h b/drivers/filesystems/fastfat/vfat.h index 28a047a5b1e..1f2939577c7 100644 --- a/drivers/filesystems/fastfat/vfat.h +++ b/drivers/filesystems/fastfat/vfat.h @@ -4,8 +4,24 @@ #include #include #include +#include +#ifdef KDBG +#include +#include +#endif + +#ifdef __GNUC__ +#define INIT_SECTION __attribute__((section ("INIT"))) +#else +#define INIT_SECTION /* Done via alloc_text for MSC */ +#endif #define USE_ROS_CC_AND_FS +#if 0 +#ifndef _MSC_VER +#define ENABLE_SWAPOUT +#endif +#endif #define ROUND_DOWN(n, align) \ (((ULONG)n) & ~((align) - 1l)) @@ -13,6 +29,12 @@ #define ROUND_UP(n, align) \ ROUND_DOWN(((ULONG)n) + (align) - 1, (align)) +#define ROUND_DOWN_64(n, align) \ + (((ULONGLONG)n) & ~((align) - 1LL)) + +#define ROUND_UP_64(n, align) \ + ROUND_DOWN_64(((ULONGLONG)n) + (align) - 1LL, (align)) + #include struct _BootSector { @@ -179,9 +201,9 @@ typedef struct _slot slot; #define LONGNAME_MAX_LENGTH 256 // max length for a long filename -#define ENTRY_DELETED(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_DELETED(&((DirEntry)->FatX)) : FAT_ENTRY_DELETED(&((DirEntry)->Fat))) -#define ENTRY_VOLUME(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_VOLUME(&((DirEntry)->FatX)) : FAT_ENTRY_VOLUME(&((DirEntry)->Fat))) -#define ENTRY_END(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_END(&((DirEntry)->FatX)) : FAT_ENTRY_END(&((DirEntry)->Fat))) +#define ENTRY_DELETED(IsFatX, DirEntry) (IsFatX ? FATX_ENTRY_DELETED(&((DirEntry)->FatX)) : FAT_ENTRY_DELETED(&((DirEntry)->Fat))) +#define ENTRY_VOLUME(IsFatX, DirEntry) (IsFatX ? FATX_ENTRY_VOLUME(&((DirEntry)->FatX)) : FAT_ENTRY_VOLUME(&((DirEntry)->Fat))) +#define ENTRY_END(IsFatX, DirEntry) (IsFatX ? FATX_ENTRY_END(&((DirEntry)->FatX)) : FAT_ENTRY_END(&((DirEntry)->Fat))) #define FAT_ENTRY_DELETED(DirEntry) ((DirEntry)->Filename[0] == 0xe5) #define FAT_ENTRY_END(DirEntry) ((DirEntry)->Filename[0] == 0) @@ -217,12 +239,14 @@ typedef union _DIR_ENTRY DIR_ENTRY, *PDIR_ENTRY; #define VCB_VOLUME_LOCKED 0x0001 #define VCB_DISMOUNT_PENDING 0x0002 #define VCB_IS_FATX 0x0004 +#define VCB_IS_SYS_OR_HAS_PAGE 0x0008 #define VCB_IS_DIRTY 0x4000 /* Volume is dirty */ #define VCB_CLEAR_DIRTY 0x8000 /* Clean dirty flag at shutdown */ typedef struct { ULONG VolumeID; + CHAR VolumeLabel[11]; ULONG FATStart; ULONG FATCount; ULONG FATSectors; @@ -241,6 +265,7 @@ typedef struct struct _VFATFCB; struct _VFAT_DIRENTRY_CONTEXT; +struct _VFAT_MOVE_CONTEXT; typedef struct _HASHENTRY { @@ -250,16 +275,32 @@ typedef struct _HASHENTRY } HASHENTRY; -#define FCB_HASH_TABLE_SIZE 65536 - typedef struct DEVICE_EXTENSION *PDEVICE_EXTENSION; typedef NTSTATUS (*PGET_NEXT_CLUSTER)(PDEVICE_EXTENSION,ULONG,PULONG); typedef NTSTATUS (*PFIND_AND_MARK_AVAILABLE_CLUSTER)(PDEVICE_EXTENSION,PULONG); typedef NTSTATUS (*PWRITE_CLUSTER)(PDEVICE_EXTENSION,ULONG,ULONG,PULONG); +typedef BOOLEAN (*PIS_DIRECTORY_EMPTY)(PDEVICE_EXTENSION,struct _VFATFCB*); +typedef NTSTATUS (*PADD_ENTRY)(PDEVICE_EXTENSION,PUNICODE_STRING,struct _VFATFCB**,struct _VFATFCB*,ULONG,UCHAR,struct _VFAT_MOVE_CONTEXT*); +typedef NTSTATUS (*PDEL_ENTRY)(PDEVICE_EXTENSION,struct _VFATFCB*,struct _VFAT_MOVE_CONTEXT*); typedef NTSTATUS (*PGET_NEXT_DIR_ENTRY)(PVOID*,PVOID*,struct _VFATFCB*,struct _VFAT_DIRENTRY_CONTEXT*,BOOLEAN); +typedef struct _VFAT_DISPATCH +{ + PIS_DIRECTORY_EMPTY IsDirectoryEmpty; + PADD_ENTRY AddEntry; + PDEL_ENTRY DelEntry; + PGET_NEXT_DIR_ENTRY GetNextDirEntry; +} VFAT_DISPATCH, *PVFAT_DISPATCH; + +#define STATISTICS_SIZE_NO_PAD (sizeof(FILESYSTEM_STATISTICS) + sizeof(FAT_STATISTICS)) +typedef struct _STATISTICS { + FILESYSTEM_STATISTICS Base; + FAT_STATISTICS Fat; + UCHAR Pad[((STATISTICS_SIZE_NO_PAD + 0x3f) & ~0x3f) - STATISTICS_SIZE_NO_PAD]; +} STATISTICS, *PSTATISTICS; + typedef struct DEVICE_EXTENSION { ERESOURCE DirResource; @@ -270,6 +311,7 @@ typedef struct DEVICE_EXTENSION ULONG HashTableSize; struct _HASHENTRY **FcbHashTable; + PDEVICE_OBJECT VolumeDevice; PDEVICE_OBJECT StorageDevice; PFILE_OBJECT FATFileObject; FATINFO FatInfo; @@ -278,6 +320,7 @@ typedef struct DEVICE_EXTENSION BOOLEAN AvailableClustersValid; ULONG Flags; struct _VFATFCB *VolumeFcb; + PSTATISTICS Statistics; /* Pointers to functions for manipulating FAT. */ PGET_NEXT_CLUSTER GetNextCluster; @@ -285,9 +328,6 @@ typedef struct DEVICE_EXTENSION PWRITE_CLUSTER WriteCluster; ULONG CleanShutBitMask; - /* Pointers to functions for manipulating directory entries. */ - PGET_NEXT_DIR_ENTRY GetNextDirEntry; - ULONG BaseDateYear; LIST_ENTRY VolumeListEntry; @@ -295,13 +335,68 @@ typedef struct DEVICE_EXTENSION /* Notifications */ LIST_ENTRY NotifyList; PNOTIFY_SYNC NotifySync; + + /* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLOSE */ + ULONG OpenHandleCount; + + /* VPBs for dismount */ + PVPB IoVPB; + PVPB SpareVPB; + + /* Pointers to functions for manipulating directory entries. */ + VFAT_DISPATCH Dispatch; } DEVICE_EXTENSION, VCB, *PVCB; +FORCEINLINE +BOOLEAN +VfatIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt, + struct _VFATFCB* Fcb) +{ + return DeviceExt->Dispatch.IsDirectoryEmpty(DeviceExt, Fcb); +} + +FORCEINLINE +NTSTATUS +VfatAddEntry(PDEVICE_EXTENSION DeviceExt, + PUNICODE_STRING NameU, + struct _VFATFCB** Fcb, + struct _VFATFCB* ParentFcb, + ULONG RequestedOptions, + UCHAR ReqAttr, + struct _VFAT_MOVE_CONTEXT* MoveContext) +{ + return DeviceExt->Dispatch.AddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr, MoveContext); +} + +FORCEINLINE +NTSTATUS +VfatDelEntry(PDEVICE_EXTENSION DeviceExt, + struct _VFATFCB* Fcb, + struct _VFAT_MOVE_CONTEXT* MoveContext) +{ + return DeviceExt->Dispatch.DelEntry(DeviceExt, Fcb, MoveContext); +} + +FORCEINLINE +NTSTATUS +VfatGetNextDirEntry(PDEVICE_EXTENSION DeviceExt, + PVOID *pContext, + PVOID *pPage, + struct _VFATFCB* pDirFcb, + struct _VFAT_DIRENTRY_CONTEXT* DirContext, + BOOLEAN First) +{ + return DeviceExt->Dispatch.GetNextDirEntry(pContext, pPage, pDirFcb, DirContext, First); +} + +#define VFAT_BREAK_ON_CORRUPTION 1 + typedef struct { PDRIVER_OBJECT DriverObject; PDEVICE_OBJECT DeviceObject; ULONG Flags; + ULONG NumberProcessors; ERESOURCE VolumeListLock; LIST_ENTRY VolumeListHead; NPAGED_LOOKASIDE_LIST FcbLookasideList; @@ -319,7 +414,12 @@ extern PVFAT_GLOBAL_DATA VfatGlobalData; #define FCB_IS_PAGE_FILE 0x0008 #define FCB_IS_VOLUME 0x0010 #define FCB_IS_DIRTY 0x0020 -#define FCB_IS_FATX_ENTRY 0x0040 +#ifdef KDBG +#define FCB_CLEANED_UP 0x0040 +#define FCB_CLOSED 0x0080 +#endif + +#define NODE_TYPE_FCB ((CSHORT)0x0502) typedef struct _VFATFCB { @@ -360,9 +460,15 @@ typedef struct _VFATFCB /* List of FCB's for this volume */ LIST_ENTRY FcbListEntry; + /* List of FCB's for the parent */ + LIST_ENTRY ParentListEntry; + /* pointer to the parent fcb */ struct _VFATFCB *parentFcb; + /* List for the children */ + LIST_ENTRY ParentListHead; + /* Flags for the fcb */ ULONG Flags; @@ -391,7 +497,7 @@ typedef struct _VFATFCB FILE_LOCK FileLock; /* - * Optimalization: caching of last read/write cluster+offset pair. Can't + * Optimization: caching of last read/write cluster+offset pair. Can't * be in VFATCCB because it must be reset everytime the allocated clusters * change. */ @@ -400,9 +506,12 @@ typedef struct _VFATFCB ULONG LastOffset; } VFATFCB, *PVFATFCB; +#define CCB_DELETE_ON_CLOSE 0x0001 + typedef struct _VFATCCB { LARGE_INTEGER CurrentByteOffset; + ULONG Flags; /* for DirectoryControl */ ULONG Entry; /* for DirectoryControl */ @@ -432,8 +541,11 @@ typedef struct __DOSDATE } DOSDATE, *PDOSDATE; -#define IRPCONTEXT_CANWAIT 0x0001 -#define IRPCONTEXT_PENDINGRETURNED 0x0002 +#define IRPCONTEXT_CANWAIT 0x0001 +#define IRPCONTEXT_COMPLETE 0x0002 +#define IRPCONTEXT_QUEUE 0x0004 +#define IRPCONTEXT_PENDINGRETURNED 0x0008 +#define IRPCONTEXT_DEFERRED_WRITE 0x0010 typedef struct { @@ -448,6 +560,7 @@ typedef struct PFILE_OBJECT FileObject; ULONG RefCount; KEVENT Event; + CCHAR PriorityBoost; } VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT; typedef struct _VFAT_DIRENTRY_CONTEXT @@ -457,8 +570,71 @@ typedef struct _VFAT_DIRENTRY_CONTEXT DIR_ENTRY DirEntry; UNICODE_STRING LongNameU; UNICODE_STRING ShortNameU; + PDEVICE_EXTENSION DeviceExt; } VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT; +typedef struct _VFAT_MOVE_CONTEXT +{ + ULONG FirstCluster; + ULONG FileSize; + USHORT CreationDate; + USHORT CreationTime; + BOOLEAN InPlace; +} VFAT_MOVE_CONTEXT, *PVFAT_MOVE_CONTEXT; + +FORCEINLINE +NTSTATUS +VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext) +{ + PULONG Flags = &IrpContext->Flags; + + *Flags &= ~IRPCONTEXT_COMPLETE; + *Flags |= IRPCONTEXT_QUEUE; + + return STATUS_PENDING; +} + +FORCEINLINE +BOOLEAN +vfatFCBIsDirectory(PVFATFCB FCB) +{ + return BooleanFlagOn(*FCB->Attributes, FILE_ATTRIBUTE_DIRECTORY); +} + +FORCEINLINE +BOOLEAN +vfatFCBIsReadOnly(PVFATFCB FCB) +{ + return BooleanFlagOn(*FCB->Attributes, FILE_ATTRIBUTE_READONLY); +} + +FORCEINLINE +BOOLEAN +vfatVolumeIsFatX(PDEVICE_EXTENSION DeviceExt) +{ + return BooleanFlagOn(DeviceExt->Flags, VCB_IS_FATX); +} + +FORCEINLINE +VOID +vfatReportChange( + IN PDEVICE_EXTENSION DeviceExt, + IN PVFATFCB Fcb, + IN ULONG FilterMatch, + IN ULONG Action) +{ + FsRtlNotifyFullReportChange(DeviceExt->NotifySync, + &(DeviceExt->NotifyList), + (PSTRING)&Fcb->PathNameU, + Fcb->PathNameU.Length - Fcb->LongNameU.Length, + NULL, NULL, FilterMatch, Action, NULL); +} + +#define vfatAddToStat(Vcb, Stat, Inc) \ +{ \ + PSTATISTICS Stats = &(Vcb)->Statistics[KeGetCurrentProcessorNumber() % VfatGlobalData->NumberProcessors]; \ + Stats->Stat += Inc; \ +} /* blockdev.c */ @@ -532,11 +708,6 @@ vfat8Dot3ToString( PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU); -NTSTATUS -ReadVolumeLabel( - PDEVICE_EXTENSION DeviceExt, - PVPB Vpb); - /* dir.c */ NTSTATUS @@ -564,46 +735,18 @@ vfatDirEntryGetFirstCluster( PDEVICE_EXTENSION pDeviceExt, PDIR_ENTRY pDirEntry); -BOOLEAN -VfatIsDirectoryEmpty( - PVFATFCB Fcb); - -NTSTATUS -FATGetNextDirEntry( - PVOID *pContext, - PVOID *pPage, - IN PVFATFCB pDirFcb, - IN PVFAT_DIRENTRY_CONTEXT DirContext, - BOOLEAN First); - -NTSTATUS -FATXGetNextDirEntry( - PVOID *pContext, - PVOID *pPage, - IN PVFATFCB pDirFcb, - IN PVFAT_DIRENTRY_CONTEXT DirContext, - BOOLEAN First); - /* dirwr.c */ NTSTATUS -VfatAddEntry( - PDEVICE_EXTENSION DeviceExt, - PUNICODE_STRING PathNameU, - PVFATFCB* Fcb, - PVFATFCB ParentFcb, - ULONG RequestedOptions, - UCHAR ReqAttr); +vfatFCBInitializeCacheFromVolume( + PVCB vcb, + PVFATFCB fcb); NTSTATUS VfatUpdateEntry( + IN PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb); -NTSTATUS -VfatDelEntry( - PDEVICE_EXTENSION, - PVFATFCB); - BOOLEAN vfatFindDirSpace( PDEVICE_EXTENSION DeviceExt, @@ -611,6 +754,20 @@ vfatFindDirSpace( ULONG nbSlots, PULONG start); +NTSTATUS +vfatRenameEntry( + IN PDEVICE_EXTENSION DeviceExt, + IN PVFATFCB pFcb, + IN PUNICODE_STRING FileName, + IN BOOLEAN CaseChangeOnly); + +NTSTATUS +VfatMoveEntry( + IN PDEVICE_EXTENSION DeviceExt, + IN PVFATFCB pFcb, + IN PUNICODE_STRING FileName, + IN PVFATFCB ParentFcb); + /* ea.h */ NTSTATUS @@ -636,17 +793,6 @@ NTAPI VfatReleaseFromLazyWrite( IN PVOID Context); -BOOLEAN -NTAPI -VfatAcquireForReadAhead( - IN PVOID Context, - IN BOOLEAN Wait); - -VOID -NTAPI -VfatReleaseFromReadAhead( - IN PVOID Context); - /* fat.c */ NTSTATUS @@ -746,6 +892,19 @@ vfatNewFCB( PDEVICE_EXTENSION pVCB, PUNICODE_STRING pFileNameU); +NTSTATUS +vfatSetFCBNewDirName( + PDEVICE_EXTENSION pVCB, + PVFATFCB Fcb, + PVFATFCB ParentFcb); + +NTSTATUS +vfatUpdateFCB( + PDEVICE_EXTENSION pVCB, + PVFATFCB Fcb, + PVFAT_DIRENTRY_CONTEXT DirContext, + PVFATFCB ParentFcb); + VOID vfatDestroyFCB( PVFATFCB pFCB); @@ -755,19 +914,41 @@ vfatDestroyCCB( PVFATCCB pCcb); VOID +#ifndef KDBG vfatGrabFCB( +#else +_vfatGrabFCB( +#endif PDEVICE_EXTENSION pVCB, - PVFATFCB pFCB); + PVFATFCB pFCB +#ifdef KDBG + , + PCSTR File, + ULONG Line, + PCSTR Func +#endif + ); VOID +#ifndef KDBG vfatReleaseFCB( +#else +_vfatReleaseFCB( +#endif PDEVICE_EXTENSION pVCB, - PVFATFCB pFCB); - -VOID -vfatAddFCBToTable( - PDEVICE_EXTENSION pVCB, - PVFATFCB pFCB); + PVFATFCB pFCB +#ifdef KDBG + , + PCSTR File, + ULONG Line, + PCSTR Func +#endif + ); + +#ifdef KDBG +#define vfatGrabFCB(v, f) _vfatGrabFCB(v, f, __FILE__, __LINE__, __FUNCTION__) +#define vfatReleaseFCB(v, f) _vfatReleaseFCB(v, f, __FILE__, __LINE__, __FUNCTION__) +#endif PVFATFCB vfatGrabFCBFromTable( @@ -819,6 +1000,20 @@ vfatMakeFCBFromDirEntry( /* finfo.c */ +NTSTATUS +VfatGetStandardInformation( + PVFATFCB FCB, + PFILE_STANDARD_INFORMATION StandardInfo, + PULONG BufferLength); + +NTSTATUS +VfatGetBasicInformation( + PFILE_OBJECT FileObject, + PVFATFCB FCB, + PDEVICE_EXTENSION DeviceExt, + PFILE_BASIC_INFORMATION BasicInfo, + PULONG BufferLength); + NTSTATUS VfatQueryInformation( PVFAT_IRP_CONTEXT IrpContext); @@ -859,22 +1054,13 @@ DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath); +#ifdef KDBG +/* kdbg.c */ +KDBG_CLI_ROUTINE vfatKdbgHandler; +#endif /* misc.c */ -NTSTATUS -VfatQueueRequest( - PVFAT_IRP_CONTEXT IrpContext); - -PVFAT_IRP_CONTEXT -VfatAllocateIrpContext( - PDEVICE_OBJECT DeviceObject, - PIRP Irp); - -VOID -VfatFreeIrpContext( - PVFAT_IRP_CONTEXT IrpContext); - DRIVER_DISPATCH VfatBuildRequest; @@ -886,7 +1072,8 @@ VfatBuildRequest( PVOID VfatGetUserBuffer( - IN PIRP); + IN PIRP, + IN BOOLEAN Paging); NTSTATUS VfatLockUserBuffer( @@ -894,6 +1081,24 @@ VfatLockUserBuffer( IN ULONG, IN LOCK_OPERATION); +BOOLEAN +VfatCheckForDismount( + IN PDEVICE_EXTENSION DeviceExt, + IN BOOLEAN Create); + +VOID +vfatReportChange( + IN PDEVICE_EXTENSION DeviceExt, + IN PVFATFCB Fcb, + IN ULONG FilterMatch, + IN ULONG Action); + +VOID +NTAPI +VfatHandleDeferredWrite( + IN PVOID IrpContext, + IN PVOID Unused); + /* pnp.c */ NTSTATUS