Sync with trunk (r48545)
[reactos.git] / drivers / filesystems / cdfs / fsctl.c
index 0f1950c..dd0e065 100644 (file)
@@ -1,29 +1,29 @@
 /*
- *  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.
- */
+*  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.,
+*  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
 /*
- * COPYRIGHT:        See COPYING in the top level directory
- * PROJECT:          ReactOS kernel
- * FILE:             drivers/fs/cdfs/fsctl.c
- * PURPOSE:          CDROM (ISO 9660) filesystem driver
- * PROGRAMMER:       Art Yerkes
- *                   Eric Kohl
- */
+* COPYRIGHT:        See COPYING in the top level directory
+* PROJECT:          ReactOS kernel
+* FILE:             drivers/fs/cdfs/fsctl.c
+* PURPOSE:          CDROM (ISO 9660) filesystem driver
+* PROGRAMMER:       Art Yerkes
+*                   Eric Kohl
+*/
 
 /* INCLUDES *****************************************************************/
 
 static __inline
 int msf_to_lba (UCHAR m, UCHAR s, UCHAR f)
 {
-   return (((m * 60) + s) * 75 + f) - 150;
+    return (((m * 60) + s) * 75 + f) - 150;
 }
 
 
 static VOID
 CdfsGetPVDData(PUCHAR Buffer,
-              PCDINFO CdInfo)
+               PCDINFO CdInfo)
 {
-  PPVD Pvd;
-  ULONG i;
-  PUCHAR pc;
-  PWCHAR pw;
+    PPVD Pvd;
+    ULONG i;
+    PUCHAR pc;
+    PWCHAR pw;
 
-  union
+    union
     {
-      ULONG Value;
-      UCHAR Part[4];
+        ULONG Value;
+        UCHAR Part[4];
     } Serial;
 
-  Pvd = (PPVD)Buffer;
+    Pvd = (PPVD)Buffer;
 
-  /* Calculate the volume serial number */
-  Serial.Value = 0;
-  for (i = 0; i < 2048; i += 4)
+    /* Calculate the volume serial number */
+    Serial.Value = 0;
+    for (i = 0; i < 2048; i += 4)
     {
-      /* DON'T optimize this to ULONG!!! (breaks overflow) */
-      Serial.Part[0] += Buffer[i+3];
-      Serial.Part[1] += Buffer[i+2];
-      Serial.Part[2] += Buffer[i+1];
-      Serial.Part[3] += Buffer[i+0];
+        /* DON'T optimize this to ULONG!!! (breaks overflow) */
+        Serial.Part[0] += Buffer[i+3];
+        Serial.Part[1] += Buffer[i+2];
+        Serial.Part[2] += Buffer[i+1];
+        Serial.Part[3] += Buffer[i+0];
     }
-  CdInfo->SerialNumber = Serial.Value;
+    CdInfo->SerialNumber = Serial.Value;
 
-  /* Extract the volume label */
-  pc = Pvd->VolumeId;
-  pw = CdInfo->VolumeLabel;
-  for (i = 0; i < MAXIMUM_VOLUME_LABEL_LENGTH && *pc != ' '; i++)
+    /* Extract the volume label */
+    pc = Pvd->VolumeId;
+    pw = CdInfo->VolumeLabel;
+    for (i = 0; i < (MAXIMUM_VOLUME_LABEL_LENGTH / sizeof(WCHAR)) - 1; i++)
     {
-      *pw++ = (WCHAR)*pc++;
+        *pw++ = (WCHAR)*pc++;
     }
-  *pw = 0;
-  CdInfo->VolumeLabelLength = i * sizeof(WCHAR);
-
-  CdInfo->VolumeSpaceSize = Pvd->VolumeSpaceSizeL;
-  CdInfo->RootStart = Pvd->RootDirRecord.ExtentLocationL;
-  CdInfo->RootSize = Pvd->RootDirRecord.DataLengthL;
-
-  DPRINT("VolumeSerial: %08lx\n", CdInfo->SerialNumber);
-  DPRINT("VolumeLabel: '%S'\n", CdInfo->VolumeLabel);
-  DPRINT("VolumeLabelLength: %lu\n", CdInfo->VolumeLabelLength);
-  DPRINT("VolumeSize: %lu\n", Pvd->VolumeSpaceSizeL);
-  DPRINT("RootStart: %lu\n", Pvd->RootDirRecord.ExtentLocationL);
-  DPRINT("RootSize: %lu\n", Pvd->RootDirRecord.DataLengthL);
-  DPRINT("PathTableSize: %lu\n", Pvd->PathTableSizeL);
-  DPRINT("PathTablePos: %lu\n", Pvd->LPathTablePos);
-  DPRINT("OptPathTablePos: %lu\n", Pvd->LOptPathTablePos);
+    *pw = 0;
+
+    /* Trim trailing spaces */
+    while (pw > CdInfo->VolumeLabel)
+    {
+        if (*--pw != ' ') break;
+
+        /* Remove the space */
+        *pw = '\0';
+
+        /* Decrease size */
+        i--;
+    }
+
+    CdInfo->VolumeLabelLength = i * sizeof(WCHAR);
+
+    CdInfo->VolumeSpaceSize = Pvd->VolumeSpaceSizeL;
+    CdInfo->RootStart = Pvd->RootDirRecord.ExtentLocationL;
+    CdInfo->RootSize = Pvd->RootDirRecord.DataLengthL;
+
+    DPRINT("VolumeSerial: %08lx\n", CdInfo->SerialNumber);
+    DPRINT("VolumeLabel: '%S'\n", CdInfo->VolumeLabel);
+    DPRINT("VolumeLabelLength: %lu\n", CdInfo->VolumeLabelLength);
+    DPRINT("VolumeSize: %lu\n", Pvd->VolumeSpaceSizeL);
+    DPRINT("RootStart: %lu\n", Pvd->RootDirRecord.ExtentLocationL);
+    DPRINT("RootSize: %lu\n", Pvd->RootDirRecord.DataLengthL);
+    DPRINT("PathTableSize: %lu\n", Pvd->PathTableSizeL);
+    DPRINT("PathTablePos: %lu\n", Pvd->LPathTablePos);
+    DPRINT("OptPathTablePos: %lu\n", Pvd->LOptPathTablePos);
 
 #if 0
-  DbgPrint("******** PVD **********\n");
-  DbgPrint("VdType:               %d\n", Pvd->VdType);
-  DbgPrint("StandardId:           '%.*s'\n", 5, Pvd->StandardId);
-  DbgPrint("VdVersion:            %d\n", Pvd->VdVersion);
-  DbgPrint("SystemId:             '%.*s'\n", 32, Pvd->SystemId);
-  DbgPrint("VolumeId:             '%.*s'\n", 32, Pvd->VolumeId);
-  DbgPrint("VolumeSpaceSizeL:     %d (%x)\n", Pvd->VolumeSpaceSizeL, Pvd->VolumeSpaceSizeL);
-  DbgPrint("VolumeSpaceSizeM:     %d (%x)\n", Pvd->VolumeSpaceSizeM, Pvd->VolumeSpaceSizeM);
-  DbgPrint("VolumeSetSize:        %d (%x)\n", Pvd->VolumeSequenceNumber, Pvd->VolumeSequenceNumber);
-  DbgPrint("VolumeSequenceNumber: %d (%x)\n", Pvd->VolumeSequenceNumber, Pvd->VolumeSequenceNumber);
-  DbgPrint("LogicalBlockSize:     %d (%x)\n", Pvd->LogicalBlockSize, Pvd->LogicalBlockSize);
-  DbgPrint("PathTableSizeL:       %d (%x)\n", Pvd->PathTableSizeL, Pvd->PathTableSizeL);
-  DbgPrint("PathTableSizeM:       %d (%x)\n", Pvd->PathTableSizeM, Pvd->PathTableSizeM);
-  DbgPrint("LPathTablePos:        %d (%x)\n", Pvd->LPathTablePos, Pvd->LPathTablePos);
-  DbgPrint("LOptPathTablePos:     %d (%x)\n", Pvd->LOptPathTablePos, Pvd->LOptPathTablePos);
-  DbgPrint("MPathTablePos:        %d (%x)\n", Pvd->MPathTablePos, Pvd->MPathTablePos);
-  DbgPrint("MOptPathTablePos:     %d (%x)\n", Pvd->MOptPathTablePos, Pvd->MOptPathTablePos);
-  DbgPrint("VolumeSetIdentifier:  '%.*s'\n", 128, Pvd->VolumeSetIdentifier);
-  DbgPrint("PublisherIdentifier:  '%.*s'\n", 128, Pvd->PublisherIdentifier);
-  DbgPrint("******** Root *********\n");
-  DbgPrint("RecordLength:         %d\n", Pvd->RootDirRecord.RecordLength);
-  DbgPrint("ExtAttrRecordLength:  %d\n", Pvd->RootDirRecord.ExtAttrRecordLength);
-  DbgPrint("ExtentLocationL:      %d\n", Pvd->RootDirRecord.ExtentLocationL);
-  DbgPrint("DataLengthL:          %d\n", Pvd->RootDirRecord.DataLengthL);
-  DbgPrint("Year:                 %d\n", Pvd->RootDirRecord.Year);
-  DbgPrint("Month:                %d\n", Pvd->RootDirRecord.Month);
-  DbgPrint("Day:                  %d\n", Pvd->RootDirRecord.Day);
-  DbgPrint("Hour:                 %d\n", Pvd->RootDirRecord.Hour);
-  DbgPrint("Minute:               %d\n", Pvd->RootDirRecord.Minute);
-  DbgPrint("Second:               %d\n", Pvd->RootDirRecord.Second);
-  DbgPrint("TimeZone:             %d\n", Pvd->RootDirRecord.TimeZone);
-  DbgPrint("FileFlags:            %d\n", Pvd->RootDirRecord.FileFlags);
-  DbgPrint("FileUnitSize:         %d\n", Pvd->RootDirRecord.FileUnitSize);
-  DbgPrint("InterleaveGapSize:    %d\n", Pvd->RootDirRecord.InterleaveGapSize);
-  DbgPrint("VolumeSequenceNumber: %d\n", Pvd->RootDirRecord.VolumeSequenceNumber);
-  DbgPrint("FileIdLength:         %d\n", Pvd->RootDirRecord.FileIdLength);
-  DbgPrint("FileId:               '%.*s'\n", Pvd->RootDirRecord.FileId);
-  DbgPrint("***********************\n");
+    DbgPrint("******** PVD **********\n");
+    DbgPrint("VdType:               %d\n", Pvd->VdType);
+    DbgPrint("StandardId:           '%.*s'\n", 5, Pvd->StandardId);
+    DbgPrint("VdVersion:            %d\n", Pvd->VdVersion);
+    DbgPrint("SystemId:             '%.*s'\n", 32, Pvd->SystemId);
+    DbgPrint("VolumeId:             '%.*s'\n", 32, Pvd->VolumeId);
+    DbgPrint("VolumeSpaceSizeL:     %d (%x)\n", Pvd->VolumeSpaceSizeL, Pvd->VolumeSpaceSizeL);
+    DbgPrint("VolumeSpaceSizeM:     %d (%x)\n", Pvd->VolumeSpaceSizeM, Pvd->VolumeSpaceSizeM);
+    DbgPrint("VolumeSetSize:        %d (%x)\n", Pvd->VolumeSequenceNumber, Pvd->VolumeSequenceNumber);
+    DbgPrint("VolumeSequenceNumber: %d (%x)\n", Pvd->VolumeSequenceNumber, Pvd->VolumeSequenceNumber);
+    DbgPrint("LogicalBlockSize:     %d (%x)\n", Pvd->LogicalBlockSize, Pvd->LogicalBlockSize);
+    DbgPrint("PathTableSizeL:       %d (%x)\n", Pvd->PathTableSizeL, Pvd->PathTableSizeL);
+    DbgPrint("PathTableSizeM:       %d (%x)\n", Pvd->PathTableSizeM, Pvd->PathTableSizeM);
+    DbgPrint("LPathTablePos:        %d (%x)\n", Pvd->LPathTablePos, Pvd->LPathTablePos);
+    DbgPrint("LOptPathTablePos:     %d (%x)\n", Pvd->LOptPathTablePos, Pvd->LOptPathTablePos);
+    DbgPrint("MPathTablePos:        %d (%x)\n", Pvd->MPathTablePos, Pvd->MPathTablePos);
+    DbgPrint("MOptPathTablePos:     %d (%x)\n", Pvd->MOptPathTablePos, Pvd->MOptPathTablePos);
+    DbgPrint("VolumeSetIdentifier:  '%.*s'\n", 128, Pvd->VolumeSetIdentifier);
+    DbgPrint("PublisherIdentifier:  '%.*s'\n", 128, Pvd->PublisherIdentifier);
+    DbgPrint("******** Root *********\n");
+    DbgPrint("RecordLength:         %d\n", Pvd->RootDirRecord.RecordLength);
+    DbgPrint("ExtAttrRecordLength:  %d\n", Pvd->RootDirRecord.ExtAttrRecordLength);
+    DbgPrint("ExtentLocationL:      %d\n", Pvd->RootDirRecord.ExtentLocationL);
+    DbgPrint("DataLengthL:          %d\n", Pvd->RootDirRecord.DataLengthL);
+    DbgPrint("Year:                 %d\n", Pvd->RootDirRecord.Year);
+    DbgPrint("Month:                %d\n", Pvd->RootDirRecord.Month);
+    DbgPrint("Day:                  %d\n", Pvd->RootDirRecord.Day);
+    DbgPrint("Hour:                 %d\n", Pvd->RootDirRecord.Hour);
+    DbgPrint("Minute:               %d\n", Pvd->RootDirRecord.Minute);
+    DbgPrint("Second:               %d\n", Pvd->RootDirRecord.Second);
+    DbgPrint("TimeZone:             %d\n", Pvd->RootDirRecord.TimeZone);
+    DbgPrint("FileFlags:            %d\n", Pvd->RootDirRecord.FileFlags);
+    DbgPrint("FileUnitSize:         %d\n", Pvd->RootDirRecord.FileUnitSize);
+    DbgPrint("InterleaveGapSize:    %d\n", Pvd->RootDirRecord.InterleaveGapSize);
+    DbgPrint("VolumeSequenceNumber: %d\n", Pvd->RootDirRecord.VolumeSequenceNumber);
+    DbgPrint("FileIdLength:         %d\n", Pvd->RootDirRecord.FileIdLength);
+    DbgPrint("FileId:               '%.*s'\n", Pvd->RootDirRecord.FileId);
+    DbgPrint("***********************\n");
 #endif
 }
 
 
 static VOID
 CdfsGetSVDData(PUCHAR Buffer,
-              PCDINFO CdInfo)
+               PCDINFO CdInfo)
 {
-  PSVD Svd;
-  ULONG JolietLevel = 0;
+    PSVD Svd;
+    ULONG JolietLevel = 0;
 
-  Svd = (PSVD)Buffer;
+    Svd = (PSVD)Buffer;
 
-  DPRINT("EscapeSequences: '%.32s'\n", Svd->EscapeSequences);
+    DPRINT("EscapeSequences: '%.32s'\n", Svd->EscapeSequences);
 
-  if (strncmp((PCHAR)Svd->EscapeSequences, "%/@", 3) == 0)
+    if (strncmp((PCHAR)Svd->EscapeSequences, "%/@", 3) == 0)
     {
-      DPRINT("Joliet extension found (UCS-2 Level 1)\n");
-      JolietLevel = 1;
+        DPRINT("Joliet extension found (UCS-2 Level 1)\n");
+        JolietLevel = 1;
     }
-  else if (strncmp((PCHAR)Svd->EscapeSequences, "%/C", 3) == 0)
+    else if (strncmp((PCHAR)Svd->EscapeSequences, "%/C", 3) == 0)
     {
-      DPRINT("Joliet extension found (UCS-2 Level 2)\n");
-      JolietLevel = 2;
+        DPRINT("Joliet extension found (UCS-2 Level 2)\n");
+        JolietLevel = 2;
     }
-  else if (strncmp((PCHAR)Svd->EscapeSequences, "%/E", 3) == 0)
+    else if (strncmp((PCHAR)Svd->EscapeSequences, "%/E", 3) == 0)
     {
-      DPRINT("Joliet extension found (UCS-2 Level 3)\n");
-      JolietLevel = 3;
+        DPRINT("Joliet extension found (UCS-2 Level 3)\n");
+        JolietLevel = 3;
     }
 
-  CdInfo->JolietLevel = JolietLevel;
+    CdInfo->JolietLevel = JolietLevel;
 
-  if (JolietLevel != 0)
+    if (JolietLevel != 0)
     {
-      CdInfo->RootStart = Svd->RootDirRecord.ExtentLocationL;
-      CdInfo->RootSize = Svd->RootDirRecord.DataLengthL;
+        CdInfo->RootStart = Svd->RootDirRecord.ExtentLocationL;
+        CdInfo->RootSize = Svd->RootDirRecord.DataLengthL;
 
-      DPRINT("RootStart: %lu\n", Svd->RootDirRecord.ExtentLocationL);
-      DPRINT("RootSize: %lu\n", Svd->RootDirRecord.DataLengthL);
+        DPRINT("RootStart: %lu\n", Svd->RootDirRecord.ExtentLocationL);
+        DPRINT("RootSize: %lu\n", Svd->RootDirRecord.DataLengthL);
     }
 }
 
 
 static NTSTATUS
 CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
