1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS File System Recognizer 4 * FILE: drivers/filesystems/fs_rec/fat.c 5 * PURPOSE: FAT Recognizer 6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org) 7 * Eric Kohl 8 */ 9 10 /* INCLUDES *****************************************************************/ 11 12 #include "fs_rec.h" 13 14 #define NDEBUG 15 #include <debug.h> 16 17 /* FUNCTIONS ****************************************************************/ 18 19 BOOLEAN 20 NTAPI 21 FsRecIsFatVolume(IN PPACKED_BOOT_SECTOR PackedBootSector) 22 { 23 BIOS_PARAMETER_BLOCK Bpb; 24 BOOLEAN Result = TRUE; 25 PAGED_CODE(); 26 27 RtlZeroMemory(&Bpb, sizeof(BIOS_PARAMETER_BLOCK)); 28 29 /* Unpack the BPB and do a small fix up */ 30 FatUnpackBios(&Bpb, &PackedBootSector->PackedBpb); 31 if (Bpb.Sectors) Bpb.LargeSectors = 0; 32 33 /* Recognize jump */ 34 if ((PackedBootSector->Jump[0] != 0x49) && 35 (PackedBootSector->Jump[0] != 0xE9) && 36 (PackedBootSector->Jump[0] != 0xEB)) 37 { 38 /* Fail */ 39 Result = FALSE; 40 } 41 else if ((Bpb.BytesPerSector != 128) && 42 (Bpb.BytesPerSector != 256) && 43 (Bpb.BytesPerSector != 512) && 44 (Bpb.BytesPerSector != 1024) && 45 (Bpb.BytesPerSector != 2048) && 46 (Bpb.BytesPerSector != 4096)) 47 { 48 /* Fail */ 49 Result = FALSE; 50 } 51 else if ((Bpb.SectorsPerCluster != 1) && 52 (Bpb.SectorsPerCluster != 2) && 53 (Bpb.SectorsPerCluster != 4) && 54 (Bpb.SectorsPerCluster != 8) && 55 (Bpb.SectorsPerCluster != 16) && 56 (Bpb.SectorsPerCluster != 32) && 57 (Bpb.SectorsPerCluster != 64) && 58 (Bpb.SectorsPerCluster != 128)) 59 { 60 /* Fail */ 61 Result = FALSE; 62 } 63 else if (!Bpb.ReservedSectors) 64 { 65 /* Fail */ 66 Result = FALSE; 67 } 68 else if (!(Bpb.Sectors) && !(Bpb.LargeSectors)) 69 { 70 /* Fail */ 71 Result = FALSE; 72 } 73 else if ((Bpb.Media != 0x00) && 74 (Bpb.Media != 0x01) && 75 (Bpb.Media != 0xf0) && 76 (Bpb.Media != 0xf8) && 77 (Bpb.Media != 0xf9) && 78 (Bpb.Media != 0xfa) && 79 (Bpb.Media != 0xfb) && 80 (Bpb.Media != 0xfc) && 81 (Bpb.Media != 0xfd) && 82 (Bpb.Media != 0xfe) && 83 (Bpb.Media != 0xff)) 84 { 85 /* Fail */ 86 Result = FALSE; 87 } 88 else if ((Bpb.SectorsPerFat) && !(Bpb.RootEntries)) 89 { 90 /* Fail */ 91 Result = FALSE; 92 } 93 94 /* Return the result */ 95 return Result; 96 } 97 98 NTSTATUS 99 NTAPI 100 FsRecVfatFsControl(IN PDEVICE_OBJECT DeviceObject, 101 IN PIRP Irp) 102 { 103 PIO_STACK_LOCATION Stack; 104 NTSTATUS Status; 105 PDEVICE_OBJECT MountDevice; 106 PPACKED_BOOT_SECTOR Bpb = NULL; 107 ULONG SectorSize; 108 LARGE_INTEGER Offset = {{0, 0}}; 109 BOOLEAN DeviceError = FALSE; 110 PAGED_CODE(); 111 112 /* Get the I/O Stack and check the function type */ 113 Stack = IoGetCurrentIrpStackLocation(Irp); 114 switch (Stack->MinorFunction) 115 { 116 case IRP_MN_MOUNT_VOLUME: 117 118 /* Assume failure */ 119 Status = STATUS_UNRECOGNIZED_VOLUME; 120 121 /* Get the device object and request the sector size */ 122 MountDevice = Stack->Parameters.MountVolume.DeviceObject; 123 if (FsRecGetDeviceSectorSize(MountDevice, &SectorSize)) 124 { 125 /* Try to read the BPB */ 126 if (FsRecReadBlock(MountDevice, 127 &Offset, 128 512, 129 SectorSize, 130 (PVOID)&Bpb, 131 &DeviceError)) 132 { 133 /* Check if it's an actual FAT volume */ 134 if (FsRecIsFatVolume(Bpb)) 135 { 136 /* It is! */ 137 Status = STATUS_FS_DRIVER_REQUIRED; 138 } 139 } 140 141 /* Free the boot sector if we have one */ 142 ExFreePool(Bpb); 143 } 144 else 145 { 146 /* We have some sort of failure in the storage stack */ 147 DeviceError = TRUE; 148 } 149 150 /* Check if we have an error on the stack */ 151 if (DeviceError) 152 { 153 /* Was this because of a floppy? */ 154 if (MountDevice->Characteristics & FILE_FLOPPY_DISKETTE) 155 { 156 /* Let the FS try anyway */ 157 Status = STATUS_FS_DRIVER_REQUIRED; 158 } 159 } 160 161 break; 162 163 case IRP_MN_LOAD_FILE_SYSTEM: 164 165 /* Load the file system */ 166 Status = FsRecLoadFileSystem(DeviceObject, 167 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\fastfat"); 168 break; 169 170 default: 171 172 /* Invalid request */ 173 Status = STATUS_INVALID_DEVICE_REQUEST; 174 } 175 176 /* Return Status */ 177 return Status; 178 } 179 180 /* EOF */ 181