xref: /reactos/drivers/filesystems/fs_rec/fatx.c (revision 5efb6e3d)
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