-                 PCDINFO CdInfo)
+                  PCDINFO CdInfo)
 {
-  PUCHAR Buffer;
-  NTSTATUS Status;
-  ULONG Sector;
-  PVD_HEADER VdHeader;
-  ULONG Size;
-  ULONG Offset;
-  ULONG i;
-  struct
-  {
-    UCHAR  Length[2];
-    UCHAR  FirstSession;
-    UCHAR  LastSession;
-    TRACK_DATA  TrackData;
-  }
-  Toc;
-
-  DPRINT("CdfsGetVolumeData\n");
-
-  Buffer = ExAllocatePool(NonPagedPool,
-                         CDFS_BASIC_SECTOR);
-  if (Buffer == NULL)
-    return STATUS_INSUFFICIENT_RESOURCES;
-
-  Size = sizeof(Toc);
-  Status = CdfsDeviceIoControl(DeviceObject,
-                              IOCTL_CDROM_GET_LAST_SESSION,
-                              NULL,
-                              0,
-                              &Toc,
-                              &Size,
-                              TRUE);
-  if (!NT_SUCCESS(Status))
+    PUCHAR Buffer;
+    NTSTATUS Status;
+    ULONG Sector;
+    PVD_HEADER VdHeader;
+    ULONG Size;
+    ULONG Offset;
+    ULONG i;
+    struct
+    {
+        UCHAR  Length[2];
+        UCHAR  FirstSession;
+        UCHAR  LastSession;
+        TRACK_DATA  TrackData;
+    }
+    Toc;
+
+    DPRINT("CdfsGetVolumeData\n");
+
+    Buffer = ExAllocatePool(NonPagedPool,
+        CDFS_BASIC_SECTOR);
+    if (Buffer == NULL)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    Size = sizeof(Toc);
+    Status = CdfsDeviceIoControl(DeviceObject,
+        IOCTL_CDROM_GET_LAST_SESSION,
+        NULL,
+        0,
+        &Toc,
+        &Size,
+        TRUE);
+    if (!NT_SUCCESS(Status))
     {
-      ExFreePool(Buffer);
-      return Status;
+        ExFreePool(Buffer);
+        return Status;
     }
 
-  DPRINT("FirstSession %d, LastSession %d, FirstTrack %d\n",
-         Toc.FirstSession, Toc.LastSession, Toc.TrackData.TrackNumber);
+    DPRINT("FirstSession %d, LastSession %d, FirstTrack %d\n",
+        Toc.FirstSession, Toc.LastSession, Toc.TrackData.TrackNumber);
 
-  Offset = 0;
-  for (i = 0; i < 4; i++)
+    Offset = 0;
+    for (i = 0; i < 4; i++)
     {
-      Offset = (Offset << 8) + Toc.TrackData.Address[i];
+        Offset = (Offset << 8) + Toc.TrackData.Address[i];
     }
-  CdInfo->VolumeOffset = Offset;
+    CdInfo->VolumeOffset = Offset;
 
-  DPRINT("Offset of first track in last session %d\n", Offset);
+    DPRINT("Offset of first track in last session %d\n", Offset);
 
-  CdInfo->JolietLevel = 0;
-  VdHeader = (PVD_HEADER)Buffer;
-  Buffer[0] = 0;
+    CdInfo->JolietLevel = 0;
+    VdHeader = (PVD_HEADER)Buffer;
+    Buffer[0] = 0;
 
-  for (Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION; Sector < 100 && Buffer[0] != 255; Sector++)
+    for (Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION; Sector < 100 && Buffer[0] != 255; Sector++)
     {
-      /* Read the Primary Volume Descriptor (PVD) */
-      Status = CdfsReadSectors (DeviceObject,
-                               Sector + Offset,
-                               1,
-                               Buffer,
-                               TRUE);
-      if (!NT_SUCCESS(Status))
-       {
-           ExFreePool(Buffer);
-           return Status;
-       }
-
-      if (Sector == CDFS_PRIMARY_DESCRIPTOR_LOCATION)
-       {
-         DPRINT("CD-identifier: [%.5s]\n", Buffer + 1);
-
-         if (Buffer[0] != 1 || Buffer[1] != 'C' || Buffer[2] != 'D' ||
-             Buffer[3] != '0' || Buffer[4] != '0' || Buffer[5] != '1')
-           {
-             ExFreePool(Buffer);
-             return STATUS_UNRECOGNIZED_VOLUME;
-           }
-       }
-
-      switch (VdHeader->VdType)
-       {
-         case 0:
-           DPRINT("BootVolumeDescriptor found!\n");
-           break;
-
-         case 1:
-           DPRINT("PrimaryVolumeDescriptor found!\n");
-           CdfsGetPVDData(Buffer, CdInfo);
-           break;
-
-         case 2:
-           DPRINT("SupplementaryVolumeDescriptor found!\n");
-           CdfsGetSVDData(Buffer, CdInfo);
-           break;
-
-         case 3:
-           DPRINT("VolumePartitionDescriptor found!\n");
-           break;
-
-         case 255:
-           DPRINT("VolumeDescriptorSetTerminator found!\n");
-           break;
-
-         default:
-           DPRINT1("Unknown volume descriptor type %u found!\n", VdHeader->VdType);
-           break;
-       }
+        /* Read the Primary Volume Descriptor (PVD) */
+        Status = CdfsReadSectors (DeviceObject,
+            Sector + Offset,
+            1,
+            Buffer,
+            TRUE);
+        if (!NT_SUCCESS(Status))
+        {
+            ExFreePool(Buffer);
+            return Status;
+        }
+
+        if (Sector == CDFS_PRIMARY_DESCRIPTOR_LOCATION)
+        {
+            DPRINT("CD-identifier: [%.5s]\n", Buffer + 1);
+
+            if (Buffer[0] != 1 || Buffer[1] != 'C' || Buffer[2] != 'D' ||
+                Buffer[3] != '0' || Buffer[4] != '0' || Buffer[5] != '1')
+            {
+                ExFreePool(Buffer);
+                return STATUS_UNRECOGNIZED_VOLUME;
+            }
+        }
+
+        switch (VdHeader->VdType)
+        {
+        case 0:
+            DPRINT("BootVolumeDescriptor found!\n");
+            break;
+
+        case 1:
+            DPRINT("PrimaryVolumeDescriptor found!\n");
+            CdfsGetPVDData(Buffer, CdInfo);
+            break;
+
+        case 2:
+            DPRINT("SupplementaryVolumeDescriptor found!\n");
+            CdfsGetSVDData(Buffer, CdInfo);
+            break;
+
+        case 3:
+            DPRINT("VolumePartitionDescriptor found!\n");
+            break;
+
+        case 255:
+            DPRINT("VolumeDescriptorSetTerminator found!\n");
+            break;
+
+        default:
+            DPRINT1("Unknown volume descriptor type %u found!\n", VdHeader->VdType);
+            break;
+        }
     }
 
-  ExFreePool(Buffer);
+    ExFreePool(Buffer);
 
-  return(STATUS_SUCCESS);
+    return(STATUS_SUCCESS);
 }
 
 
 static NTSTATUS
 CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
