Added UDF filesystem recognizer (still incomplete).
authorEric Kohl <eric.kohl@reactos.org>
Thu, 16 Jan 2003 11:58:15 +0000 (11:58 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Thu, 16 Jan 2003 11:58:15 +0000 (11:58 +0000)
Fixed several memory leaks.

svn path=/trunk/; revision=4013

reactos/drivers/fs/fs_rec/cdfs.c
reactos/drivers/fs/fs_rec/fat.c
reactos/drivers/fs/fs_rec/fs_rec.c
reactos/drivers/fs/fs_rec/fs_rec.h
reactos/drivers/fs/fs_rec/makefile
reactos/drivers/fs/fs_rec/ntfs.c
reactos/drivers/fs/fs_rec/udfs.c [new file with mode: 0644]

index a98af26..e9412c6 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: cdfs.c,v 1.7 2002/09/08 10:22:09 chorns Exp $
+/* $Id: cdfs.c,v 1.8 2003/01/16 11:58:15 ekohl Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -76,6 +76,7 @@ FsRecIsCdfsVolume(IN PDEVICE_OBJECT DeviceObject)
   if (!NT_SUCCESS(Status))
     {
       DPRINT("FsRecReadSectors() failed (Status %lx)\n", Status);
+      ExFreePool(Buffer);
       return(Status);
     }
 
index 3de3344..9cafad6 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ReactOS kernel
- *  Copyright (C) 2002 ReactOS Team
+ *  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
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: fat.c,v 1.6 2002/09/08 10:22:09 chorns Exp $
+/* $Id: fat.c,v 1.7 2003/01/16 11:58:15 ekohl Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
- * FILE:             services/fs/fs_rec/vfat.c
+ * FILE:             drivers/fs/fs_rec/vfat.c
  * PURPOSE:          Filesystem recognizer driver
  * PROGRAMMER:       Eric Kohl
  */
@@ -73,6 +73,7 @@ FsRecIsFatVolume(IN PDEVICE_OBJECT DeviceObject)
                            Buffer);
   if (!NT_SUCCESS(Status))
     {
+      ExFreePool(Buffer);
       return(Status);
     }
 
index bb9474d..bc5d582 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ReactOS kernel
- *  Copyright (C) 2002 ReactOS Team
+ *  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
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: fs_rec.c,v 1.4 2002/09/08 10:22:09 chorns Exp $
+/* $Id: fs_rec.c,v 1.5 2003/01/16 11:58:15 ekohl Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
- * FILE:             services/fs/fs_rec/fs_rec.c
+ * FILE:             drivers/fs/fs_rec/fs_rec.c
  * PURPOSE:          Filesystem recognizer driver
  * PROGRAMMER:       Eric Kohl
  */
