#include <ntdddisk.h>
#include <dos.h>
#include <pseh/pseh2.h>
+#ifdef KDBG
+#include <ndk/kdfuncs.h>
+#include <reactos/kdros.h>
+#endif
#ifdef __GNUC__
#define INIT_SECTION __attribute__((section ("INIT")))
unsigned short Signature1; // 510
};
+#define FAT_DIRTY_BIT 0x01
+
struct _BootSectorFatX
{
unsigned char SysType[4]; // 0
#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 */
ULONG FatType;
ULONG Sectors;
BOOLEAN FixedMedia;
+ ULONG FSInfoSector;
} FATINFO, *PFATINFO;
struct _VFATFCB;
struct _VFAT_DIRENTRY_CONTEXT;
struct _VFAT_MOVE_CONTEXT;
+struct _VFAT_CLOSE_CONTEXT;
typedef struct _HASHENTRY
{
typedef NTSTATUS (*PFIND_AND_MARK_AVAILABLE_CLUSTER)(PDEVICE_EXTENSION,PULONG);
typedef NTSTATUS (*PWRITE_CLUSTER)(PDEVICE_EXTENSION,ULONG,ULONG,PULONG);
-typedef BOOLEAN (*PIS_DIRECTORY_EMPTY)(struct _VFATFCB*);
+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 NTSTATUS (*PGET_DIRTY_STATUS)(PDEVICE_EXTENSION,PBOOLEAN);
+typedef NTSTATUS (*PSET_DIRTY_STATUS)(PDEVICE_EXTENSION,BOOLEAN);
typedef struct _VFAT_DISPATCH
{
PGET_NEXT_CLUSTER GetNextCluster;
PFIND_AND_MARK_AVAILABLE_CLUSTER FindAndMarkAvailableCluster;
PWRITE_CLUSTER WriteCluster;
- ULONG CleanShutBitMask;
+ PGET_DIRTY_STATUS GetDirtyStatus;
+ PSET_DIRTY_STATUS SetDirtyStatus;
ULONG BaseDateYear;
VfatIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt,
struct _VFATFCB* Fcb)
{
- return DeviceExt->Dispatch.IsDirectoryEmpty(Fcb);
+ return DeviceExt->Dispatch.IsDirectoryEmpty(DeviceExt, Fcb);
}
FORCEINLINE
NPAGED_LOOKASIDE_LIST FcbLookasideList;
NPAGED_LOOKASIDE_LIST CcbLookasideList;
NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
+ PAGED_LOOKASIDE_LIST CloseContextLookasideList;
FAST_IO_DISPATCH FastIoDispatch;
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks;
+ FAST_MUTEX CloseMutex;
+ ULONG CloseCount;
+ LIST_ENTRY CloseListHead;
+ BOOLEAN CloseWorkerRunning;
+ PIO_WORKITEM CloseWorkItem;
+ BOOLEAN ShutdownStarted;
} VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
extern PVFAT_GLOBAL_DATA VfatGlobalData;
#define FCB_IS_PAGE_FILE 0x0008
#define FCB_IS_VOLUME 0x0010
#define FCB_IS_DIRTY 0x0020
+#define FCB_DELAYED_CLOSE 0x0040
+#ifdef KDBG
+#define FCB_CLEANED_UP 0x0080
+#define FCB_CLOSED 0x0100
+#endif
+
+#define NODE_TYPE_FCB ((CSHORT)0x0502)
typedef struct _VFATFCB
{
FAST_MUTEX LastMutex;
ULONG LastCluster;
ULONG LastOffset;
+
+ struct _VFAT_CLOSE_CONTEXT * CloseContext;
} VFATFCB, *PVFATFCB;
#define CCB_DELETE_ON_CLOSE 0x0001
UNICODE_STRING SearchPattern;
} VFATCCB, *PVFATCCB;
-#define TAG_CCB 'BCCV'
-#define TAG_FCB 'BCFV'
-#define TAG_IRP 'PRIV'
+#define TAG_CCB 'CtaF'
+#define TAG_FCB 'FtaF'
+#define TAG_IRP 'ItaF'
#define TAG_VFAT 'TAFV'
+#define TAG_CLOSE 'xtaF'
+#define TAG_STATS 'VtaF'
+#define TAG_BUFFER 'OtaF'
#define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
#define IRPCONTEXT_COMPLETE 0x0002
#define IRPCONTEXT_QUEUE 0x0004
#define IRPCONTEXT_PENDINGRETURNED 0x0008
+#define IRPCONTEXT_DEFERRED_WRITE 0x0010
typedef struct
{
DIR_ENTRY DirEntry;
UNICODE_STRING LongNameU;
UNICODE_STRING ShortNameU;
+ PDEVICE_EXTENSION DeviceExt;
} VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
typedef struct _VFAT_MOVE_CONTEXT
BOOLEAN InPlace;
} VFAT_MOVE_CONTEXT, *PVFAT_MOVE_CONTEXT;
+typedef struct _VFAT_CLOSE_CONTEXT
+{
+ PDEVICE_EXTENSION Vcb;
+ PVFATFCB Fcb;
+ LIST_ENTRY CloseListEntry;
+} VFAT_CLOSE_CONTEXT, *PVFAT_CLOSE_CONTEXT;
+
FORCEINLINE
NTSTATUS
VfatMarkIrpContextForQueue(PVFAT_IRP_CONTEXT IrpContext)
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]; \
IN ULONG BufferOffset,
IN BOOLEAN Wait);
+NTSTATUS
+VfatWriteDisk(
+ IN PDEVICE_OBJECT pDeviceObject,
+ IN PLARGE_INTEGER WriteOffset,
+ IN ULONG WriteLength,
+ IN OUT PUCHAR Buffer,
+ IN BOOLEAN Override);
+
NTSTATUS
VfatWriteDiskPartial(
IN PVFAT_IRP_CONTEXT IrpContext,
/* dirwr.c */
+NTSTATUS
+vfatFCBInitializeCacheFromVolume(
+ PVCB vcb,
+ PVFATFCB fcb);
+
NTSTATUS
VfatUpdateEntry(
- PVFATFCB pFcb,
- IN BOOLEAN IsFatX);
+ IN PDEVICE_EXTENSION DeviceExt,
+ PVFATFCB pFcb);
BOOLEAN
vfatFindDirSpace(
VfatReleaseFromLazyWrite(
IN PVOID Context);
-BOOLEAN
-NTAPI
-VfatAcquireForReadAhead(
- IN PVOID Context,
- IN BOOLEAN Wait);
-
-VOID
-NTAPI
-VfatReleaseFromReadAhead(
- IN PVOID Context);
-
/* fat.c */
NTSTATUS
ULONG ClusterToWrite,
ULONG NewValue);
+NTSTATUS
+GetDirtyStatus(
+ PDEVICE_EXTENSION DeviceExt,
+ PBOOLEAN DirtyStatus);
+
+NTSTATUS
+FAT16GetDirtyStatus(
+ PDEVICE_EXTENSION DeviceExt,
+ PBOOLEAN DirtyStatus);
+
+NTSTATUS
+FAT32GetDirtyStatus(
+ PDEVICE_EXTENSION DeviceExt,
+ PBOOLEAN DirtyStatus);
+
+NTSTATUS
+SetDirtyStatus(
+ PDEVICE_EXTENSION DeviceExt,
+ BOOLEAN DirtyStatus);
+
+NTSTATUS
+FAT16SetDirtyStatus(
+ PDEVICE_EXTENSION DeviceExt,
+ BOOLEAN DirtyStatus);
+
+NTSTATUS
+FAT32SetDirtyStatus(
+ PDEVICE_EXTENSION DeviceExt,
+ BOOLEAN DirtyStatus);
+
+NTSTATUS
+FAT32UpdateFreeClustersCount(
+ PDEVICE_EXTENSION DeviceExt);
+
/* fcb.c */
PVFATFCB
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);
+ 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(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
+#ifdef KDBG
+/* kdbg.c */
+KDBG_CLI_ROUTINE vfatKdbgHandler;
+#endif
/* misc.c */
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