From 6d65da93e3c5d9c934dc5d4ae03b95d7609b2198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Tue, 13 Sep 2022 23:46:04 +0200 Subject: [PATCH] [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(+) create mode 100644 drivers/filesystems/fs_rec/fatx.c 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 + +/* TYPES ****************************************************************/ + +#include +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 + +/* 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(