1 /* 2 * PROJECT: ReactOS File System Recognizer 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: FATX Recognizer 5 * COPYRIGHT: Copyright 2022 Hervé Poussineau <hpoussin@reactos.org> 6 */ 7 8 /* INCLUDES *****************************************************************/ 9 10 #include "fs_rec.h" 11 12 #define NDEBUG 13 #include <debug.h> 14 15 /* TYPES ****************************************************************/ 16 17 #include <pshpack1.h> 18 typedef struct _FATX_BOOT_SECTOR 19 { 20 UCHAR SysType[4]; 21 ULONG VolumeId; 22 ULONG SectorsPerCluster; 23 USHORT FatCount; 24 ULONG Reserved; 25 UCHAR Unused[4078]; 26 } FATX_BOOT_SECTOR, *PFATX_BOOT_SECTOR; 27 #include <poppack.h> 28 29 /* FUNCTIONS ****************************************************************/ 30 31 BOOLEAN 32 NTAPI 33 FsRecIsFatxVolume(IN PFATX_BOOT_SECTOR BootSector) 34 { 35 BOOLEAN Result = TRUE; 36 37 PAGED_CODE(); 38 39 if (BootSector->SysType[0] != 'F' || 40 BootSector->SysType[1] != 'A' || 41 BootSector->SysType[2] != 'T' || 42 BootSector->SysType[3] != 'X') 43 { 44 /* Fail */ 45 Result = FALSE; 46 } 47 else if (BootSector->SectorsPerCluster != 1 && 48 BootSector->SectorsPerCluster != 2 && 49 BootSector->SectorsPerCluster != 4 && 50 BootSector->SectorsPerCluster != 8 && 51 BootSector->SectorsPerCluster != 16 && 52 BootSector->SectorsPerCluster != 32 && 53 BootSector->SectorsPerCluster != 64 && 54 BootSector->SectorsPerCluster != 128) 55 { 56 /* Fail */ 57 Result = FALSE; 58 } 59 60 /* Return the result */ 61 return Result; 62 } 63 64 NTSTATUS 65 NTAPI 66 FsRecFatxFsControl(IN PDEVICE_OBJECT DeviceObject, 67 IN PIRP Irp) 68 { 69 PIO_STACK_LOCATION Stack; 70 NTSTATUS Status; 71 PDEVICE_OBJECT MountDevice; 72 PFATX_BOOT_SECTOR Bpb = NULL; 73 ULONG SectorSize; 74 LARGE_INTEGER Offset = {{0, 0}}; 75 BOOLEAN DeviceError = FALSE; 76 PAGED_CODE(); 77 78 /* Get the I/O Stack and check the function type */ 79 Stack = IoGetCurrentIrpStackLocation(Irp); 80 switch (Stack->MinorFunction) 81 { 82 case IRP_MN_MOUNT_VOLUME: 83 84 /* Assume failure */ 85 Status = STATUS_UNRECOGNIZED_VOLUME; 86 87 /* Get the device object and request the sector size */ 88 MountDevice = Stack->Parameters.MountVolume.DeviceObject; 89 if (FsRecGetDeviceSectorSize(MountDevice, &SectorSize)) 90 { 91 /* Try to read the BPB */ 92 if (FsRecReadBlock(MountDevice, 93 &Offset, 94 512, 95 SectorSize, 96 (PVOID)&Bpb, 97 &DeviceError)) 98 { 99 /* Check if it's an actual FAT volume */ 100 if (FsRecIsFatxVolume(Bpb)) 101 { 102 /* It is! */ 103 Status = STATUS_FS_DRIVER_REQUIRED; 104 } 105 } 106 107 /* Free the boot sector if we have one */ 108 ExFreePool(Bpb); 109 } 110 111 break; 112 113 case IRP_MN_LOAD_FILE_SYSTEM: 114 115 /* Load the file system */ 116 Status = FsRecLoadFileSystem(DeviceObject, 117 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\vfatfs"); 118 break; 119 120 default: 121 122 /* Invalid request */ 123 Status = STATUS_INVALID_DEVICE_REQUEST; 124 } 125 126 /* Return Status */ 127 return Status; 128 } 129 130 /* EOF */ 131