Author: ion
Date: Thu Apr 5 04:11:35 2007
New Revision: 26266
URL:
http://svn.reactos.org/svn/reactos?rev=26266&view=rev
Log:
- Refactored some parts of the FS Recognizer Driver.
- Added support for some more advanced storage stack support.
- Added locking and states.
- Added the ability for a file system to span across different device types (such as UDFS
which is both for disks and optical media)
- Updated NTFS, UDFS validation to use new functions. CDFS validation was removed (NT
doesn't do it).
- Improved some parts of FAT validation and relaxed others to match NT's.
Modified:
trunk/reactos/drivers/filesystems/fs_rec/blockdev.c
trunk/reactos/drivers/filesystems/fs_rec/cdfs.c
trunk/reactos/drivers/filesystems/fs_rec/fat.c
trunk/reactos/drivers/filesystems/fs_rec/fs_rec.c
trunk/reactos/drivers/filesystems/fs_rec/fs_rec.h
trunk/reactos/drivers/filesystems/fs_rec/ntfs.c
trunk/reactos/drivers/filesystems/fs_rec/udfs.c
Modified: trunk/reactos/drivers/filesystems/fs_rec/blockdev.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fs_rec…
==============================================================================
--- trunk/reactos/drivers/filesystems/fs_rec/blockdev.c (original)
+++ trunk/reactos/drivers/filesystems/fs_rec/blockdev.c Thu Apr 5 04:11:35 2007
@@ -1,162 +1,224 @@
-/*
- * ReactOS kernel
- * Copyright (C) 2002 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: services/fs/fs_rec/blockdev.c
- * PURPOSE: Filesystem recognizer driver
- * PROGRAMMER: Eric Kohl
+ * PROJECT: ReactOS File System Recognizer
+ * FILE: drivers/filesystems/fs_rec/blockdev.c
+ * PURPOSE: Generic Helper Functions
+ * PROGRAMMER: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Eric Kohl
*/
/* INCLUDES *****************************************************************/
+#include "fs_rec.h"
#define NDEBUG
#include <debug.h>
-#include "fs_rec.h"
-
-
/* FUNCTIONS ****************************************************************/
-NTSTATUS
-FsRecReadSectors(IN PDEVICE_OBJECT DeviceObject,
- IN ULONG DiskSector,
- IN ULONG SectorCount,
- IN ULONG SectorSize,
- IN OUT PUCHAR Buffer)
+BOOLEAN
+NTAPI
+FsRecGetDeviceSectors(IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SectorSize,
+ OUT PLARGE_INTEGER SectorCount)
{
- IO_STATUS_BLOCK IoStatus;
- LARGE_INTEGER Offset;
- ULONG BlockSize;
- PKEVENT Event;
- PIRP Irp;
- NTSTATUS Status;
-
- Event = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
- if (Event == NULL)
- {
- return(STATUS_INSUFFICIENT_RESOURCES);
- }
-
- KeInitializeEvent(Event,
- NotificationEvent,
- FALSE);
-
- Offset.QuadPart = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
- BlockSize = SectorCount * SectorSize;
-
- DPRINT("FsrecReadSectors(DeviceObject %x, DiskSector %d, Buffer %x)\n",
- DeviceObject, DiskSector, Buffer);
- DPRINT("Offset %I64x BlockSize %ld\n",
- Offset.QuadPart,
- BlockSize);
-
- DPRINT("Building synchronous FSD Request...\n");
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
- DeviceObject,
- Buffer,
- BlockSize,
- &Offset,
- Event,
- &IoStatus);
- if (Irp == NULL)
- {
- DPRINT("IoBuildSynchronousFsdRequest failed\n");
- ExFreePool(Event);
- return(STATUS_INSUFFICIENT_RESOURCES);
- }
-
- DPRINT("Calling IO Driver... with irp %x\n", Irp);
- Status = IoCallDriver(DeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- DPRINT("Operation pending\n");
- KeWaitForSingleObject(Event, Suspended, KernelMode, FALSE, NULL);
- Status = IoStatus.Status;
- }
-
- ExFreePool(Event);
-
- return(STATUS_SUCCESS);
+ PARTITION_INFORMATION PartitionInfo;
+ IO_STATUS_BLOCK IoStatusBlock;
+ KEVENT Event;
+ PIRP Irp;
+ NTSTATUS Status;
+ ULONG Remainder;
+ PAGED_CODE();
+
+ /* Only needed for disks */
+ if (DeviceObject->DeviceType != FILE_DEVICE_DISK) return FALSE;
+
+ /* Build the information IRP */
+ KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
+ Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO,
+ DeviceObject,
+ NULL,
+ 0,
+ &PartitionInfo,
+ sizeof(PARTITION_INFORMATION),
+ FALSE,
+ &Event,
+ &IoStatusBlock);
+ if (!Irp) return FALSE;
+
+ /* Override verification */
+ IoGetNextIrpStackLocation(Irp)->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
+
+ /* Do the request */
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ /* Wait for completion */
+ KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ /* Fail if we couldn't get the data */
+ if (!NT_SUCCESS(Status)) return FALSE;
+
+ /* Otherwise, return the number of sectors */
+ *SectorCount = RtlExtendedLargeIntegerDivide(PartitionInfo.PartitionLength,
+ SectorSize,
+ &Remainder);
+ return TRUE;
}
-
-NTSTATUS
-FsRecDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
- IN ULONG ControlCode,
- IN PVOID InputBuffer,
- IN ULONG InputBufferSize,
- IN OUT PVOID OutputBuffer,
- IN OUT PULONG OutputBufferSize)
+BOOLEAN
+NTAPI
+FsRecGetDeviceSectorSize(IN PDEVICE_OBJECT DeviceObject,
+ OUT PULONG SectorSize)
{
- ULONG BufferSize = 0;
- PKEVENT Event;
- PIRP Irp;
- IO_STATUS_BLOCK IoStatus;
- NTSTATUS Status;
-
- if (OutputBufferSize != NULL)
- {
- BufferSize = *OutputBufferSize;
- }
-
- Event = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
- if (Event == NULL)
- {
- return(STATUS_INSUFFICIENT_RESOURCES);
- }
-
- KeInitializeEvent(Event, NotificationEvent, FALSE);
-
- DPRINT("Building device I/O control request ...\n");
- Irp = IoBuildDeviceIoControlRequest(ControlCode,
- DeviceObject,
- InputBuffer,
- InputBufferSize,
- OutputBuffer,
- BufferSize,
- FALSE,
- Event,
- &IoStatus);
- if (Irp == NULL)
- {
- DPRINT("IoBuildDeviceIoControlRequest() failed\n");
- ExFreePool(Event);
- return(STATUS_INSUFFICIENT_RESOURCES);
- }
-
- DPRINT("Calling IO Driver... with irp %x\n", Irp);
- Status = IoCallDriver(DeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject(Event, Suspended, KernelMode, FALSE, NULL);
- Status = IoStatus.Status;
- }
-
- if (OutputBufferSize != NULL)
- {
- *OutputBufferSize = IoStatus.Information;
- }
-
- ExFreePool(Event);
-
- return(Status);
+ DISK_GEOMETRY DiskGeometry;
+ IO_STATUS_BLOCK IoStatusBlock;
+ KEVENT Event;
+ PIRP Irp;
+ NTSTATUS Status;
+ ULONG ControlCode;
+ PAGED_CODE();
+
+ /* Check what device we have */
+ switch (DeviceObject->DeviceType)
+ {
+ case FILE_DEVICE_CD_ROM:
+
+ /* Use the CD IOCTL */
+ ControlCode = IOCTL_CDROM_GET_DRIVE_GEOMETRY;
+ break;
+
+ case FILE_DEVICE_DISK:
+
+ /* Use the Disk IOCTL */
+ ControlCode = IOCTL_DISK_GET_DRIVE_GEOMETRY;
+ break;
+
+ default:
+
+ /* Invalid device type */
+ return FALSE;
+ }
+
+ /* Build the information IRP */
+ KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
+ Irp = IoBuildDeviceIoControlRequest(ControlCode,
+ DeviceObject,
+ NULL,
+ 0,
+ &DiskGeometry,
+ sizeof(DISK_GEOMETRY),
+ FALSE,
+ &Event,
+ &IoStatusBlock);
+ if (!Irp) return FALSE;
+
+ /* Override verification */
+ IoGetNextIrpStackLocation(Irp)->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
+
+ /* Do the request */
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ /* Wait for completion */
+ KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ /* Fail if we couldn't get the data */
+ if (!NT_SUCCESS(Status)) return FALSE;
+
+ /* Return the sector size if it's valid */
+ if (!DiskGeometry.BytesPerSector) return FALSE;
+ *SectorSize = DiskGeometry.BytesPerSector;
+ return TRUE;
}
-/* EOF */
+BOOLEAN
+NTAPI
+FsRecReadBlock(IN PDEVICE_OBJECT DeviceObject,
+ IN PLARGE_INTEGER Offset,
+ IN ULONG Length,
+ IN ULONG SectorSize,
+ IN OUT PVOID *Buffer,
+ OUT PBOOLEAN DeviceError OPTIONAL)
+{
+ IO_STATUS_BLOCK IoStatusBlock;
+ KEVENT Event;
+ PIRP Irp;
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ /* Assume failure */
+ if (DeviceError) *DeviceError = FALSE;
+
+ /* Check if the caller requested too little */
+ if (Length < SectorSize)
+ {
+ /* Read at least the sector size */
+ Length = SectorSize;
+ }
+ else
+ {
+ /* Otherwise, just round up the request to sector size */
+ Length = ROUND_UP(Length, SectorSize);
+ }
+
+ /* Check if the caller gave us a buffer */
+ if (!*Buffer)
+ {
+ /* He didn't, allocate one */
+ *Buffer = ExAllocatePoolWithTag(NonPagedPool,
+ PAGE_ROUND_UP(Length),
+ FSREC_TAG);
+ if (!*Buffer) return FALSE;
+ }
+
+ /* Build the IRP */
+ KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
+ DeviceObject,
+ *Buffer,
+ Length,
+ Offset,
+ &Event,
+ &IoStatusBlock);
+ if (!Irp) return FALSE;
+
+ /* Override verification */
+ IoGetNextIrpStackLocation(Irp)->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
+
+ /* Do the request */
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ /* Wait for completion */
+ KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ /* Check if we couldn't get the data */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Check if caller wanted to know about the device and fail */
+ if (DeviceError) *DeviceError = TRUE;
+ return FALSE;
+ }
+
+ /* All went well */
+ return TRUE;
+}
+
Modified: trunk/reactos/drivers/filesystems/fs_rec/cdfs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fs_rec…
==============================================================================
--- trunk/reactos/drivers/filesystems/fs_rec/cdfs.c (original)
+++ trunk/reactos/drivers/filesystems/fs_rec/cdfs.c Thu Apr 5 04:11:35 2007
@@ -1,140 +1,54 @@
-/*
- * ReactOS kernel
- * Copyright (C) 2002 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: services/fs/fs_rec/cdfs.c
- * PURPOSE: Filesystem recognizer driver
- * PROGRAMMER: Eric Kohl
+ * PROJECT: ReactOS File System Recognizer
+ * FILE: drivers/filesystems/fs_rec/cdfs.c
+ * PURPOSE: CDFS Recognizer
+ * PROGRAMMER: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Eric Kohl
*/
/* INCLUDES *****************************************************************/
+#include "fs_rec.h"
#define NDEBUG
#include <debug.h>
-#include "fs_rec.h"
-
-
-#define CDFS_PVD_SECTOR 16
-
/* FUNCTIONS ****************************************************************/
-static NTSTATUS
-FsRecIsCdfsVolume(IN PDEVICE_OBJECT DeviceObject)
+NTSTATUS
+NTAPI
+FsRecCdfsFsControl(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- DISK_GEOMETRY DiskGeometry;
- PUCHAR Buffer;
- NTSTATUS Status;
- ULONG Size;
+ PIO_STACK_LOCATION Stack;
+ NTSTATUS Status;
+ PAGED_CODE();
- Size = sizeof(DISK_GEOMETRY);
- Status = FsRecDeviceIoControl(DeviceObject,
- IOCTL_CDROM_GET_DRIVE_GEOMETRY,
- NULL,
- 0,
- &DiskGeometry,
- &Size);
- if (!NT_SUCCESS(Status))
+ /* Get the I/O Stack and check the function type */
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ switch (Stack->MinorFunction)
{
- DPRINT("FsRecDeviceIoControl() failed (Status %lx)\n", Status);
- return(Status);
+ case IRP_MN_MOUNT_VOLUME:
+
+ /* We don't validate */
+ 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\\Cdfs");
+ break;
+
+ default:
+
+ /* Invalid request */
+ Status = STATUS_INVALID_DEVICE_REQUEST;
}
- DPRINT("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector);
- Buffer = ExAllocatePool(NonPagedPool,
- DiskGeometry.BytesPerSector);
- if (Buffer == NULL)
- {
- return(STATUS_INSUFFICIENT_RESOURCES);
- }
-
- Status = FsRecReadSectors(DeviceObject,
- CDFS_PVD_SECTOR,
- 1,
- DiskGeometry.BytesPerSector,
- Buffer);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("FsRecReadSectors() failed (Status %lx)\n", Status);
- ExFreePool(Buffer);
- return(Status);
- }
-
- Buffer[6] = 0;
- DPRINT("CD-identifier: [%.5s]\n", Buffer + 1);
-
- Status = (Buffer[0] == 1 &&
- Buffer[1] == 'C' &&
- Buffer[2] == 'D' &&
- Buffer[3] == '0' &&
- Buffer[4] == '0' &&
- Buffer[5] == '1') ? STATUS_SUCCESS : STATUS_UNRECOGNIZED_VOLUME;
-
- ExFreePool(Buffer);
-
- return(Status);
-}
-
-
-NTSTATUS
-FsRecCdfsFsControl(IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION Stack;
- static UNICODE_STRING RegistryPath =
-
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Cdfs");
- NTSTATUS Status;
-
- Stack = IoGetCurrentIrpStackLocation(Irp);
-
- switch (Stack->MinorFunction)
- {
- case IRP_MN_MOUNT_VOLUME:
- DPRINT("Cdfs: IRP_MN_MOUNT_VOLUME\n");
- Status = FsRecIsCdfsVolume(Stack->Parameters.MountVolume.DeviceObject);
- if (NT_SUCCESS(Status))
- {
- DPRINT("Identified CDFS volume\n");
- Status = STATUS_FS_DRIVER_REQUIRED;
- }
- break;
-
- case IRP_MN_LOAD_FILE_SYSTEM:
- DPRINT("Cdfs: IRP_MN_LOAD_FILE_SYSTEM\n");
- Status = ZwLoadDriver(&RegistryPath);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwLoadDriver failed (Status %x)\n", Status);
- }
- else
- {
- IoUnregisterFileSystem(DeviceObject);
- }
- break;
-
- default:
- DPRINT("Cdfs: Unknown minor function %lx\n", Stack->MinorFunction);
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
- }
- return(Status);
+ /* Return Status */
+ return Status;
}
/* EOF */
Modified: trunk/reactos/drivers/filesystems/fs_rec/fat.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fs_rec…
==============================================================================
--- trunk/reactos/drivers/filesystems/fs_rec/fat.c (original)
+++ trunk/reactos/drivers/filesystems/fs_rec/fat.c Thu Apr 5 04:11:35 2007
@@ -1,224 +1,177 @@
-/*
- * ReactOS kernel
- * Copyright (C) 2002,2003 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: drivers/fs/fs_rec/vfat.c
- * PURPOSE: Filesystem recognizer driver
- * PROGRAMMER: Eric Kohl
+ * PROJECT: ReactOS File System Recognizer
+ * FILE: drivers/filesystems/fs_rec/fat.c
+ * PURPOSE: FAT Recognizer
+ * PROGRAMMER: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Eric Kohl
*/
/* INCLUDES *****************************************************************/
+#include "fs_rec.h"
#define NDEBUG
#include <debug.h>
-#include "fs_rec.h"
-
-
/* FUNCTIONS ****************************************************************/
-static NTSTATUS
-FsRecIsFatVolume(IN PDEVICE_OBJECT DeviceObject)
+NTSTATUS
+NTAPI
+FsRecIsFatVolume(IN PPACKED_BOOT_SECTOR PackedBootSector)
{
- NTSTATUS Status;
- PARTITION_INFORMATION PartitionInfo;
- DISK_GEOMETRY DiskGeometry;
- ULONG Size;
- struct _BootSector* Boot;
- BOOLEAN RecognizedFS = FALSE;
- Size = sizeof(DISK_GEOMETRY);
+ BIOS_PARAMETER_BLOCK Bpb;
+ BOOLEAN Result = TRUE;
+ PAGED_CODE();
- Status = FsRecDeviceIoControl(DeviceObject,
- IOCTL_DISK_GET_DRIVE_GEOMETRY,
- NULL,
- 0,
- &DiskGeometry,
- &Size);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("FsRecDeviceIoControl faild (%x)\n", Status);
- return Status;
- }
- if (DiskGeometry.MediaType == FixedMedia || DiskGeometry.MediaType == RemovableMedia)
- {
- // We have found a hard disk
- Size = sizeof(PARTITION_INFORMATION);
- Status = FsRecDeviceIoControl(DeviceObject,
- IOCTL_DISK_GET_PARTITION_INFO,
- NULL,
- 0,
- &PartitionInfo,
- &Size);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("FsRecDeviceIoControl faild (%x)\n", Status);
- return Status;
- }
+ /* Unpack the BPB and do a small fix up */
+ FatUnpackBios(&Bpb, &PackedBootSector->PackedBpb);
+ if (Bpb.Sectors) Bpb.LargeSectors = 0;
- if (PartitionInfo.PartitionType)
- {
- if (PartitionInfo.PartitionType == PARTITION_FAT_12 ||
- PartitionInfo.PartitionType == PARTITION_FAT_16 ||
- PartitionInfo.PartitionType == PARTITION_HUGE ||
- PartitionInfo.PartitionType == PARTITION_FAT32 ||
- PartitionInfo.PartitionType == PARTITION_FAT32_XINT13 ||
- PartitionInfo.PartitionType == PARTITION_XINT13)
- {
- RecognizedFS = TRUE;
- }
- }
- else if (DiskGeometry.MediaType == RemovableMedia &&
- PartitionInfo.PartitionNumber > 0 &&
- PartitionInfo.StartingOffset.QuadPart == 0 &&
- PartitionInfo.PartitionLength.QuadPart > 0)
- {
- /* This is possible a removable media formated as super floppy */
- RecognizedFS = TRUE;
- }
- }
- if (DiskGeometry.MediaType > Unknown && DiskGeometry.MediaType <
RemovableMedia )
- {
- RecognizedFS = TRUE;
- }
- if (RecognizedFS == FALSE)
- {
- return STATUS_UNRECOGNIZED_VOLUME;
- }
+ /* Recognize jump */
+ if ((PackedBootSector->Jump[0] != 0x49) &&
+ (PackedBootSector->Jump[0] != 0xE9) &&
+ (PackedBootSector->Jump[0] != 0xEB))
+ {
+ /* Fail */
+ Result = FALSE;
+ }
+ else if ((Bpb.BytesPerSector != 128) &&
+ (Bpb.BytesPerSector != 256) &&
+ (Bpb.BytesPerSector != 512) &&
+ (Bpb.BytesPerSector != 1024) &&
+ (Bpb.BytesPerSector != 2048) &&
+ (Bpb.BytesPerSector != 4096))
+ {
+ /* Fail */
+ Result = FALSE;
+ }
+ else if ((Bpb.SectorsPerCluster != 1) &&
+ (Bpb.SectorsPerCluster != 2) &&
+ (Bpb.SectorsPerCluster != 4) &&
+ (Bpb.SectorsPerCluster != 8) &&
+ (Bpb.SectorsPerCluster != 16) &&
+ (Bpb.SectorsPerCluster != 32) &&
+ (Bpb.SectorsPerCluster != 64) &&
+ (Bpb.SectorsPerCluster != 128))
+ {
+ /* Fail */
+ Result = FALSE;
+ }
+ else if (!Bpb.ReservedSectors)
+ {
+ /* Fail */
+ Result = FALSE;
+ }
+ else if (!(Bpb.Sectors) && !(Bpb.LargeSectors))
+ {
+ /* Fail */
+ Result = FALSE;
+ }
+ else if ((Bpb.Media != 0x00) &&
+ (Bpb.Media != 0x01) &&
+ (Bpb.Media != 0xf0) &&
+ (Bpb.Media != 0xf8) &&
+ (Bpb.Media != 0xf9) &&
+ (Bpb.Media != 0xfa) &&
+ (Bpb.Media != 0xfb) &&
+ (Bpb.Media != 0xfc) &&
+ (Bpb.Media != 0xfd) &&
+ (Bpb.Media != 0xfe) &&
+ (Bpb.Media != 0xff))
+ {
+ /* Fail */
+ Result = FALSE;
+ }
+ else if ((Bpb.SectorsPerFat) && !(Bpb.RootEntries))
+ {
+ /* Fail */
+ Result = FALSE;
+ }
- Boot = ExAllocatePool(NonPagedPool, DiskGeometry.BytesPerSector);
- if (Boot == NULL)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- Status = FsRecReadSectors(DeviceObject,
- 0,
- 1,
- DiskGeometry.BytesPerSector,
- (PUCHAR) Boot);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- if (Boot->Signatur1 != 0xaa55)
- {
- RecognizedFS=FALSE;
- }
- if (RecognizedFS &&
- Boot->BytesPerSector != 512 &&
- Boot->BytesPerSector != 1024 &&
- Boot->BytesPerSector != 2048 &&
- Boot->BytesPerSector == 4096)
- {
- RecognizedFS=FALSE;
- }
-
- if (RecognizedFS &&
- Boot->FATCount != 1 &&
- Boot->FATCount != 2)
- {
- RecognizedFS=FALSE;
- }
-
- if (RecognizedFS &&
- Boot->Media != 0xf0 &&
- Boot->Media != 0xf8 &&
- Boot->Media != 0xf9 &&
- Boot->Media != 0xfa &&
- Boot->Media != 0xfb &&
- Boot->Media != 0xfc &&
- Boot->Media != 0xfd &&
- Boot->Media != 0xfe &&
- Boot->Media != 0xff)
- {
- RecognizedFS=FALSE;
- }
-
- if (RecognizedFS &&
- Boot->SectorsPerCluster != 1 &&
- Boot->SectorsPerCluster != 2 &&
- Boot->SectorsPerCluster != 4 &&
- Boot->SectorsPerCluster != 8 &&
- Boot->SectorsPerCluster != 16 &&
- Boot->SectorsPerCluster != 32 &&
- Boot->SectorsPerCluster != 64 &&
- Boot->SectorsPerCluster != 128)
- {
- RecognizedFS=FALSE;
- }
-
- if (RecognizedFS &&
- Boot->BytesPerSector * Boot->SectorsPerCluster > 32 * 1024)
- {
- RecognizedFS=FALSE;
- }
-
-
- ExFreePool(Boot);
- return RecognizedFS ? STATUS_SUCCESS : STATUS_UNRECOGNIZED_VOLUME;
+ /* Return the result */
+ return Result;
}
+NTSTATUS
+NTAPI
+FsRecVfatFsControl(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION Stack;
+ NTSTATUS Status;
+ PDEVICE_OBJECT MountDevice;
+ PPACKED_BOOT_SECTOR Bpb = NULL;
+ ULONG SectorSize;
+ LARGE_INTEGER Offset = {{0}};
+ BOOLEAN DeviceError = FALSE;
+ PAGED_CODE();
-NTSTATUS
-FsRecVfatFsControl(IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION Stack;
- static UNICODE_STRING RegistryPath =
-
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Vfatfs");
- NTSTATUS Status;
+ /* Get the I/O Stack and check the function type */
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ switch (Stack->MinorFunction)
+ {
+ case IRP_MN_MOUNT_VOLUME:
- Stack = IoGetCurrentIrpStackLocation(Irp);
+ /* Assume failure */
+ Status = STATUS_UNRECOGNIZED_VOLUME;
- switch (Stack->MinorFunction)
- {
- case IRP_MN_MOUNT_VOLUME:
- DPRINT("FAT: IRP_MN_MOUNT_VOLUME\n");
- Status = FsRecIsFatVolume(Stack->Parameters.MountVolume.DeviceObject);
- if (NT_SUCCESS(Status))
- {
- DPRINT("Identified FAT volume\n");
- Status = STATUS_FS_DRIVER_REQUIRED;
- }
- break;
+ /* Get the device object and request the sector size */
+ MountDevice = Stack->Parameters.MountVolume.DeviceObject;
+ if (FsRecGetDeviceSectorSize(MountDevice, &SectorSize))
+ {
+ /* Try to read the BPB */
+ if (FsRecReadBlock(MountDevice,
+ &Offset,
+ 512,
+ SectorSize,
+ (PVOID)&Bpb,
+ &DeviceError))
+ {
+ /* Check if it's an actual FAT volume */
+ if (FsRecIsFatVolume(Bpb))
+ {
+ /* It is! */
+ Status = STATUS_FS_DRIVER_REQUIRED;
+ }
+ }
- case IRP_MN_LOAD_FILE_SYSTEM:
- DPRINT("FAT: IRP_MN_LOAD_FILE_SYSTEM\n");
- Status = ZwLoadDriver(&RegistryPath);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwLoadDriver failed (Status %x)\n", Status);
- }
- else
- {
- IoUnregisterFileSystem(DeviceObject);
- }
- break;
+ /* Free the boot sector if we have one */
+ ExFreePool(Bpb);
+ }
+ else
+ {
+ /* We have some sort of failure in the storage stack */
+ DeviceError = TRUE;
+ }
- default:
- DPRINT("FAT: Unknown minor function %lx\n", Stack->MinorFunction);
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
+ /* 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\\Vfatfs");
+ break;
+
+ default:
+
+ /* Invalid request */
+ Status = STATUS_INVALID_DEVICE_REQUEST;
}
- return(Status);
+
+ /* Return Status */
+ return Status;
}
/* EOF */
Modified: trunk/reactos/drivers/filesystems/fs_rec/fs_rec.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fs_rec…
==============================================================================
--- trunk/reactos/drivers/filesystems/fs_rec/fs_rec.c (original)
+++ trunk/reactos/drivers/filesystems/fs_rec/fs_rec.c Thu Apr 5 04:11:35 2007
@@ -1,254 +1,362 @@
-/*
- * ReactOS kernel
- * Copyright (C) 2002,2003 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: drivers/fs/fs_rec/fs_rec.c
- * PURPOSE: Filesystem recognizer driver
- * PROGRAMMER: Eric Kohl
+ * PROJECT: ReactOS File System Recognizer
+ * FILE: drivers/filesystems/fs_rec/fs_rec.c
+ * PURPOSE: Main Driver Entrypoint and FS Registration
+ * PROGRAMMER: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Eric Kohl
*/
/* INCLUDES *****************************************************************/
+#include "fs_rec.h"
#define NDEBUG
#include <debug.h>
-#include "fs_rec.h"
-
+PKEVENT FsRecLoadSync;
/* FUNCTIONS ****************************************************************/
-static NTSTATUS STDCALL
+NTSTATUS
+NTAPI
+FsRecLoadFileSystem(IN PDEVICE_OBJECT DeviceObject,
+ IN PWCHAR DriverServiceName)
+{
+ UNICODE_STRING DriverName;
+ PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+ NTSTATUS Status = STATUS_IMAGE_ALREADY_LOADED;
+ PAGED_CODE();
+
+ /* Make sure we haven't already been called */
+ if (DeviceExtension->State != Loaded)
+ {
+ /* Acquire the load lock */
+ KeWaitForSingleObject(FsRecLoadSync,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ KeEnterCriticalRegion();
+
+ /* Make sure we're active */
+ if (DeviceExtension->State == Pending)
+ {
+ /* Load the FS driver */
+ RtlInitUnicodeString(&DriverName, DriverServiceName);
+ Status = ZwLoadDriver(&DriverName);
+
+ /* Loop all the linked recognizer objects */
+ while (DeviceExtension->State != Unloading)
+ {
+ /* Set them to the unload state */
+ DeviceExtension->State = Unloading;
+
+ /* Go to the next one */
+ DeviceObject = DeviceExtension->Alternate;
+ DeviceExtension = DeviceObject->DeviceExtension;
+ }
+ }
+
+ /* Make sure that we haven't already loaded the FS */
+ if (DeviceExtension->State != Loaded)
+ {
+ /* Unregiser us, and set us as loaded */
+ IoUnregisterFileSystem(DeviceObject);
+ DeviceExtension->State = Loaded;
+ }
+
+ /* Release the lock */
+ KeSetEvent(FsRecLoadSync, 0, FALSE);
+ KeLeaveCriticalRegion();
+ }
+
+ /* Return */
+ return Status;
+}
+
+NTSTATUS
+STDCALL
FsRecCreate(IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- NTSTATUS Status;
-
-
- Status = STATUS_SUCCESS;
-
-
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp,
- IO_NO_INCREMENT);
-
- return(Status);
-}
-
-
-static NTSTATUS STDCALL
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ /* Make sure we have a file name */
+ if (IoStack->FileObject->FileName.Length)
+ {
+ /* Fail the request */
+ Status = STATUS_OBJECT_PATH_NOT_FOUND;
+ }
+ else
+ {
+ /* Let it through */
+ Status = STATUS_SUCCESS;
+ }
+
+ /* Complete the IRP */
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = FILE_OPENED;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+}
+
+NTSTATUS
+STDCALL
FsRecClose(IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- Irp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest(Irp,
- IO_NO_INCREMENT);
-
- return(STATUS_SUCCESS);
-}
-
-
-static NTSTATUS STDCALL
+ IN PIRP Irp)
+{
+ PAGED_CODE();
+
+ /* Just complete the IRP and return success */
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+STDCALL
FsRecFsControl(IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PDEVICE_EXTENSION DeviceExt;
- NTSTATUS Status;
-
- DeviceExt = DeviceObject->DeviceExtension;
- switch (DeviceExt->FsType)
- {
- case FS_TYPE_VFAT:
- Status = FsRecVfatFsControl(DeviceObject, Irp);
- break;
-
- case FS_TYPE_NTFS:
- Status = FsRecNtfsFsControl(DeviceObject, Irp);
- break;
-
- case FS_TYPE_CDFS:
- Status = FsRecCdfsFsControl(DeviceObject, Irp);
- break;
-
- case FS_TYPE_UDFS:
- Status = FsRecUdfsFsControl(DeviceObject, Irp);
- break;
-
- default:
- Status = STATUS_INVALID_DEVICE_REQUEST;
- }
-
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp,
- IO_NO_INCREMENT);
-
- return(Status);
-}
-
-
-static VOID STDCALL
+ IN PIRP Irp)
+{
+ PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ /* Check the file system type */
+ switch (DeviceExtension->FsType)
+ {
+ case FS_TYPE_VFAT:
+
+ /* Send FAT command */
+ Status = FsRecVfatFsControl(DeviceObject, Irp);
+ break;
+
+ case FS_TYPE_NTFS:
+
+ /* Send NTFS command */
+ Status = FsRecNtfsFsControl(DeviceObject, Irp);
+ break;
+
+ case FS_TYPE_CDFS:
+
+ /* Send CDFS command */
+ Status = FsRecCdfsFsControl(DeviceObject, Irp);
+ break;
+
+ case FS_TYPE_UDFS:
+
+ /* Send UDFS command */
+ Status = FsRecUdfsFsControl(DeviceObject, Irp);
+ break;
+
+ default:
+
+ /* Unrecognized FS */
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ /* Complete the IRP */
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+}
+
+VOID
+STDCALL
FsRecUnload(IN PDRIVER_OBJECT DriverObject)
{
- PDEVICE_OBJECT NextDevice;
- PDEVICE_OBJECT ThisDevice;
-
- /* Delete all remaining device objects */
- NextDevice = DriverObject->DeviceObject;
- while (NextDevice != NULL)
- {
- ThisDevice = NextDevice;
- NextDevice = NextDevice->NextDevice;
- IoDeleteDevice(ThisDevice);
- }
-}
-
-
-static NTSTATUS
-FsRecRegisterFs(PDRIVER_OBJECT DriverObject,
- PCWSTR FsName,
- PCWSTR RecognizerName,
- ULONG DeviceType,
- ULONG FsType)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatus;
- PDEVICE_EXTENSION DeviceExt;
- UNICODE_STRING DeviceName;
- UNICODE_STRING FileName;
- PDEVICE_OBJECT DeviceObject;
- HANDLE FileHandle;
- NTSTATUS Status;
-
- RtlInitUnicodeString(&FileName,
- FsName);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &FileName,
- OBJ_CASE_INSENSITIVE,
- 0,
- NULL);
-
- Status = ZwCreateFile(&FileHandle,
- 0x100000,
- &ObjectAttributes,
- &IoStatus,
- NULL,
- 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_OPEN,
- 0,
- NULL,
- 0);
- if (NT_SUCCESS(Status))
- {
- ZwClose(FileHandle);
- return(STATUS_IMAGE_ALREADY_LOADED);
- }
-
- /* Create recognizer device object */
- RtlInitUnicodeString(&DeviceName,
- RecognizerName);
-
- Status = IoCreateDevice(DriverObject,
- sizeof(DEVICE_EXTENSION),
- &DeviceName,
- DeviceType,
- 0,
- FALSE,
- &DeviceObject);
-
- if (NT_SUCCESS(Status))
- {
- DeviceExt = DeviceObject->DeviceExtension;
- DeviceExt->FsType = FsType;
- IoRegisterFileSystem(DeviceObject);
- DPRINT("Created recognizer device '%wZ'\n", &DeviceName);
- }
-
- return(Status);
-}
-
-
-NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT DriverObject,
- PUNICODE_STRING RegistryPath)
-{
- PCONFIGURATION_INFORMATION ConfigInfo;
- ULONG DeviceCount;
- NTSTATUS Status;
-
- DPRINT("FileSystem recognizer 0.0.2\n");
-
- DeviceCount = 0;
-
- DriverObject->MajorFunction[IRP_MJ_CREATE] = FsRecCreate;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsRecClose;
- DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FsRecClose;
- DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FsRecFsControl;
- DriverObject->DriverUnload = FsRecUnload;
-
- ConfigInfo = IoGetConfigurationInformation();
-
- if (ConfigInfo->CdRomCount > 0)
- {
- Status = FsRecRegisterFs(DriverObject,
- L"\\Cdfs",
- L"\\FileSystem\\CdfsRecognizer",
- FILE_DEVICE_CD_ROM_FILE_SYSTEM,
- FS_TYPE_CDFS);
- if (NT_SUCCESS(Status))
- {
- DeviceCount++;
- }
-
- Status = FsRecRegisterFs(DriverObject,
- L"\\Udfs",
- L"\\FileSystem\\UdfsRecognizer",
- FILE_DEVICE_CD_ROM_FILE_SYSTEM,
- FS_TYPE_UDFS);
- if (NT_SUCCESS(Status))
- {
- DeviceCount++;
- }
- }
-
- Status = FsRecRegisterFs(DriverObject,
- L"\\Fat",
- L"\\FileSystem\\FatRecognizer",
- FILE_DEVICE_DISK_FILE_SYSTEM,
- FS_TYPE_VFAT);
- if (NT_SUCCESS(Status))
- {
- DeviceCount++;
- }
-
- Status = FsRecRegisterFs(DriverObject,
- L"\\Ntfs",
- L"\\FileSystem\\NtfsRecognizer",
- FILE_DEVICE_DISK_FILE_SYSTEM,
- FS_TYPE_NTFS);
- if (NT_SUCCESS(Status))
- {
- DeviceCount++;
- }
-
- return((DeviceCount > 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
+ PAGED_CODE();
+
+ /* Loop all driver device objects */
+ while (DriverObject->DeviceObject)
+ {
+ /* Delete this device */
+ IoDeleteDevice(DriverObject->DeviceObject);
+ }
+
+ /* Free the lock */
+ ExFreePool(FsRecLoadSync);
+}
+
+NTSTATUS
+STDCALL
+FsRecRegisterFs(IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT ParentObject OPTIONAL,
+ OUT PDEVICE_OBJECT *NewDeviceObject OPTIONAL,
+ IN PCWSTR FsName,
+ IN PCWSTR RecognizerName,
+ IN ULONG FsType,
+ IN DEVICE_TYPE DeviceType)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatus;
+ PDEVICE_EXTENSION DeviceExtension;
+ UNICODE_STRING DeviceName;
+ PDEVICE_OBJECT DeviceObject;
+ HANDLE FileHandle;
+ NTSTATUS Status;
+
+ /* Assume failure */
+ if (NewDeviceObject) *NewDeviceObject = NULL;
+
+ /* Setup the attributes */
+ RtlInitUnicodeString(&DeviceName, FsName);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DeviceName,
+ OBJ_CASE_INSENSITIVE,
+ 0,
+ NULL);
+
+ /* Open the device */
+ Status = ZwCreateFile(&FileHandle,
+ SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatus,
+ NULL,
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_OPEN,
+ 0,
+ NULL,
+ 0);
+ if (NT_SUCCESS(Status))
+ {
+ /* We suceeded, close the handle */
+ ZwClose(FileHandle);
+ }
+ else if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ /* We failed with anything else then what we want to fail with */
+ Status = STATUS_SUCCESS;
+ }
+
+ /* If we succeeded, there's no point in trying this again */
+ if (NT_SUCCESS(Status)) return STATUS_IMAGE_ALREADY_LOADED;
+
+ /* Create recognizer device object */
+ RtlInitUnicodeString(&DeviceName, RecognizerName);
+ Status = IoCreateDevice(DriverObject,
+ sizeof(DEVICE_EXTENSION),
+ &DeviceName,
+ DeviceType,
+ 0,
+ FALSE,
+ &DeviceObject);
+ if (NT_SUCCESS(Status))
+ {
+ /* Get the device extension and set it up */
+ DeviceExtension = DeviceObject->DeviceExtension;
+ DeviceExtension->FsType = FsType;
+ DeviceExtension->State = Pending;
+
+ /* Do we have a parent? */
+ if (ParentObject)
+ {
+ /* Link it in */
+ DeviceExtension->Alternate =
+ ((PDEVICE_EXTENSION)ParentObject->DeviceExtension)->Alternate;
+ ((PDEVICE_EXTENSION)ParentObject->DeviceExtension)->Alternate =
+ DeviceObject;
+ }
+ else
+ {
+ /* Otherwise, we're the only one */
+ DeviceExtension->Alternate = DeviceObject;
+ }
+
+ /* Return the DO if needed */
+ if (NewDeviceObject) *NewDeviceObject = DeviceObject;
+
+ /* Register the file system */
+ IoRegisterFileSystem(DeviceObject);
+ }
+
+ /* Return Status */
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+DriverEntry(IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath)
+{
+ ULONG DeviceCount = 0;
+ NTSTATUS Status;
+ PDEVICE_OBJECT UdfsObject;
+ PAGED_CODE();
+
+ /* Page the entire driver */
+ MmPageEntireDriver(DriverEntry);
+
+ /* Allocate the lock */
+ FsRecLoadSync = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(KEVENT),
+ FSREC_TAG);
+ if (!FsRecLoadSync) return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Initialize it */
+ KeInitializeEvent(FsRecLoadSync, SynchronizationEvent, TRUE);
+
+ /* Setup the major functions */
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = FsRecCreate;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsRecClose;
+ DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FsRecClose;
+ DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FsRecFsControl;
+ DriverObject->DriverUnload = FsRecUnload;
+
+ /* Register CDFS */
+ Status = FsRecRegisterFs(DriverObject,
+ NULL,
+ NULL,
+ L"\\Cdfs",
+ L"\\FileSystem\\CdfsRecognizer",
+ FS_TYPE_CDFS,
+ FILE_DEVICE_CD_ROM_FILE_SYSTEM);
+ if (NT_SUCCESS(Status)) DeviceCount++;
+
+ /* Register UDFS for CDs */
+ Status = FsRecRegisterFs(DriverObject,
+ NULL,
+ &UdfsObject,
+ L"\\UdfsCdRom",
+ L"\\FileSystem\\UdfsCdRomRecognizer",
+ FS_TYPE_UDFS,
+ FILE_DEVICE_CD_ROM_FILE_SYSTEM);
+ if (NT_SUCCESS(Status)) DeviceCount++;
+
+ /* Register UDFS for HDDs */
+ Status = FsRecRegisterFs(DriverObject,
+ UdfsObject,
+ NULL,
+ L"\\UdfsDisk",
+ L"\\FileSystem\\UdfsDiskRecognizer",
+ FS_TYPE_UDFS,
+ FILE_DEVICE_DISK_FILE_SYSTEM);
+ if (NT_SUCCESS(Status)) DeviceCount++;
+
+ /* Register FAT */
+ Status = FsRecRegisterFs(DriverObject,
+ NULL,
+ NULL,
+ L"\\Fat",
+ L"\\FileSystem\\FatRecognizer",
+ FS_TYPE_VFAT,
+ FILE_DEVICE_DISK_FILE_SYSTEM);
+ if (NT_SUCCESS(Status)) DeviceCount++;
+
+ /* Register NTFS */
+ Status = FsRecRegisterFs(DriverObject,
+ NULL,
+ NULL,
+ L"\\Ntfs",
+ L"\\FileSystem\\NtfsRecognizer",
+ FS_TYPE_NTFS,
+ FILE_DEVICE_DISK_FILE_SYSTEM);
+ if (NT_SUCCESS(Status)) DeviceCount++;
+
+ /* Return appropriate Status */
+ return (DeviceCount > 0) ? STATUS_SUCCESS : STATUS_IMAGE_ALREADY_LOADED;
}
/* EOF */
Modified: trunk/reactos/drivers/filesystems/fs_rec/fs_rec.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fs_rec…
==============================================================================
--- trunk/reactos/drivers/filesystems/fs_rec/fs_rec.h (original)
+++ trunk/reactos/drivers/filesystems/fs_rec/fs_rec.h Thu Apr 5 04:11:35 2007
@@ -1,121 +1,268 @@
-/*
- * ReactOS kernel
- * Copyright (C) 2002,2003 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: drivers/fs/fs_rec/fs_rec.h
- * PURPOSE: Filesystem recognizer driver
- * PROGRAMMER: Eric Kohl
+ * PROJECT: ReactOS File System Recognizer
+ * FILE: drivers/filesystems/fs_rec/fs_rec.h
+ * PURPOSE: Main Header File
+ * PROGRAMMER: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Eric Kohl
*/
+//
+// IFS Headers
+//
#include <ntifs.h>
#include <ntdddisk.h>
#include <ntddcdrm.h>
-
-#ifdef _MSC_VER
-#define STDCALL __stdcall
-#endif
-
-/* Filesystem types (add new filesystems here)*/
-
-#define FS_TYPE_UNUSED 0
-#define FS_TYPE_VFAT 1
-#define FS_TYPE_NTFS 2
-#define FS_TYPE_CDFS 3
-#define FS_TYPE_UDFS 4
-
-
+#include "helper.h"
+
+//
+// Tag for memory allocations
+//
+#define FSREC_TAG TAG('F', 's', 'R', 'c')
+
+//
+// UDFS Offsets
+//
+#define UDFS_VRS_START_SECTOR 16
+#define UDFS_AVDP_SECTOR 256
+
+//
+// Conversion types and macros taken from internal ntifs headers
+//
+typedef union _UCHAR1
+{
+ UCHAR Uchar[1];
+ UCHAR ForceAlignment;
+} UCHAR1, *PUCHAR1;
+
+typedef union _UCHAR2
+{
+ UCHAR Uchar[2];
+ USHORT ForceAlignment;
+} UCHAR2, *PUCHAR2;
+
+typedef union _UCHAR4
+{
+ UCHAR Uchar[4];
+ ULONG ForceAlignment;
+} UCHAR4, *PUCHAR4;
+
+#define CopyUchar1(Dst,Src) { \
+ *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \
+}
+
+#define CopyUchar2(Dst,Src) { \
+ *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \
+}
+
+#define CopyUchar4(Dst,Src) { \
+ *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \
+}
+
+#define FatUnpackBios(Bios,Pbios) { \
+ CopyUchar2(&(Bios)->BytesPerSector, &(Pbios)->BytesPerSector[0] );
\
+ CopyUchar1(&(Bios)->SectorsPerCluster, &(Pbios)->SectorsPerCluster[0]);
\
+ CopyUchar2(&(Bios)->ReservedSectors, &(Pbios)->ReservedSectors[0] );
\
+ CopyUchar1(&(Bios)->Fats, &(Pbios)->Fats[0] );
\
+ CopyUchar2(&(Bios)->RootEntries, &(Pbios)->RootEntries[0] );
\
+ CopyUchar2(&(Bios)->Sectors, &(Pbios)->Sectors[0] );
\
+ CopyUchar1(&(Bios)->Media, &(Pbios)->Media[0] );
\
+ CopyUchar2(&(Bios)->SectorsPerFat, &(Pbios)->SectorsPerFat[0] );
\
+ CopyUchar2(&(Bios)->SectorsPerTrack, &(Pbios)->SectorsPerTrack[0] );
\
+ CopyUchar2(&(Bios)->Heads, &(Pbios)->Heads[0] );
\
+ CopyUchar4(&(Bios)->HiddenSectors, &(Pbios)->HiddenSectors[0] );
\
+ CopyUchar4(&(Bios)->LargeSectors, &(Pbios)->LargeSectors[0] );
\
+}
+
+//
+// Packed versions of the BPB and Boot Sector
+//
+typedef struct _PACKED_BIOS_PARAMETER_BLOCK
+{
+ UCHAR BytesPerSector[2];
+ UCHAR SectorsPerCluster[1];
+ UCHAR ReservedSectors[2];
+ UCHAR Fats[1];
+ UCHAR RootEntries[2];
+ UCHAR Sectors[2];
+ UCHAR Media[1];
+ UCHAR SectorsPerFat[2];
+ UCHAR SectorsPerTrack[2];
+ UCHAR Heads[2];
+ UCHAR HiddenSectors[4];
+ UCHAR LargeSectors[4];
+} PACKED_BIOS_PARAMETER_BLOCK, *PPACKED_BIOS_PARAMETER_BLOCK;
+
+typedef struct _PACKED_BOOT_SECTOR
+{
+ UCHAR Jump[3];
+ UCHAR Oem[8];
+ PACKED_BIOS_PARAMETER_BLOCK PackedBpb;
+ UCHAR PhysicalDriveNumber;
+ UCHAR CurrentHead;
+ UCHAR Signature;
+ UCHAR Id[4];
+ UCHAR VolumeLabel[11];
+ UCHAR SystemId[8];
+} PACKED_BOOT_SECTOR, *PPACKED_BOOT_SECTOR;
+
+//
+// Unpacked version of the BPB
+//
+typedef struct BIOS_PARAMETER_BLOCK
+{
+ USHORT BytesPerSector;
+ UCHAR SectorsPerCluster;
+ USHORT ReservedSectors;
+ UCHAR Fats;
+ USHORT RootEntries;
+ USHORT Sectors;
+ UCHAR Media;
+ USHORT SectorsPerFat;
+ USHORT SectorsPerTrack;
+ USHORT Heads;
+ ULONG32 HiddenSectors;
+ ULONG32 LargeSectors;
+ ULONG32 LargeSectorsPerFat;
+ union
+ {
+ USHORT ExtendedFlags;
+ struct
+ {
+ ULONG ActiveFat:4;
+ ULONG Reserved0:3;
+ ULONG MirrorDisabled:1;
+ ULONG Reserved1:8;
+ };
+ };
+ USHORT FsVersion;
+ ULONG32 RootDirFirstCluster;
+ USHORT FsInfoSector;
+ USHORT BackupBootSector;
+} BIOS_PARAMETER_BLOCK, *PBIOS_PARAMETER_BLOCK;
+
+//
+// UDFS Structures
+//
+#include <pshpack1.h>
+typedef struct _TAG
+{
+ USHORT Identifier;
+ USHORT Version;
+ UCHAR Checksum;
+ UCHAR Reserved;
+ USHORT SerialNumber;
+ USHORT Crc;
+ USHORT CrcLength;
+ ULONG Location;
+} TAG, *PTAG;
+
+typedef struct _EXTENT
+{
+ ULONG Length;
+ ULONG Location;
+} EXTENT, *PEXTENT;
+
+typedef struct _AVDP
+{
+ TAG DescriptorTag;
+ EXTENT MainVolumeDescriptorExtent;
+ EXTENT ReserveVolumeDescriptorExtent;
+} AVDP, *PAVDP;
+#include <poppack.h>
+
+//
+// Filesystem Types
+//
+typedef enum _FILE_SYSTEM_TYPE
+{
+ FS_TYPE_UNUSED,
+ FS_TYPE_VFAT,
+ FS_TYPE_NTFS,
+ FS_TYPE_CDFS,
+ FS_TYPE_UDFS
+} FILE_SYSTEM_TYPE, *PFILE_SYSTEM_TYPE;
+
+//
+// FS Recognizer State
+//
+typedef enum _FS_REC_STATE
+{
+ Pending,
+ Loaded,
+ Unloading
+} FS_REC_STATE, *PFS_REC_STATE;
+
+//
+// Device extension
+//
typedef struct _DEVICE_EXTENSION
{
- ULONG FsType;
+ FS_REC_STATE State;
+ FILE_SYSTEM_TYPE FsType;
+ PDEVICE_OBJECT Alternate;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
-#include <pshpack1.h>
-struct _BootSector
-{
- unsigned char magic0, res0, magic1;
- unsigned char OEMName[8];
- unsigned short BytesPerSector;
- unsigned char SectorsPerCluster;
- unsigned short ReservedSectors;
- unsigned char FATCount;
- unsigned short RootEntries, Sectors;
- unsigned char Media;
- unsigned short FATSectors, SectorsPerTrack, Heads;
- unsigned long HiddenSectors, SectorsHuge;
- unsigned char Drive, Res1, Sig;
- unsigned long VolumeID;
- unsigned char VolumeLabel[11], SysType[8];
- unsigned char Res2[448];
- unsigned short Signatur1;
-};
-#include <poppack.h>
-
-/* blockdev.c */
-
-NTSTATUS
-FsRecReadSectors(IN PDEVICE_OBJECT DeviceObject,
- IN ULONG DiskSector,
- IN ULONG SectorCount,
- IN ULONG SectorSize,
- IN OUT PUCHAR Buffer);
-
-NTSTATUS
-FsRecDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
- IN ULONG ControlCode,
- IN PVOID InputBuffer,
- IN ULONG InputBufferSize,
- IN OUT PVOID OutputBuffer,
- IN OUT PULONG OutputBufferSize);
-
-
-/* cdfs.c */
-
-NTSTATUS
-FsRecCdfsFsControl(IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
-
-
-/* fat.c */
-
-NTSTATUS
-FsRecVfatFsControl(IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
-
-
-/* ntfs.c */
-
-NTSTATUS
-FsRecNtfsFsControl(IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
-
-
-/* udfs.c */
-
-NTSTATUS
-FsRecUdfsFsControl(IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
-
-/* fs_rec.c */
-
-NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT DriverObject,
- PUNICODE_STRING RegistryPath);
-
-/* EOF */
+//
+// Prototypes
+//
+NTSTATUS
+NTAPI
+FsRecCdfsFsControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+);
+
+NTSTATUS
+NTAPI
+FsRecVfatFsControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+);
+
+NTSTATUS
+NTAPI
+FsRecNtfsFsControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+);
+
+NTSTATUS
+NTAPI
+FsRecUdfsFsControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+);
+
+BOOLEAN
+NTAPI
+FsRecGetDeviceSectors(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SectorSize,
+ OUT PLARGE_INTEGER SectorCount
+);
+
+BOOLEAN
+NTAPI
+FsRecGetDeviceSectorSize(
+ IN PDEVICE_OBJECT DeviceObject,
+ OUT PULONG SectorSize
+);
+
+BOOLEAN
+NTAPI
+FsRecReadBlock(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PLARGE_INTEGER Offset,
+ IN ULONG Length,
+ IN ULONG SectorSize,
+ IN OUT PVOID *Buffer,
+ OUT PBOOLEAN DeviceError OPTIONAL
+);
+
+NTSTATUS
+NTAPI
+FsRecLoadFileSystem(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PWCHAR DriverServiceName
+);
Modified: trunk/reactos/drivers/filesystems/fs_rec/ntfs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fs_rec…
==============================================================================
--- trunk/reactos/drivers/filesystems/fs_rec/ntfs.c (original)
+++ trunk/reactos/drivers/filesystems/fs_rec/ntfs.c Thu Apr 5 04:11:35 2007
@@ -1,139 +1,145 @@
-/*
- * ReactOS kernel
- * Copyright (C) 2002,2003 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: drivers/fs/fs_rec/ntfs.c
- * PURPOSE: Filesystem recognizer driver
- * PROGRAMMER: Eric Kohl
+ * PROJECT: ReactOS File System Recognizer
+ * FILE: drivers/filesystems/fs_rec/ntfs.c
+ * PURPOSE: NTFS Recognizer
+ * PROGRAMMER: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Eric Kohl
*/
/* INCLUDES *****************************************************************/
+#include "fs_rec.h"
#define NDEBUG
#include <debug.h>
-#include "fs_rec.h"
-
-
/* FUNCTIONS ****************************************************************/
-static NTSTATUS
-FsRecIsNtfsVolume(IN PDEVICE_OBJECT DeviceObject)
+BOOLEAN
+NTAPI
+FsRecIsNtfsVolume(IN PPACKED_BOOT_SECTOR BootSector,
+ IN ULONG BytesPerSector,
+ IN PLARGE_INTEGER NumberOfSectors)
{
- DISK_GEOMETRY DiskGeometry;
- PUCHAR Buffer;
- ULONG Size;
- NTSTATUS Status;
+ PAGED_CODE();
+ BOOLEAN Result;
- Size = sizeof(DISK_GEOMETRY);
- Status = FsRecDeviceIoControl(DeviceObject,
- IOCTL_DISK_GET_DRIVE_GEOMETRY,
- NULL,
- 0,
- &DiskGeometry,
- &Size);
- if (!NT_SUCCESS(Status))
+ /* Assume success */
+ Result = TRUE;
+
+ if ((BootSector->Oem[0] == 'N') &&
+ (BootSector->Oem[1] == 'T') &&
+ (BootSector->Oem[2] == 'F') &&
+ (BootSector->Oem[3] == 'S') &&
+ (BootSector->Oem[4] == ' ') &&
+ (BootSector->Oem[5] == ' ') &&
+ (BootSector->Oem[6] == ' ') &&
+ (BootSector->Oem[7] == ' '))
{
- DPRINT("FsRecDeviceIoControl() failed (Status %lx)\n", Status);
- return(Status);
+ /* Fail */
+ Result = FALSE;
}
- DPRINT("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector);
- Buffer = ExAllocatePool(NonPagedPool,
- DiskGeometry.BytesPerSector);
- if (Buffer == NULL)
+ /* Return the result */
+ return Result;
+}
+
+NTSTATUS
+NTAPI
+FsRecNtfsFsControl(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION Stack;
+ NTSTATUS Status;
+ PDEVICE_OBJECT MountDevice;
+ PPACKED_BOOT_SECTOR Bpb = NULL;
+ ULONG SectorSize;
+ LARGE_INTEGER Offset = {{0}}, Offset2, Offset3, SectorCount;
+ PAGED_CODE();
+
+ /* Get the I/O Stack and check the function type */
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ switch (Stack->MinorFunction)
{
- return(STATUS_INSUFFICIENT_RESOURCES);
+ 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)) &&
+ (FsRecGetDeviceSectors(MountDevice, SectorSize, &SectorCount)))
+ {
+ /* Setup other offsets to try */
+ Offset2.QuadPart = SectorCount.QuadPart >> 1;
+ Offset2.QuadPart *= SectorSize;
+ Offset3.QuadPart = (SectorCount.QuadPart - 1) * SectorSize;
+
+ /* Try to read the BPB */
+ if (FsRecReadBlock(MountDevice,
+ &Offset,
+ 512,
+ SectorSize,
+ (PVOID)&Bpb,
+ NULL))
+ {
+ /* Check if it's an actual FAT volume */
+ if (FsRecIsNtfsVolume(Bpb, SectorSize, &SectorCount))
+ {
+ /* It is! */
+ Status = STATUS_FS_DRIVER_REQUIRED;
+ }
+ }
+ else if (FsRecReadBlock(MountDevice,
+ &Offset2,
+ 512,
+ SectorSize,
+ (PVOID)&Bpb,
+ NULL))
+ {
+ /* Check if it's an actual FAT volume */
+ if (FsRecIsNtfsVolume(Bpb, SectorSize, &SectorCount))
+ {
+ /* It is! */
+ Status = STATUS_FS_DRIVER_REQUIRED;
+ }
+ }
+ else if (FsRecReadBlock(MountDevice,
+ &Offset3,
+ 512,
+ SectorSize,
+ (PVOID)&Bpb,
+ NULL))
+ {
+ /* Check if it's an actual FAT volume */
+ if (FsRecIsNtfsVolume(Bpb, SectorSize, &SectorCount))
+ {
+ /* It is! */
+ Status = STATUS_FS_DRIVER_REQUIRED;
+ }
+ }
+
+ /* Free the boot sector if we have one */
+ ExFreePool(Bpb);
+ }
+ break;
+
+ case IRP_MN_LOAD_FILE_SYSTEM:
+
+ /* Load the file system */
+ Status = FsRecLoadFileSystem(DeviceObject,
+
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Ntfs");
+ break;
+
+ default:
+
+ /* Invalid request */
+ Status = STATUS_INVALID_DEVICE_REQUEST;
}
- Status = FsRecReadSectors(DeviceObject,
- 0, /* Partition boot sector */
- 1,
- DiskGeometry.BytesPerSector,
- Buffer);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("FsRecReadSectors() failed (Status %lx)\n", Status);
- ExFreePool(Buffer);
- return(Status);
- }
-
- DPRINT("NTFS-identifier: [%.8s]\n", &Buffer[3]);
- if (RtlCompareMemory(&Buffer[3], "NTFS ", 8) == 8)
- {
- Status = STATUS_SUCCESS;
- }
- else
- {
- Status = STATUS_UNRECOGNIZED_VOLUME;
- }
-
- ExFreePool(Buffer);
-
- return(Status);
-}
-
-
-NTSTATUS
-FsRecNtfsFsControl(IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION Stack;
- static UNICODE_STRING RegistryPath =
-
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Ntfs");
- NTSTATUS Status;
-
- Stack = IoGetCurrentIrpStackLocation(Irp);
-
- switch (Stack->MinorFunction)
- {
- case IRP_MN_MOUNT_VOLUME:
- DPRINT("NTFS: IRP_MN_MOUNT_VOLUME\n");
-
- Status = FsRecIsNtfsVolume(Stack->Parameters.MountVolume.DeviceObject);
- if (NT_SUCCESS(Status))
- {
- DPRINT("Identified NTFS volume\n");
- Status = STATUS_FS_DRIVER_REQUIRED;
- }
- break;
-
- case IRP_MN_LOAD_FILE_SYSTEM:
- DPRINT("NTFS: IRP_MN_LOAD_FILE_SYSTEM\n");
- Status = ZwLoadDriver(&RegistryPath);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwLoadDriver failed (Status %x)\n", Status);
- }
- else
- {
- IoUnregisterFileSystem(DeviceObject);
- }
- break;
-
- default:
- DPRINT("NTFS: Unknown minor function %lx\n", Stack->MinorFunction);
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
- }
- return(Status);
+ /* Return Status */
+ return Status;
}
/* EOF */
Modified: trunk/reactos/drivers/filesystems/fs_rec/udfs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fs_rec…
==============================================================================
--- trunk/reactos/drivers/filesystems/fs_rec/udfs.c (original)
+++ trunk/reactos/drivers/filesystems/fs_rec/udfs.c Thu Apr 5 04:11:35 2007
@@ -1,295 +1,149 @@
-/*
- * ReactOS kernel
- * Copyright (C) 2003 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: drivers/fs/fs_rec/udfs.c
- * PURPOSE: Filesystem recognizer driver
- * PROGRAMMER: Eric Kohl
+ * PROJECT: ReactOS File System Recognizer
+ * FILE: drivers/filesystems/fs_rec/udfs.c
+ * PURPOSE: USFS Recognizer
+ * PROGRAMMER: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Eric Kohl
*/
/* INCLUDES *****************************************************************/
+#include "fs_rec.h"
#define NDEBUG
#include <debug.h>
-#include "fs_rec.h"
-
-
-#define UDFS_VRS_START_SECTOR 16
-#define UDFS_AVDP_SECTOR 256
-
-/* TYPES ********************************************************************/
-
-#include <pshpack1.h>
-
-typedef struct _TAG
-{
- USHORT Identifier;
- USHORT Version;
- UCHAR Checksum;
- UCHAR Reserved;
- USHORT SerialNumber;
- USHORT Crc;
- USHORT CrcLength;
- ULONG Location;
-} TAG, *PTAG;
-
-typedef struct _EXTENT
-{
- ULONG Length;
- ULONG Location;
-} EXTENT, *PEXTENT;
-
-typedef struct _AVDP
-{
- TAG DescriptorTag;
- EXTENT MainVolumeDescriptorExtent;
- EXTENT ReserveVolumeDescriptorExtent;
-} AVDP, *PAVDP;
-
-#include <poppack.h>
-
-
/* FUNCTIONS ****************************************************************/
-static NTSTATUS
-FsRecCheckVolumeRecognitionSequence(IN PDEVICE_OBJECT DeviceObject,
- IN ULONG SectorSize)
+BOOLEAN
+NTAPI
+FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SectorSize)
{
- PUCHAR Buffer;
- ULONG Sector;
- NTSTATUS Status;
- ULONG State;
+ PUCHAR Buffer = NULL;
+ LARGE_INTEGER Offset;
+ ULONG State = 0;
- Buffer = ExAllocatePool(NonPagedPool,
- SectorSize);
- if (Buffer == NULL)
+ Offset.QuadPart = UDFS_VRS_START_SECTOR;
+ while (TRUE)
{
- return(STATUS_INSUFFICIENT_RESOURCES);
+ if (!FsRecReadBlock(DeviceObject,
+ &Offset,
+ 512,
+ SectorSize,
+ (PVOID)&Buffer,
+ NULL))
+ {
+ break;
+ }
+
+ switch (State)
+ {
+ case 0:
+
+ if ((Offset.QuadPart == UDFS_VRS_START_SECTOR) &&
+ (Buffer[1] == 'B') &&
+ (Buffer[2] == 'E') &&
+ (Buffer[3] == 'A') &&
+ (Buffer[4] == '0') &&
+ (Buffer[5] == '1'))
+ {
+ State = 1;
+ }
+ else
+ {
+ ExFreePool(Buffer);
+ return FALSE;
+ }
+ break;
+
+ case 1:
+
+ if ((Buffer[1] == 'N') &&
+ (Buffer[2] == 'S') &&
+ (Buffer[3] == 'R') &&
+ (Buffer[4] == '0') &&
+ ((Buffer[5] == '2') || (Buffer[5] == '3')))
+ {
+ State = 2;
+ }
+ break;
+
+ case 2:
+
+ if ((Buffer[1] == 'T') &&
+ (Buffer[2] == 'E') &&
+ (Buffer[3] == 'A') &&
+ (Buffer[4] == '0') &&
+ (Buffer[5] == '1'))
+ {
+ ExFreePool(Buffer);
+ return TRUE;
+ }
+ break;
+ }
+
+ Offset.QuadPart++;
+ if (Offset.QuadPart == UDFS_AVDP_SECTOR)
+ {
+ ExFreePool(Buffer);
+ return FALSE;
+ }
}
- State = 0;
- Sector = UDFS_VRS_START_SECTOR;
- while (TRUE)
+ ExFreePool(Buffer);
+ return TRUE;
+}
+
+NTSTATUS
+NTAPI
+FsRecUdfsFsControl(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION Stack;
+ NTSTATUS Status;
+ PDEVICE_OBJECT MountDevice;
+ ULONG SectorSize;
+ PAGED_CODE();
+
+ /* Get the I/O Stack and check the function type */
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ switch (Stack->MinorFunction)
{
- Status = FsRecReadSectors(DeviceObject,
- Sector,
- 1,
- SectorSize,
- Buffer);
- if (!NT_SUCCESS(Status))
- {
- DPRINT ("FsRecReadSectors() failed (Status %lx)\n", Status);
- break;
- }
+ case IRP_MN_MOUNT_VOLUME:
- DPRINT ("Descriptor identifier: [%.5s]\n", Buffer + 1);
+ /* Assume failure */
+ Status = STATUS_UNRECOGNIZED_VOLUME;
- switch (State)
- {
- case 0:
- if ((Sector == UDFS_VRS_START_SECTOR) &&
- (Buffer[1] == 'B') &&
- (Buffer[2] == 'E') &&
- (Buffer[3] == 'A') &&
- (Buffer[4] == '0') &&
- (Buffer[5] == '1'))
- {
- State = 1;
- }
- else
- {
- DPRINT ("VRS start sector is not 'BEA01'\n");
- ExFreePool(Buffer);
- return(STATUS_UNRECOGNIZED_VOLUME);
- }
- break;
+ /* Get the device object and request the sector size */
+ MountDevice = Stack->Parameters.MountVolume.DeviceObject;
+ if (FsRecGetDeviceSectorSize(MountDevice, &SectorSize))
+ {
+ /* Check if it's an actual FAT volume */
+ if (FsRecIsUdfsVolume(MountDevice, SectorSize))
+ {
+ /* It is! */
+ Status = STATUS_FS_DRIVER_REQUIRED;
+ }
+ }
- case 1:
- if ((Buffer[1] == 'N') &&
- (Buffer[2] == 'S') &&
- (Buffer[3] == 'R') &&
- (Buffer[4] == '0') &&
- ((Buffer[5] == '2') || (Buffer[5] == '3')))
- {
- State = 2;
- }
- break;
+ break;
- case 2:
- if ((Buffer[1] == 'T') &&
- (Buffer[2] == 'E') &&
- (Buffer[3] == 'A') &&
- (Buffer[4] == '0') &&
- (Buffer[5] == '1'))
- {
- DPRINT ("Found 'TEA01'\n");
- ExFreePool(Buffer);
- return(STATUS_SUCCESS);
- }
- break;
- }
+ case IRP_MN_LOAD_FILE_SYSTEM:
- Sector++;
- if (Sector == UDFS_AVDP_SECTOR)
- {
- DPRINT ("No 'TEA01' found\n");
- ExFreePool(Buffer);
- return(STATUS_UNRECOGNIZED_VOLUME);
- }
+ /* Load the file system */
+ Status = FsRecLoadFileSystem(DeviceObject,
+
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Udfs");
+ break;
+
+ default:
+
+ /* Invalid request */
+ Status = STATUS_INVALID_DEVICE_REQUEST;
}
- ExFreePool(Buffer);
-
- return(STATUS_UNRECOGNIZED_VOLUME);
-}
-
-
-static NTSTATUS
-FsRecCheckAnchorVolumeDescriptorPointer(IN PDEVICE_OBJECT DeviceObject,
- IN ULONG SectorSize)
-{
- PUCHAR Buffer;
- ULONG Sector;
- NTSTATUS Status;
- PAVDP Avdp;
-
- Buffer = ExAllocatePool(NonPagedPool,
- SectorSize);
- if (Buffer == NULL)
- {
- return(STATUS_INSUFFICIENT_RESOURCES);
- }
-
- Sector = UDFS_AVDP_SECTOR;
- Status = FsRecReadSectors(DeviceObject,
- Sector,
- 1,
- SectorSize,
- Buffer);
- if (!NT_SUCCESS(Status))
- {
- DPRINT ("FsRecReadSectors() failed (Status %lx)\n", Status);
- ExFreePool(Buffer);
- return(Status);
- }
-
- Avdp = (PAVDP)Buffer;
- DPRINT ("Descriptor identifier: %hu\n", Avdp->DescriptorTag.Identifier);
-
- DPRINT ("Main volume descriptor sequence location: %lu\n",
- Avdp->MainVolumeDescriptorExtent.Location);
-
- DPRINT ("Main volume descriptor sequence length: %lu\n",
- Avdp->MainVolumeDescriptorExtent.Length);
-
- DPRINT ("Reserve volume descriptor sequence location: %lu\n",
- Avdp->ReserveVolumeDescriptorExtent.Location);
-
- DPRINT ("Reserve volume descriptor sequence length: %lu\n",
- Avdp->ReserveVolumeDescriptorExtent.Length);
-
- ExFreePool(Buffer);
-
-// return(Status);
- return(STATUS_SUCCESS);
-}
-
-
-static NTSTATUS
-FsRecIsUdfsVolume(IN PDEVICE_OBJECT DeviceObject)
-{
- DISK_GEOMETRY DiskGeometry;
- ULONG Size;
- NTSTATUS Status;
-
- Size = sizeof(DISK_GEOMETRY);
- Status = FsRecDeviceIoControl(DeviceObject,
- IOCTL_CDROM_GET_DRIVE_GEOMETRY,
- NULL,
- 0,
- &DiskGeometry,
- &Size);
- if (!NT_SUCCESS(Status))
- {
- DPRINT ("FsRecDeviceIoControl() failed (Status %lx)\n", Status);
- return(Status);
- }
-
- /* Check the volume recognition sequence */
- Status = FsRecCheckVolumeRecognitionSequence(DeviceObject,
- DiskGeometry.BytesPerSector);
- if (!NT_SUCCESS(Status))
- return(Status);
-
- Status = FsRecCheckAnchorVolumeDescriptorPointer(DeviceObject,
- DiskGeometry.BytesPerSector);
- if (!NT_SUCCESS(Status))
- return(Status);
-
- return(STATUS_SUCCESS);
-}
-
-
-NTSTATUS
-FsRecUdfsFsControl(IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION Stack;
- static UNICODE_STRING RegistryPath =
-
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Udfs");
- NTSTATUS Status;
-
- Stack = IoGetCurrentIrpStackLocation(Irp);
-
- switch (Stack->MinorFunction)
- {
- case IRP_MN_MOUNT_VOLUME:
- DPRINT("Udfs: IRP_MN_MOUNT_VOLUME\n");
- Status = FsRecIsUdfsVolume(Stack->Parameters.MountVolume.DeviceObject);
- if (NT_SUCCESS(Status))
- {
- DPRINT("Identified UDFS volume\n");
- Status = STATUS_FS_DRIVER_REQUIRED;
- }
- break;
-
- case IRP_MN_LOAD_FILE_SYSTEM:
- DPRINT("Udfs: IRP_MN_LOAD_FILE_SYSTEM\n");
- Status = ZwLoadDriver(&RegistryPath);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwLoadDriver failed (Status %x)\n", Status);
- }
- else
- {
- IoUnregisterFileSystem(DeviceObject);
- }
- break;
-
- default:
- DPRINT("Udfs: Unknown minor function %lx\n", Stack->MinorFunction);
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
- }
- return(Status);
+ /* Return Status */
+ return Status;
}
/* EOF */