/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS File System Recognizer * FILE: drivers/filesystems/fs_rec/ffs.c * PURPOSE: FFS Recognizer * PROGRAMMER: Peter Hater * Pierre Schweitzer (pierre@reactos.org) */ /* INCLUDES *****************************************************************/ #include "fs_rec.h" #include "ffs.h" #define NDEBUG #include /* FUNCTIONS ****************************************************************/ BOOLEAN NTAPI FsRecIsFfsDiskLabel(IN PFFSD_DISKLABEL dl) { return (dl->d_magic == DISKMAGIC); } BOOLEAN NTAPI FsRecIsFfs1Volume(IN PFFSD_SUPER_BLOCK sb) { return (sb->fs_magic == FS_UFS1_MAGIC); } BOOLEAN NTAPI FsRecIsFfs2Volume(IN PFFSD_SUPER_BLOCK sb) { return (sb->fs_magic == FS_UFS2_MAGIC); } NTSTATUS NTAPI FsRecFfsFsControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION Stack; NTSTATUS Status; PDEVICE_OBJECT MountDevice; PFFSD_SUPER_BLOCK Spb = NULL; PFFSD_DISKLABEL DiskLabel = NULL; ULONGLONG FSOffset = 0; int i; ULONG SectorSize; LARGE_INTEGER Offset; 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 disklabel */ Offset.QuadPart = LABELSECTOR*SectorSize; if (FsRecReadBlock(MountDevice, &Offset, SectorSize, SectorSize, (PVOID)&DiskLabel, &DeviceError)) { /* Check if it's an actual FFS disk label */ if (FsRecIsFfsDiskLabel(DiskLabel)) { /* It is! */ for (i = 0; i < MAXPARTITIONS; i++) { if (DiskLabel->d_partitions[i].p_fstype == FS_BSDFFS) { /* Important */ FSOffset = DiskLabel->d_partitions[i].p_offset; FSOffset = FSOffset * SectorSize; /* Try to read the superblock */ Offset.QuadPart = FSOffset+SBLOCK_UFS1; if (FsRecReadBlock(MountDevice, &Offset, SBLOCKSIZE, SectorSize, (PVOID)&Spb, &DeviceError)) { /* Check if it's an actual FFS volume */ if (FsRecIsFfs1Volume(Spb)) { /* It is! */ Status = STATUS_FS_DRIVER_REQUIRED; } else { /* Free the boot sector if we have one */ ExFreePool(Spb); Spb = NULL; Offset.QuadPart = FSOffset+SBLOCK_UFS2; if (FsRecReadBlock(MountDevice, &Offset, SBLOCKSIZE, SectorSize, (PVOID)&Spb, &DeviceError)) { /* Check if it's an actual FFS volume */ if (FsRecIsFfs2Volume(Spb)) { /* It is! */ Status = STATUS_FS_DRIVER_REQUIRED; } } } } /* Free the boot sector if we have one */ ExFreePool(Spb); Spb = NULL; } } } else { /* Try to read the superblock */ Offset.QuadPart = FSOffset+SBLOCK_UFS1; if (FsRecReadBlock(MountDevice, &Offset, SBLOCKSIZE, SectorSize, (PVOID)&Spb, &DeviceError)) { /* Check if it's an actual FFS volume */ if (FsRecIsFfs1Volume(Spb)) { /* It is! */ Status = STATUS_FS_DRIVER_REQUIRED; } else { /* Free the boot sector if we have one */ ExFreePool(Spb); Spb = NULL; Offset.QuadPart = FSOffset+SBLOCK_UFS2; if (FsRecReadBlock(MountDevice, &Offset, SBLOCKSIZE, SectorSize, (PVOID)&Spb, &DeviceError)) { /* Check if it's an actual FFS volume */ if (FsRecIsFfs2Volume(Spb)) { /* It is! */ Status = STATUS_FS_DRIVER_REQUIRED; } } } } /* Free the boot sector if we have one */ ExFreePool(Spb); Spb = NULL; } } /* Free the boot sector if we have one */ ExFreePool(DiskLabel); } else { /* We have some sort of failure in the storage stack */ DeviceError = TRUE; } /* Check if we have an error on the stack */ if (DeviceError) { /* Was this because of a floppy? */ if (MountDevice->Characteristics & FILE_FLOPPY_DISKETTE) { /* Let the FS try anyway */ Status = STATUS_FS_DRIVER_REQUIRED; } } break; case IRP_MN_LOAD_FILE_SYSTEM: /* Load the file system */ Status = FsRecLoadFileSystem(DeviceObject, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\ffs"); break; default: /* Invalid request */ Status = STATUS_INVALID_DEVICE_REQUEST; } /* Return Status */ return Status; }