diff --git a/reactos/drivers/filesystems/fs_rec/cdfs.c b/reactos/drivers/filesystems/fs_rec/cdfs.c index 2f097d923e6..79fcca60ec6 100644 --- a/reactos/drivers/filesystems/fs_rec/cdfs.c +++ b/reactos/drivers/filesystems/fs_rec/cdfs.c @@ -1,10 +1,10 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS File System Recognizer - * FILE: drivers/filesystems/fs_rec/cdfs.c - * PURPOSE: CDFS Recognizer - * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org) - * Eric Kohl + * PROJECT: ReactOS File System Recognizer + * LICENSE: GPL-2.0 (https://spdx.org/licenses/GPL-2.0) + * PURPOSE: CDFS Recognizer + * COPYRIGHT: Copyright 2002 Eric Kohl + * Copyright 2007 Alex Ionescu + * Copyright 2017 Colin Finck */ /* INCLUDES *****************************************************************/ @@ -14,13 +14,60 @@ #define NDEBUG #include +#include "cdfs.h" + /* FUNCTIONS ****************************************************************/ +BOOLEAN +NTAPI +FsRecIsCdfsVolume(IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize) +{ + BOOLEAN bReturnValue = FALSE; + LARGE_INTEGER Offset; + PVD_HEADER pVdHeader = NULL; + PAGED_CODE(); + + // Read the Primary Volume Descriptor. + Offset.QuadPart = VD_HEADER_OFFSET; + if (!FsRecReadBlock(DeviceObject, &Offset, sizeof(VD_HEADER), SectorSize, (PVOID*)&pVdHeader, NULL)) + { + // We cannot read this block, so no reason to let the CDFS driver try it. + goto Cleanup; + } + + // Verify the fields. + if (pVdHeader->Type != VD_TYPE_PRIMARY) + goto Cleanup; + + DPRINT("pVdHeader->Type verified!\n"); + + if (RtlCompareMemory(pVdHeader->Identifier, VD_IDENTIFIER, VD_IDENTIFIER_LENGTH) != VD_IDENTIFIER_LENGTH) + goto Cleanup; + + DPRINT("pVdHeader->Identifier verified!\n"); + + if (pVdHeader->Version != VD_VERSION) + goto Cleanup; + + DPRINT("pVdHeader->Version verified! This is a CDFS volume!\n"); + + bReturnValue = TRUE; + +Cleanup: + if (pVdHeader) + ExFreePool(pVdHeader); + + return bReturnValue; +} + NTSTATUS NTAPI FsRecCdfsFsControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { + PDEVICE_OBJECT MountDevice; + ULONG SectorSize; PIO_STACK_LOCATION Stack; NTSTATUS Status; PAGED_CODE(); @@ -31,8 +78,21 @@ FsRecCdfsFsControl(IN PDEVICE_OBJECT DeviceObject, { case IRP_MN_MOUNT_VOLUME: - /* We don't validate */ - Status = STATUS_FS_DRIVER_REQUIRED; + /* Assume failure */ + Status = STATUS_UNRECOGNIZED_VOLUME; + + /* Get the device object and request the sector size */ + MountDevice = Stack->Parameters.MountVolume.DeviceObject; + if (FsRecGetDeviceSectorSize(MountDevice, &SectorSize)) + { + /* Check if it's an actual CDFS (ISO-9660) volume */ + if (FsRecIsCdfsVolume(MountDevice, SectorSize)) + { + /* It is! */ + Status = STATUS_FS_DRIVER_REQUIRED; + } + } + break; case IRP_MN_LOAD_FILE_SYSTEM: diff --git a/reactos/drivers/filesystems/fs_rec/cdfs.h b/reactos/drivers/filesystems/fs_rec/cdfs.h new file mode 100644 index 00000000000..521185aff94 --- /dev/null +++ b/reactos/drivers/filesystems/fs_rec/cdfs.h @@ -0,0 +1,24 @@ +/* + * PROJECT: ReactOS File System Recognizer + * LICENSE: GPL-2.0 (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: CDFS Recognizer + * COPYRIGHT: Copyright 2017 Colin Finck + */ + +// Information from http://wiki.osdev.org/ISO_9660#Volume_Descriptors + +// Structures +typedef struct _VD_HEADER +{ + char Type; + char Identifier[5]; + char Version; +} +VD_HEADER, *PVD_HEADER; + +// Constants +#define VD_HEADER_OFFSET 32768 // Offset of the VD Header +#define VD_IDENTIFIER "CD001" // Identifier that must be in the Volume Descriptor +#define VD_IDENTIFIER_LENGTH 5 // Character count of VD_IDENTIFIER +#define VD_TYPE_PRIMARY 1 // Type code for Primary Volume Descriptor +#define VD_VERSION 1 // Volume Descriptor Version diff --git a/reactos/drivers/filesystems/fs_rec/fs_rec.c b/reactos/drivers/filesystems/fs_rec/fs_rec.c index 3c01eda34f4..f279adff3f2 100644 --- a/reactos/drivers/filesystems/fs_rec/fs_rec.c +++ b/reactos/drivers/filesystems/fs_rec/fs_rec.c @@ -316,6 +316,7 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, { ULONG DeviceCount = 0; NTSTATUS Status; + PDEVICE_OBJECT CdfsObject; PDEVICE_OBJECT UdfsObject; PAGED_CODE(); @@ -340,16 +341,26 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FsRecFsControl; DriverObject->DriverUnload = FsRecUnload; - /* Register CDFS */ + /* Register CDFS for CDs */ Status = FsRecRegisterFs(DriverObject, NULL, - NULL, + &CdfsObject, L"\\Cdfs", L"\\FileSystem\\CdfsRecognizer", FS_TYPE_CDFS, FILE_DEVICE_CD_ROM_FILE_SYSTEM); if (NT_SUCCESS(Status)) DeviceCount++; + /* Register CDFS for HDDs */ + Status = FsRecRegisterFs(DriverObject, + CdfsObject, + NULL, + L"\\CdfsHdd", + L"\\FileSystem\\CdfsHddRecognizer", + FS_TYPE_CDFS, + FILE_DEVICE_DISK_FILE_SYSTEM); + if (NT_SUCCESS(Status)) DeviceCount++; + /* Register UDFS for CDs */ Status = FsRecRegisterFs(DriverObject, NULL, diff --git a/reactos/drivers/filesystems/fs_rec/udfs.c b/reactos/drivers/filesystems/fs_rec/udfs.c index b277324856a..655b6ea28c6 100644 --- a/reactos/drivers/filesystems/fs_rec/udfs.c +++ b/reactos/drivers/filesystems/fs_rec/udfs.c @@ -125,7 +125,7 @@ FsRecUdfsFsControl(IN PDEVICE_OBJECT DeviceObject, MountDevice = Stack->Parameters.MountVolume.DeviceObject; if (FsRecGetDeviceSectorSize(MountDevice, &SectorSize)) { - /* Check if it's an actual FAT volume */ + /* Check if it's an actual UDF volume */ if (FsRecIsUdfsVolume(MountDevice, SectorSize)) { /* It is! */