-               PIRP Irp)
+                PIRP Irp)
 {
-  PDEVICE_EXTENSION DeviceExt = NULL;
-  PDEVICE_OBJECT NewDeviceObject = NULL;
-  PDEVICE_OBJECT DeviceToMount;
-  PIO_STACK_LOCATION Stack;
-  PFCB Fcb = NULL;
-  PCCB Ccb = NULL;
-  PVPB Vpb;
-  NTSTATUS Status;
-  CDINFO CdInfo;
-
-  DPRINT("CdfsMountVolume() called\n");
-
-  if (DeviceObject != CdfsGlobalData->DeviceObject)
+    PDEVICE_EXTENSION DeviceExt = NULL;
+    PDEVICE_OBJECT NewDeviceObject = NULL;
+    PDEVICE_OBJECT DeviceToMount;
+    PIO_STACK_LOCATION Stack;
+    PFCB Fcb = NULL;
+    PCCB Ccb = NULL;
+    PVPB Vpb;
+    NTSTATUS Status;
+    CDINFO CdInfo;
+
+    DPRINT("CdfsMountVolume() called\n");
+
+    if (DeviceObject != CdfsGlobalData->DeviceObject)
     {
-      Status = STATUS_INVALID_DEVICE_REQUEST;
-      goto ByeBye;
+        Status = STATUS_INVALID_DEVICE_REQUEST;
+        goto ByeBye;
     }
 
-  Stack = IoGetCurrentIrpStackLocation(Irp);
-  DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
-  Vpb = Stack->Parameters.MountVolume.Vpb;
+    Stack = IoGetCurrentIrpStackLocation(Irp);
+    DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
+    Vpb = Stack->Parameters.MountVolume.Vpb;
 
-  Status = CdfsGetVolumeData(DeviceToMount, &CdInfo);
-  if (!NT_SUCCESS(Status))
+    Status = CdfsGetVolumeData(DeviceToMount, &CdInfo);
+    if (!NT_SUCCESS(Status))
     {
-      goto ByeBye;
+        goto ByeBye;
     }
 
-  Status = IoCreateDevice(CdfsGlobalData->DriverObject,
-                         sizeof(DEVICE_EXTENSION),
-                         NULL,
-                         FILE_DEVICE_FILE_SYSTEM,
-//                       FILE_DEVICE_DISK_FILE_SYSTEM,
-                         0,
-                         FALSE,
-                         &NewDeviceObject);
-  if (!NT_SUCCESS(Status))
-    goto ByeBye;
-
-  NewDeviceObject->Flags = NewDeviceObject->Flags | DO_DIRECT_IO;
-  NewDeviceObject->Flags &= ~DO_VERIFY_VOLUME;
-  DeviceExt = (PVOID)NewDeviceObject->DeviceExtension;
-  RtlZeroMemory(DeviceExt,
-               sizeof(DEVICE_EXTENSION));
-
-  Vpb->SerialNumber = CdInfo.SerialNumber;
-  Vpb->VolumeLabelLength = CdInfo.VolumeLabelLength;
-  RtlCopyMemory(Vpb->VolumeLabel, CdInfo.VolumeLabel, CdInfo.VolumeLabelLength * sizeof(WCHAR));
-  RtlCopyMemory(&DeviceExt->CdInfo, &CdInfo, sizeof(CDINFO));
-
-  NewDeviceObject->Vpb = DeviceToMount->Vpb;
-
-  DeviceExt->VolumeDevice = NewDeviceObject;
-  DeviceExt->StorageDevice = DeviceToMount;
-  DeviceExt->StorageDevice->Vpb->DeviceObject = NewDeviceObject;
-  DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
-  DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
-  NewDeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
-  NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-
-  /* Close (and cleanup) might be called from IoCreateStreamFileObject 
-   * but we use this resource from CdfsCleanup, therefore it should be
-   * initialized no later than this. */
-  ExInitializeResourceLite(&DeviceExt->DirResource);
-
-  DeviceExt->StreamFileObject = IoCreateStreamFileObject(NULL,
-                                                        DeviceExt->StorageDevice);
-
-  Fcb = CdfsCreateFCB(NULL);
-  if (Fcb == NULL)
+    Status = IoCreateDevice(CdfsGlobalData->DriverObject,
+        sizeof(DEVICE_EXTENSION),
+        NULL,
+        FILE_DEVICE_CD_ROM_FILE_SYSTEM,
+        DeviceToMount->Characteristics,
+        FALSE,
+        &NewDeviceObject);
+    if (!NT_SUCCESS(Status))
+        goto ByeBye;
+
+    NewDeviceObject->Flags = NewDeviceObject->Flags | DO_DIRECT_IO;
+    NewDeviceObject->Flags &= ~DO_VERIFY_VOLUME;
+    DeviceExt = (PVOID)NewDeviceObject->DeviceExtension;
+    RtlZeroMemory(DeviceExt,
+        sizeof(DEVICE_EXTENSION));
+
+    Vpb->SerialNumber = CdInfo.SerialNumber;
+    Vpb->VolumeLabelLength = CdInfo.VolumeLabelLength;
+    RtlCopyMemory(Vpb->VolumeLabel, CdInfo.VolumeLabel, CdInfo.VolumeLabelLength * sizeof(WCHAR));
+    RtlCopyMemory(&DeviceExt->CdInfo, &CdInfo, sizeof(CDINFO));
+
+    NewDeviceObject->Vpb = DeviceToMount->Vpb;
+
+    DeviceExt->VolumeDevice = NewDeviceObject;
+    DeviceExt->StorageDevice = DeviceToMount;
+    DeviceExt->StorageDevice->Vpb->DeviceObject = NewDeviceObject;
+    DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
+    DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
+    NewDeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
+    NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+
+    /* Close (and cleanup) might be called from IoCreateStreamFileObject 
+    * but we use this resource from CdfsCleanup, therefore it should be
+    * initialized no later than this. */
+    ExInitializeResourceLite(&DeviceExt->DirResource);
+
+    DeviceExt->StreamFileObject = IoCreateStreamFileObject(NULL,
+        DeviceExt->StorageDevice);
+
+    Fcb = CdfsCreateFCB(NULL);
+    if (Fcb == NULL)
     {
-      Status = STATUS_INSUFFICIENT_RESOURCES;
-      goto ByeBye;
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto ByeBye;
     }
 
-  Ccb = ExAllocatePoolWithTag(NonPagedPool,
-                             sizeof(CCB),
-                             TAG_CCB);
-  if (Ccb == NULL)
+    Ccb = ExAllocatePoolWithTag(NonPagedPool,
+        sizeof(CCB),
+        TAG_CCB);
+    if (Ccb == NULL)
     {
-      Status =  STATUS_INSUFFICIENT_RESOURCES;
-      goto ByeBye;
+        Status =  STATUS_INSUFFICIENT_RESOURCES;
+        goto ByeBye;
     }
-  RtlZeroMemory(Ccb,
-               sizeof(CCB));
+    RtlZeroMemory(Ccb,
+        sizeof(CCB));
 
-  DeviceExt->StreamFileObject->FsContext = Fcb;
-  DeviceExt->StreamFileObject->FsContext2 = Ccb;
-  DeviceExt->StreamFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
-  DeviceExt->StreamFileObject->PrivateCacheMap = NULL;
-  DeviceExt->StreamFileObject->Vpb = DeviceExt->Vpb;
-  Ccb->PtrFileObject = DeviceExt->StreamFileObject;
-  Fcb->FileObject = DeviceExt->StreamFileObject;
-  Fcb->DevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice;
+    DeviceExt->StreamFileObject->ReadAccess = TRUE;
+    DeviceExt->StreamFileObject->WriteAccess = FALSE;
+    DeviceExt->StreamFileObject->DeleteAccess = FALSE;
+    DeviceExt->StreamFileObject->FsContext = Fcb;
+    DeviceExt->StreamFileObject->FsContext2 = Ccb;
+    DeviceExt->StreamFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
+    DeviceExt->StreamFileObject->PrivateCacheMap = NULL;
+    DeviceExt->StreamFileObject->Vpb = DeviceExt->Vpb;
+    Ccb->PtrFileObject = DeviceExt->StreamFileObject;
+    Fcb->FileObject = DeviceExt->StreamFileObject;
+    Fcb->DevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice;
 
-  Fcb->Flags = FCB_IS_VOLUME_STREAM;
+    Fcb->Flags = FCB_IS_VOLUME_STREAM;
 
-  Fcb->RFCB.FileSize.QuadPart = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE;
-  Fcb->RFCB.ValidDataLength = Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize;
+    Fcb->RFCB.FileSize.QuadPart = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE;
+    Fcb->RFCB.ValidDataLength = Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize;
 
-  Fcb->Entry.ExtentLocationL = 0;
-  Fcb->Entry.DataLengthL = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE;
+    Fcb->Entry.ExtentLocationL = 0;
+    Fcb->Entry.DataLengthL = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE;
 
-  CcInitializeCacheMap(DeviceExt->StreamFileObject,
-                       (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
-                      TRUE,
-                      &(CdfsGlobalData->CacheMgrCallbacks),
-                      Fcb);
+    CcInitializeCacheMap(DeviceExt->StreamFileObject,
+        (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
+        TRUE,
+        &(CdfsGlobalData->CacheMgrCallbacks),
+        Fcb);
 
-  ExInitializeResourceLite(&DeviceExt->VcbResource);
+    ExInitializeResourceLite(&DeviceExt->VcbResource);
 
-  KeInitializeSpinLock(&DeviceExt->FcbListLock);
-  InitializeListHead(&DeviceExt->FcbListHead);
+    KeInitializeSpinLock(&DeviceExt->FcbListLock);
+    InitializeListHead(&DeviceExt->FcbListHead);
 
-  Status = STATUS_SUCCESS;
+    Status = STATUS_SUCCESS;
 
 ByeBye:
-  if (!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
-      /* Cleanup */
-      if (DeviceExt && DeviceExt->StreamFileObject)
-       ObDereferenceObject(DeviceExt->StreamFileObject);
-      if (Fcb)
-       ExFreePool(Fcb);
-      if (Ccb)
-       ExFreePool(Ccb);
-      if (NewDeviceObject)
-       IoDeleteDevice(NewDeviceObject);
+        /* Cleanup */
+        if (DeviceExt && DeviceExt->StreamFileObject)
+            ObDereferenceObject(DeviceExt->StreamFileObject);
+        if (Fcb)
+            ExFreePool(Fcb);
+        if (Ccb)
+            ExFreePool(Ccb);
+        if (NewDeviceObject)
+            IoDeleteDevice(NewDeviceObject);
     }
 
-  DPRINT("CdfsMountVolume() done (Status: %lx)\n", Status);
+    DPRINT("CdfsMountVolume() done (Status: %lx)\n", Status);
 
-  return(Status);
+    return(Status);
 }
 
 
 static NTSTATUS
 CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
-                PIRP Irp)
+                 PIRP Irp)
 {
-  PDEVICE_EXTENSION DeviceExt;
-  PDEVICE_OBJECT DeviceToVerify;
-  PIO_STACK_LOCATION Stack;
-  NTSTATUS Status;
-  CDINFO CdInfo;
+    PDEVICE_EXTENSION DeviceExt;
+    PDEVICE_OBJECT DeviceToVerify;
+    PIO_STACK_LOCATION Stack;
+    NTSTATUS Status;
+    CDINFO CdInfo;
 
-  PLIST_ENTRY Entry;
-  PFCB Fcb;
+    PLIST_ENTRY Entry;
+    PFCB Fcb;
 
-  DPRINT1 ("CdfsVerifyVolume() called\n");
+    DPRINT1 ("CdfsVerifyVolume() called\n");
 
 #if 0
-  if (DeviceObject != CdfsGlobalData->DeviceObject)
+    if (DeviceObject != CdfsGlobalData->DeviceObject)
     {
-      DPRINT1("DeviceObject != CdfsGlobalData->DeviceObject\n");
-      return(STATUS_INVALID_DEVICE_REQUEST);
+        DPRINT1("DeviceObject != CdfsGlobalData->DeviceObject\n");
+        return(STATUS_INVALID_DEVICE_REQUEST);
     }
 #endif
 
-  DeviceExt = DeviceObject->DeviceExtension;
+    DeviceExt = DeviceObject->DeviceExtension;
 
-  Stack = IoGetCurrentIrpStackLocation (Irp);
-  DeviceToVerify = Stack->Parameters.VerifyVolume.DeviceObject;
+    Stack = IoGetCurrentIrpStackLocation (Irp);
+    DeviceToVerify = Stack->Parameters.VerifyVolume.DeviceObject;
 
-  ExAcquireResourceExclusiveLite (&DeviceExt->VcbResource,
-                                 TRUE);
+    FsRtlEnterFileSystem();
+    ExAcquireResourceExclusiveLite (&DeviceExt->VcbResource,
+        TRUE);
 
-  if (!(DeviceToVerify->Flags & DO_VERIFY_VOLUME))
+    if (!(DeviceToVerify->Flags & DO_VERIFY_VOLUME))
     {
-      DPRINT1 ("Volume has been verified!\n");
-      ExReleaseResourceLite (&DeviceExt->VcbResource);
-      return STATUS_SUCCESS;
+        DPRINT1 ("Volume has been verified!\n");
+        ExReleaseResourceLite (&DeviceExt->VcbResource);
+        FsRtlExitFileSystem();
+        return STATUS_SUCCESS;
     }
 
-  DPRINT1 ("Device object %p  Device to verify %p\n", DeviceObject, DeviceToVerify);
+    DPRINT1 ("Device object %p  Device to verify %p\n", DeviceObject, DeviceToVerify);
 
-  Status = CdfsGetVolumeData (DeviceToVerify,
-                             &CdInfo);
-  if (NT_SUCCESS(Status) &&
-      CdInfo.SerialNumber == DeviceToVerify->Vpb->SerialNumber &&
-      CdInfo.VolumeLabelLength == DeviceToVerify->Vpb->VolumeLabelLength &&
-      !wcsncmp (CdInfo.VolumeLabel, DeviceToVerify->Vpb->VolumeLabel, CdInfo.VolumeLabelLength))
+    Status = CdfsGetVolumeData (DeviceToVerify,
+        &CdInfo);
+    if (NT_SUCCESS(Status) &&
+        CdInfo.SerialNumber == DeviceToVerify->Vpb->SerialNumber &&
+        CdInfo.VolumeLabelLength == DeviceToVerify->Vpb->VolumeLabelLength &&
+        !wcsncmp (CdInfo.VolumeLabel, DeviceToVerify->Vpb->VolumeLabel, CdInfo.VolumeLabelLength))
     {
-      DPRINT1 ("Same volume!\n");
+        DPRINT1 ("Same volume!\n");
 
-      /* FIXME: Flush and purge metadata */
+        /* FIXME: Flush and purge metadata */
 
-      Status = STATUS_SUCCESS;
+        Status = STATUS_SUCCESS;
     }
-  else
+    else
     {
-      DPRINT1 ("Different volume!\n");
+        DPRINT1 ("Different volume!\n");
 
-      /* FIXME: force volume dismount */
-      Entry = DeviceExt->FcbListHead.Flink;
-      while (Entry != &DeviceExt->FcbListHead)
-       {
-         Fcb = (PFCB)CONTAINING_RECORD(Entry, FCB, FcbListEntry);
-         DPRINT1("OpenFile %S  RefCount %ld\n", Fcb->PathName, Fcb->RefCount);
+        /* FIXME: force volume dismount */
+        Entry = DeviceExt->FcbListHead.Flink;
+        while (Entry != &DeviceExt->FcbListHead)
+        {
+            Fcb = (PFCB)CONTAINING_RECORD(Entry, FCB, FcbListEntry);
+            DPRINT1("OpenFile %S  RefCount %ld\n", Fcb->PathName, Fcb->RefCount);
 
-         Entry = Entry->Flink;
-       }
+            Entry = Entry->Flink;
+        }
 
-      Status = STATUS_WRONG_VOLUME;
+        Status = STATUS_WRONG_VOLUME;
     }
 
-  DeviceToVerify->Flags &= ~DO_VERIFY_VOLUME;
+    DeviceToVerify->Flags &= ~DO_VERIFY_VOLUME;
 
-  ExReleaseResourceLite (&DeviceExt->VcbResource);
+    ExReleaseResourceLite (&DeviceExt->VcbResource);
+    FsRtlExitFileSystem();
 
-  return Status;
+    return Status;
 }
 
 
 NTSTATUS NTAPI
 CdfsSetCompression(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp)