@@ -81,12 +81,16 @@ FsRecFsControl(IN PDEVICE_OBJECT DeviceObject,
        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_NTFS:
-       Status = FsRecNtfsFsControl(DeviceObject, Irp);
+      case FS_TYPE_UDFS:
+       Status = FsRecUdfsFsControl(DeviceObject, Irp);
        break;
 
       default:
@@ -192,7 +196,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   ULONG DeviceCount;
   NTSTATUS Status;
 
-  DPRINT("FileSystem recognizer 0.0.1\n");
+  DPRINT("FileSystem recognizer 0.0.2\n");
 
   DeviceCount = 0;
 
@@ -215,6 +219,16 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
        {
          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,
index 70dfc36..b4929a6 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ReactOS kernel
- *  Copyright (C) 2002 ReactOS Team
+ *  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
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: fs_rec.h,v 1.2 2002/05/15 18:02:59 ekohl Exp $
+/* $Id: fs_rec.h,v 1.3 2003/01/16 11:58:15 ekohl Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
- * FILE:             services/fs/fs_rec/fs_rec.h
+ * FILE:             drivers/fs/fs_rec/fs_rec.h
  * PURPOSE:          Filesystem recognizer driver
  * PROGRAMMER:       Eric Kohl
  */
@@ -32,6 +32,7 @@
 #define FS_TYPE_VFAT           1
 #define FS_TYPE_NTFS           2
 #define FS_TYPE_CDFS           3
+#define FS_TYPE_UDFS           4
 
 
 typedef struct _DEVICE_EXTENSION
@@ -78,4 +79,11 @@ NTSTATUS
 FsRecNtfsFsControl(IN PDEVICE_OBJECT DeviceObject,
                   IN PIRP Irp);
 
+
+/* udfs.c */
+
+NTSTATUS
+FsRecUdfsFsControl(IN PDEVICE_OBJECT DeviceObject,
+                  IN PIRP Irp);
+
 /* EOF */
index bf86328..fe341e9 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.2 2002/09/23 20:09:10 guido Exp $
+# $Id: makefile,v 1.3 2003/01/16 11:58:15 ekohl Exp $
 
 PATH_TO_TOP = ../../..
 
@@ -11,7 +11,8 @@ TARGET_OBJECTS = \
   fs_rec.o \
   cdfs.o \
   fat.o \
-  ntfs.o
+  ntfs.o \
+  udfs.o
 
 DEP_OBJECTS = $(TARGET_OBJECTS)
 
index caf9544..72821a9 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ReactOS kernel
- *  Copyright (C) 2002 ReactOS Team
+ *  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
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: ntfs.c,v 1.6 2002/09/08 10:22:09 chorns Exp $
+/* $Id: ntfs.c,v 1.7 2003/01/16 11:58:15 ekohl Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
- * FILE:             services/fs/fs_rec/ntfs.c
+ * FILE:             drivers/fs/fs_rec/ntfs.c
  * PURPOSE:          Filesystem recognizer driver
  * PROGRAMMER:       Eric Kohl
  */
@@ -74,6 +74,7 @@ FsRecIsNtfsVolume(IN PDEVICE_OBJECT DeviceObject)
   if (!NT_SUCCESS(Status))
     {
       DPRINT("FsRecReadSectors() failed (Status %lx)\n", Status);
+      ExFreePool(Buffer);
       return(Status);
     }
 
diff --git a/reactos/drivers/fs/fs_rec/udfs.c b/reactos/drivers/fs/fs_rec/udfs.c
new file mode 100644 (file)
index 0000000..9b4d8c8
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ *  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.
+ */
+/* $Id: udfs.c,v 1.1 2003/01/16 11:58:15 ekohl Exp $
+ *
+ * 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
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#include "fs_rec.h"
+
+
+#define UDFS_VRS_START_SECTOR   16
+#define UDFS_AVDP_SECTOR       256
+
+/* TYPES ********************************************************************/
+
+typedef struct _TAG
+{
+  USHORT Identifier;
+  USHORT Version;
+  UCHAR  Checksum;
+  UCHAR  Reserved;
+  USHORT SerialNumber;
+  USHORT Crc;
+  USHORT CrcLength;
+  ULONG  Location;
+} PACKED TAG, *PTAG;
+
+typedef struct _EXTENT
+{
+  ULONG Length;
+  ULONG Location;
+} PACKED EXTENT, *PEXTENT;
+
+typedef struct _AVDP
+{
+  TAG    DescriptorTag;
+  EXTENT MainVolumeDescriptorExtent;
+  EXTENT ReserveVolumeDescriptorExtent;
+} PACKED AVDP, *PAVDP;
+
+/* FUNCTIONS ****************************************************************/
+
+static NTSTATUS
+FsRecCheckVolumeRecognitionSequence(IN PDEVICE_OBJECT DeviceObject,
+                                   IN ULONG SectorSize)
+{
+  PUCHAR Buffer;
+  ULONG Sector;
+  NTSTATUS Status;
+  ULONG State;
+
+  Buffer = ExAllocatePool(NonPagedPool,
+                         SectorSize);
+  if (Buffer == NULL)
+    {
+      return(STATUS_INSUFFICIENT_RESOURCES);
+    }
+
+  State = 0;
+  Sector = UDFS_VRS_START_SECTOR;
+  while (TRUE)
+    {
+      Status = FsRecReadSectors(DeviceObject,
+                               Sector,
+                               1,
+                               SectorSize,
+                               Buffer);
+      if (!NT_SUCCESS(Status))
+       {
+         DPRINT1("FsRecReadSectors() failed (Status %lx)\n", Status);
+         break;
+       }
+
+      DPRINT1("Descriptor identifier: [%.5s]\n", Buffer + 1);
+
+      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
+             {
+               DPRINT1("VRS start sector is not 'BEA01'\n");
+               ExFreePool(Buffer);
+               return(STATUS_UNRECOGNIZED_VOLUME);
+             }
+           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'))
+             {
+               DPRINT1("Found 'TEA01'\n");
+               ExFreePool(Buffer);
+               return(STATUS_SUCCESS);
+             }
+           break;
+       }
+
+      Sector++;
+      if (Sector == UDFS_AVDP_SECTOR)
+       {
+         DPRINT1("No 'TEA01' found\n");
+         ExFreePool(Buffer);
+         return(STATUS_UNRECOGNIZED_VOLUME);
+       }
+    }
+
+  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))
+    {
+      DPRINT1("FsRecReadSectors() failed (Status %lx)\n", Status);
+      ExFreePool(Buffer);
+      return(Status);
+    }
+
+  Avdp = (PAVDP)Buffer;
+  DPRINT1("Descriptor identifier: %hu\n", Avdp->DescriptorTag.Identifier);
+
+  DPRINT1("Main volume descriptor sequence location: %lu\n",
+         Avdp->MainVolumeDescriptorExtent.Location);
+
+  DPRINT1("Main volume descriptor sequence length: %lu\n",
+         Avdp->MainVolumeDescriptorExtent.Length);
+
+  DPRINT1("Reserve volume descriptor sequence location: %lu\n",
+         Avdp->ReserveVolumeDescriptorExtent.Location);
+
+  DPRINT1("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))
+    {
+      DPRINT1("FsRecDeviceIoControl() failed (Status %lx)\n", Status);
+      return(Status);
+    }
+  DPRINT1("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector);
+
+  /* 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;
+  UNICODE_STRING RegistryPath;
+  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");
+       RtlInitUnicodeStringFromLiteral(&RegistryPath,
+                            L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Udfs");
+       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);
+}
+
+/* EOF */