reactos/drivers/filesystems/fs_rec/ffs.c

220 lines
8.2 KiB
C

/*
* 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 <debug.h>
/* 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;
}