mirror of
https://github.com/reactos/reactos.git
synced 2024-12-19 00:53:33 +08:00
221 lines
8.2 KiB
C
221 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;
|
|
}
|