+                   IN PDEVICE_OBJECT DeviceObject,
+                   IN PIRP Irp)
 {
     PIO_STACK_LOCATION Stack;
     USHORT CompressionState;
@@ -535,56 +553,56 @@ CdfsSetCompression(
 }
 
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 CdfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
-                     PIRP Irp)
+                      PIRP Irp)
 {
-  PIO_STACK_LOCATION Stack;
-  NTSTATUS Status;
+    PIO_STACK_LOCATION Stack;
+    NTSTATUS Status;
 
-  DPRINT("CdfsFileSystemControl() called\n");
+    DPRINT("CdfsFileSystemControl() called\n");
 
-  Stack = IoGetCurrentIrpStackLocation(Irp);
+    Stack = IoGetCurrentIrpStackLocation(Irp);
 
-  switch (Stack->MinorFunction)
+    switch (Stack->MinorFunction)
     {
-        case IRP_MN_USER_FS_REQUEST:
-            switch (Stack->Parameters.DeviceIoControl.IoControlCode)
-            {
-                case FSCTL_SET_COMPRESSION:
-                    DPRINT("CDFS: IRP_MN_USER_FS_REQUEST / FSCTL_SET_COMPRESSION\n");
-                    Status = CdfsSetCompression(DeviceObject, Irp);
-                    break;
-
-                default:
-                    DPRINT1("CDFS: IRP_MN_USER_FS_REQUEST / Unknown IoControlCode 0x%x\n",
-                        Stack->Parameters.DeviceIoControl.IoControlCode);
-                    Status = STATUS_INVALID_DEVICE_REQUEST;
-            }
+    case IRP_MN_USER_FS_REQUEST:
+        switch (Stack->Parameters.DeviceIoControl.IoControlCode)
+        {
+        case FSCTL_SET_COMPRESSION:
+            DPRINT("CDFS: IRP_MN_USER_FS_REQUEST / FSCTL_SET_COMPRESSION\n");
+            Status = CdfsSetCompression(DeviceObject, Irp);
             break;
 
-      case IRP_MN_MOUNT_VOLUME:
-       DPRINT("CDFS: IRP_MN_MOUNT_VOLUME\n");
-       Status = CdfsMountVolume(DeviceObject, Irp);
-       break;
-
-      case IRP_MN_VERIFY_VOLUME:
-       DPRINT1("CDFS: IRP_MN_VERIFY_VOLUME\n");
-       Status = CdfsVerifyVolume(DeviceObject, Irp);
-       break;
-
-      default:
-       DPRINT1("CDFS FSC: MinorFunction %d\n", Stack->MinorFunction);
-       Status = STATUS_INVALID_DEVICE_REQUEST;
-       break;
+        default:
+            DPRINT1("CDFS: IRP_MN_USER_FS_REQUEST / Unknown IoControlCode 0x%x\n",
+                Stack->Parameters.DeviceIoControl.IoControlCode);
+            Status = STATUS_INVALID_DEVICE_REQUEST;
+        }
+        break;
+
+    case IRP_MN_MOUNT_VOLUME:
+        DPRINT("CDFS: IRP_MN_MOUNT_VOLUME\n");
+        Status = CdfsMountVolume(DeviceObject, Irp);
+        break;
+
+    case IRP_MN_VERIFY_VOLUME:
+        DPRINT1("CDFS: IRP_MN_VERIFY_VOLUME\n");
+        Status = CdfsVerifyVolume(DeviceObject, Irp);
+        break;
+
+    default:
+        DPRINT1("CDFS FSC: MinorFunction %d\n", Stack->MinorFunction);
+        Status = STATUS_INVALID_DEVICE_REQUEST;
+        break;
     }
 
-  Irp->IoStatus.Status = Status;
-  Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = Status;
+    Irp->IoStatus.Information = 0;
 
-  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-  return(Status);
+    return(Status);
 }
 
 /* EOF */