https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6d65da93e3c5d9c934dc5…
commit 6d65da93e3c5d9c934dc5d4ae03b95d7609b2198
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Tue Sep 13 23:46:04 2022 +0200
Commit: hpoussin <32227662+hpoussin(a)users.noreply.github.com>
CommitDate: Sat Sep 24 12:12:33 2022 +0200
[FS_REC] Add FATX recognizer
CORE-16373
---
drivers/filesystems/fs_rec/CMakeLists.txt | 1 +
drivers/filesystems/fs_rec/fatx.c | 130 ++++++++++++++++++++++++++++++
drivers/filesystems/fs_rec/fs_rec.c | 17 ++++
drivers/filesystems/fs_rec/fs_rec.h | 8 ++
4 files changed, 156 insertions(+)
diff --git a/drivers/filesystems/fs_rec/CMakeLists.txt
b/drivers/filesystems/fs_rec/CMakeLists.txt
index 2d309ef7447..c231d3d378d 100644
--- a/drivers/filesystems/fs_rec/CMakeLists.txt
+++ b/drivers/filesystems/fs_rec/CMakeLists.txt
@@ -4,6 +4,7 @@ list(APPEND SOURCE
cdfs.c
ext2.c
fat.c
+ fatx.c
ffs.c
fs_rec.c
ntfs.c
diff --git a/drivers/filesystems/fs_rec/fatx.c b/drivers/filesystems/fs_rec/fatx.c
new file mode 100644
index 00000000000..165cac292e1
--- /dev/null
+++ b/drivers/filesystems/fs_rec/fatx.c
@@ -0,0 +1,130 @@
+/*
+ * PROJECT: ReactOS File System Recognizer
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: FATX Recognizer
+ * COPYRIGHT: Copyright 2022 Hervé Poussineau
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "fs_rec.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* TYPES ****************************************************************/
+
+#include <pshpack1.h>
+typedef struct _FATX_BOOT_SECTOR
+{
+ UCHAR SysType[4];
+ ULONG VolumeId;
+ ULONG SectorsPerCluster;
+ USHORT FatCount;
+ ULONG Reserved;
+ UCHAR Unused[4078];
+} FATX_BOOT_SECTOR, *PFATX_BOOT_SECTOR;
+#include <poppack.h>
+
+/* FUNCTIONS ****************************************************************/
+
+BOOLEAN
+NTAPI
+FsRecIsFatxVolume(IN PFATX_BOOT_SECTOR BootSector)
+{
+ BOOLEAN Result = TRUE;
+
+ PAGED_CODE();
+
+ if (BootSector->SysType[0] != 'F' ||
+ BootSector->SysType[1] != 'A' ||
+ BootSector->SysType[2] != 'T' ||
+ BootSector->SysType[3] != 'X')
+ {
+ /* Fail */
+ Result = FALSE;
+ }
+ else if (BootSector->SectorsPerCluster != 1 &&
+ BootSector->SectorsPerCluster != 2 &&
+ BootSector->SectorsPerCluster != 4 &&
+ BootSector->SectorsPerCluster != 8 &&
+ BootSector->SectorsPerCluster != 16 &&
+ BootSector->SectorsPerCluster != 32 &&
+ BootSector->SectorsPerCluster != 64 &&
+ BootSector->SectorsPerCluster != 128)
+ {
+ /* Fail */
+ Result = FALSE;
+ }
+
+ /* Return the result */
+ return Result;
+}
+
+NTSTATUS
+NTAPI
+FsRecFatxFsControl(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION Stack;
+ NTSTATUS Status;
+ PDEVICE_OBJECT MountDevice;
+ PFATX_BOOT_SECTOR Bpb = NULL;
+ ULONG SectorSize;
+ LARGE_INTEGER Offset = {{0, 0}};
+ BOOLEAN DeviceError = FALSE;
+ PAGED_CODE();
+
+ /* Get the I/O Stack and check the function type */
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ switch (Stack->MinorFunction)
+ {
+ case IRP_MN_MOUNT_VOLUME:
+
+ /* Assume failure */
+ Status = STATUS_UNRECOGNIZED_VOLUME;
+
+ /* Get the device object and request the sector size */
+ MountDevice = Stack->Parameters.MountVolume.DeviceObject;
+ if (FsRecGetDeviceSectorSize(MountDevice, &SectorSize))
+ {
+ /* Try to read the BPB */
+ if (FsRecReadBlock(MountDevice,
+ &Offset,
+ 512,
+ SectorSize,
+ (PVOID)&Bpb,
+ &DeviceError))
+ {
+ /* Check if it's an actual FAT volume */
+ if (FsRecIsFatxVolume(Bpb))
+ {
+ /* It is! */
+ Status = STATUS_FS_DRIVER_REQUIRED;
+ }
+ }
+
+ /* Free the boot sector if we have one */
+ ExFreePool(Bpb);
+ }
+
+ break;
+
+ case IRP_MN_LOAD_FILE_SYSTEM:
+
+ /* Load the file system */
+ Status = FsRecLoadFileSystem(DeviceObject,
+
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\vfatfs");
+ break;
+
+ default:
+
+ /* Invalid request */
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ /* Return Status */
+ return Status;
+}
+
+/* EOF */
diff --git a/drivers/filesystems/fs_rec/fs_rec.c b/drivers/filesystems/fs_rec/fs_rec.c
index e350fac5ceb..1dd5b4d2697 100644
--- a/drivers/filesystems/fs_rec/fs_rec.c
+++ b/drivers/filesystems/fs_rec/fs_rec.c
@@ -182,6 +182,12 @@ FsRecFsControl(IN PDEVICE_OBJECT DeviceObject,
Status = FsRecFfsFsControl(DeviceObject, Irp);
break;
+ case FS_TYPE_FATX:
+
+ /* Send FATX command */
+ Status = FsRecFatxFsControl(DeviceObject, Irp);
+ break;
+
default:
/* Unrecognized FS */
@@ -468,6 +474,17 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
0);
if (NT_SUCCESS(Status)) DeviceCount++;
+ /* Register FATX */
+ Status = FsRecRegisterFs(DriverObject,
+ NULL,
+ NULL,
+ L"\\FatX",
+ L"\\FileSystem\\FatXRecognizer",
+ FS_TYPE_FATX,
+ FILE_DEVICE_DISK_FILE_SYSTEM,
+ 0);
+ if (NT_SUCCESS(Status)) DeviceCount++;
+
/* Return appropriate Status */
return (DeviceCount > 0) ? STATUS_SUCCESS : STATUS_IMAGE_ALREADY_LOADED;
}
diff --git a/drivers/filesystems/fs_rec/fs_rec.h b/drivers/filesystems/fs_rec/fs_rec.h
index 4e062e2ff4b..fe56d1ac18f 100644
--- a/drivers/filesystems/fs_rec/fs_rec.h
+++ b/drivers/filesystems/fs_rec/fs_rec.h
@@ -177,6 +177,7 @@ typedef enum _FILE_SYSTEM_TYPE
FS_TYPE_BTRFS,
FS_TYPE_REISERFS,
FS_TYPE_FFS,
+ FS_TYPE_FATX,
} FILE_SYSTEM_TYPE, *PFILE_SYSTEM_TYPE;
/* FS Recognizer State */
@@ -252,6 +253,13 @@ FsRecFfsFsControl(
IN PIRP Irp
);
+NTSTATUS
+NTAPI
+FsRecFatxFsControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+);
+
BOOLEAN
NTAPI
FsRecGetDeviceSectors(