]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/UDF: Fix creation of UDF logical partition
authorPaulo Alcantara <pcacjr@zytor.com>
Fri, 22 Sep 2017 18:11:32 +0000 (02:11 +0800)
committerStar Zeng <star.zeng@intel.com>
Mon, 25 Sep 2017 07:36:27 +0000 (15:36 +0800)
Do not reserve entire block device size for an UDF file system -
instead, reserve the appropriate space (UDF logical volume space) for
it.

Additionally, only create a logical partition for UDF logical volumes
that are currently supported by EDK2 UDF file system implementation. For
instance, an UDF volume with a single LVD and a single Physical (Type 1)
Partition will be supported.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Reported-by: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
Tested-by: Hao Wu <hao.a.wu@intel.com>
Build-tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
Build-tested-by: Star Zeng <star.zeng@intel.com>
Build-tested-by: Paulo Alcantara <paulo@hp.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
MdeModulePkg/Universal/Disk/UdfDxe/File.c
MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
MdeModulePkg/Universal/Disk/UdfDxe/Udf.c
MdeModulePkg/Universal/Disk/UdfDxe/Udf.h

index 609f56cef69315a4edd016f7c954d510f8695860..8aee30c759e3b4cea9cb17534b9f8a86f5fe84f5 100644 (file)
@@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
   OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-  UINT32      BlockSize;\r
-  EFI_LBA     EndLBA;\r
-  EFI_LBA     DescriptorLBAs[4];\r
-  UINTN       Index;\r
+  EFI_STATUS          Status;\r
+  UINT32              BlockSize;\r
+  EFI_LBA             EndLBA;\r
+  EFI_LBA             DescriptorLBAs[4];\r
+  UINTN               Index;\r
+  UDF_DESCRIPTOR_TAG  *DescriptorTag;\r
 \r
   BlockSize = BlockIo->Media->BlockSize;\r
   EndLBA = BlockIo->Media->LastBlock;\r
@@ -88,10 +89,13 @@ FindAnchorVolumeDescriptorPointer (
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
+\r
+    DescriptorTag = &AnchorPoint->DescriptorTag;\r
+\r
     //\r
     // Check if read LBA has a valid AVDP descriptor.\r
     //\r
-    if (IS_AVDP (AnchorPoint)) {\r
+    if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {\r
       return EFI_SUCCESS;\r
     }\r
   }\r
@@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (
 }\r
 \r
 /**\r
-  Check if block device supports a valid UDF file system as specified by OSTA\r
-  Universal Disk Format Specification 2.60.\r
+  Find UDF volume identifiers in a Volume Recognition Sequence.\r
 \r
-  @param[in]   BlockIo  BlockIo interface.\r
-  @param[in]   DiskIo   DiskIo interface.\r
+  @param[in]  BlockIo             BlockIo interface.\r
+  @param[in]  DiskIo              DiskIo interface.\r
 \r
-  @retval EFI_SUCCESS          UDF file system found.\r
-  @retval EFI_UNSUPPORTED      UDF file system not found.\r
-  @retval EFI_NO_MEDIA         The device has no media.\r
-  @retval EFI_DEVICE_ERROR     The device reported an error.\r
-  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
-  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to lack of\r
-                               resources.\r
+  @retval EFI_SUCCESS             UDF volume identifiers were found.\r
+  @retval EFI_NOT_FOUND           UDF volume identifiers were not found.\r
+  @retval other                   Failed to perform disk I/O.\r
 \r
 **/\r
 EFI_STATUS\r
-SupportUdfFileSystem (\r
+FindUdfVolumeIdentifiers (\r
   IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,\r
   IN EFI_DISK_IO_PROTOCOL   *DiskIo\r
   )\r
@@ -128,7 +127,6 @@ SupportUdfFileSystem (
   UINT64                                EndDiskOffset;\r
   CDROM_VOLUME_DESCRIPTOR               VolDescriptor;\r
   CDROM_VOLUME_DESCRIPTOR               TerminatingVolDescriptor;\r
-  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;\r
 \r
   ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof (CDROM_VOLUME_DESCRIPTOR));\r
 \r
@@ -167,7 +165,7 @@ SupportUdfFileSystem (
         (CompareMem ((VOID *)&VolDescriptor,\r
                      (VOID *)&TerminatingVolDescriptor,\r
                      sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {\r
-      return EFI_UNSUPPORTED;\r
+      return EFI_NOT_FOUND;\r
     }\r
   }\r
 \r
@@ -176,7 +174,7 @@ SupportUdfFileSystem (
   //\r
   Offset += UDF_LOGICAL_SECTOR_SIZE;\r
   if (Offset >= EndDiskOffset) {\r
-    return EFI_UNSUPPORTED;\r
+    return EFI_NOT_FOUND;\r
   }\r
 \r
   Status = DiskIo->ReadDisk (\r
@@ -196,7 +194,7 @@ SupportUdfFileSystem (
       (CompareMem ((VOID *)VolDescriptor.Unknown.Id,\r
                    (VOID *)UDF_NSR3_IDENTIFIER,\r
                    sizeof (VolDescriptor.Unknown.Id)) != 0)) {\r
-    return EFI_UNSUPPORTED;\r
+    return EFI_NOT_FOUND;\r
   }\r
 \r
   //\r
@@ -204,7 +202,7 @@ SupportUdfFileSystem (
   //\r
   Offset += UDF_LOGICAL_SECTOR_SIZE;\r
   if (Offset >= EndDiskOffset) {\r
-    return EFI_UNSUPPORTED;\r
+    return EFI_NOT_FOUND;\r
   }\r
 \r
   Status = DiskIo->ReadDisk (\r
@@ -221,15 +219,291 @@ SupportUdfFileSystem (
   if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,\r
                   (VOID *)UDF_TEA_IDENTIFIER,\r
                   sizeof (VolDescriptor.Unknown.Id)) != 0) {\r
-    return EFI_UNSUPPORTED;\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Check if Logical Volume Descriptor is supported by current EDK2 UDF file\r
+  system implementation.\r
+\r
+  @param[in]  LogicalVolDesc  Logical Volume Descriptor pointer.\r
+\r
+  @retval TRUE                Logical Volume Descriptor is supported.\r
+  @retval FALSE               Logical Volume Descriptor is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+IsLogicalVolumeDescriptorSupported (\r
+  UDF_LOGICAL_VOLUME_DESCRIPTOR *LogicalVolDesc\r
+  )\r
+{\r
+  //\r
+  // Check for a valid UDF revision range\r
+  //\r
+  switch (LogicalVolDesc->DomainIdentifier.Suffix.Domain.UdfRevision) {\r
+  case 0x0102:\r
+  case 0x0150:\r
+  case 0x0200:\r
+  case 0x0201:\r
+  case 0x0250:\r
+  case 0x0260:\r
+    break;\r
+  default:\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check for a single Partition Map\r
+  //\r
+  if (LogicalVolDesc->NumberOfPartitionMaps > 1) {\r
+    return FALSE;\r
+  }\r
+  //\r
+  // UDF 1.02 revision supports only Type 1 (Physical) partitions, but\r
+  // let's check it any way.\r
+  //\r
+  // PartitionMap[0] -> type\r
+  // PartitionMap[1] -> length (in bytes)\r
+  //\r
+  if (LogicalVolDesc->PartitionMaps[0] != 1 ||\r
+      LogicalVolDesc->PartitionMaps[1] != 6) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Find UDF logical volume location and whether it is supported by current EDK2\r
+  UDF file system implementation.\r
+\r
+  @param[in]  BlockIo             BlockIo interface.\r
+  @param[in]  DiskIo              DiskIo interface.\r
+  @param[in]  AnchorPoint         Anchor volume descriptor pointer.\r
+  @param[out] MainVdsStartBlock   Main VDS starting block number.\r
+  @param[out] MainVdsEndBlock     Main VDS ending block number.\r
+\r
+  @retval EFI_SUCCESS             UDF logical volume was found.\r
+  @retval EFI_VOLUME_CORRUPTED    UDF file system structures are corrupted.\r
+  @retval EFI_UNSUPPORTED         UDF logical volume is not supported.\r
+  @retval other                   Failed to perform disk I/O.\r
+\r
+**/\r
+EFI_STATUS\r
+FindLogicalVolumeLocation (\r
+  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,\r
+  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,\r
+  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,\r
+  OUT  UINT64                                *MainVdsStartBlock,\r
+  OUT  UINT64                                *MainVdsEndBlock\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  UINT32                         BlockSize;\r
+  EFI_LBA                        LastBlock;\r
+  UDF_EXTENT_AD                  *ExtentAd;\r
+  UINT64                         SeqBlocksNum;\r
+  UINT64                         SeqStartBlock;\r
+  UINT64                         GuardMainVdsStartBlock;\r
+  VOID                           *Buffer;\r
+  UINT64                         SeqEndBlock;\r
+  BOOLEAN                        StopSequence;\r
+  UINTN                          LvdsCount;\r
+  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;\r
+  UDF_DESCRIPTOR_TAG             *DescriptorTag;\r
+\r
+  BlockSize = BlockIo->Media->BlockSize;\r
+  LastBlock = BlockIo->Media->LastBlock;\r
+  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;\r
+\r
+  //\r
+  // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent\r
+  //\r
+  // The Main Volume Descriptor Sequence Extent shall have a minimum length of\r
+  // 16 logical sectors.\r
+  //\r
+  // Also make sure it does not exceed maximum number of blocks in the disk.\r
+  //\r
+  SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength, BlockSize);\r
+  if (SeqBlocksNum < 16 || (EFI_LBA)SeqBlocksNum > LastBlock + 1) {\r
+    return EFI_VOLUME_CORRUPTED;\r
+  }\r
+\r
+  //\r
+  // Check for valid Volume Descriptor Sequence starting block number\r
+  //\r
+  SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;\r
+  if (SeqStartBlock > LastBlock ||\r
+      SeqStartBlock + SeqBlocksNum - 1 > LastBlock) {\r
+    return EFI_VOLUME_CORRUPTED;\r
+  }\r
+\r
+  GuardMainVdsStartBlock = SeqStartBlock;\r
+\r
+  //\r
+  // Allocate buffer for reading disk blocks\r
+  //\r
+  Buffer = AllocateZeroPool ((UINTN)BlockSize);\r
+  if (Buffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  SeqEndBlock = SeqStartBlock + SeqBlocksNum;\r
+  StopSequence = FALSE;\r
+  LvdsCount = 0;\r
+  Status = EFI_VOLUME_CORRUPTED;\r
+  //\r
+  // Start Main Volume Descriptor Sequence\r
+  //\r
+  for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {\r
+    //\r
+    // Read disk block\r
+    //\r
+    Status = BlockIo->ReadBlocks (\r
+      BlockIo,\r
+      BlockIo->Media->MediaId,\r
+      SeqStartBlock,\r
+      BlockSize,\r
+      Buffer\r
+      );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Out_Free;\r
+    }\r
+\r
+    DescriptorTag = Buffer;\r
+\r
+    //\r
+    // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence\r
+    //\r
+    // - A Volume Descriptor Sequence shall contain one or more Primary Volume\r
+    //   Descriptors.\r
+    // - A Volume Descriptor Sequence shall contain zero or more Implementation\r
+    //   Use Volume Descriptors.\r
+    // - A Volume Descriptor Sequence shall contain zero or more Partition\r
+    //   Descriptors.\r
+    // - A Volume Descriptor Sequence shall contain zero or more Logical Volume\r
+    //   Descriptors.\r
+    // - A Volume Descriptor Sequence shall contain zero or more Unallocated\r
+    //   Space Descriptors.\r
+    //\r
+    switch (DescriptorTag->TagIdentifier) {\r
+    case UdfPrimaryVolumeDescriptor:\r
+    case UdfImplemenationUseVolumeDescriptor:\r
+    case UdfPartitionDescriptor:\r
+    case UdfUnallocatedSpaceDescriptor:\r
+      break;\r
+\r
+    case UdfLogicalVolumeDescriptor:\r
+      LogicalVolDesc = Buffer;\r
+\r
+      //\r
+      // Check for existence of a single LVD and whether it is supported by\r
+      // current EDK2 UDF file system implementation.\r
+      //\r
+      if (++LvdsCount > 1 ||\r
+          !IsLogicalVolumeDescriptorSupported (LogicalVolDesc)) {\r
+        Status = EFI_UNSUPPORTED;\r
+        StopSequence = TRUE;\r
+      }\r
+\r
+      break;\r
+\r
+    case UdfTerminatingDescriptor:\r
+      //\r
+      // Stop the sequence when we find a Terminating Descriptor\r
+      // (aka Unallocated Sector), se we don't have to walk all the unallocated\r
+      // area unnecessarily.\r
+      //\r
+      StopSequence = TRUE;\r
+      break;\r
+\r
+    default:\r
+      //\r
+      // An invalid Volume Descriptor has been found in the sequece. Volume is\r
+      // corrupted.\r
+      //\r
+      Status = EFI_VOLUME_CORRUPTED;\r
+      goto Out_Free;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Check if LVD was found\r
+  //\r
+  if (!EFI_ERROR (Status) && LvdsCount == 1) {\r
+    *MainVdsStartBlock = GuardMainVdsStartBlock;\r
+    //\r
+    // We do not need to read either LVD or PD descriptors to know the last\r
+    // valid block in the found UDF file system. It's already LastBlock.\r
+    //\r
+    *MainVdsEndBlock = LastBlock;\r
+\r
+    Status = EFI_SUCCESS;\r
+  }\r
+\r
+Out_Free:\r
+  //\r
+  // Free block read buffer\r
+  //\r
+  FreePool (Buffer);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Find a supported UDF file system in block device.\r
+\r
+  @param[in]  BlockIo             BlockIo interface.\r
+  @param[in]  DiskIo              DiskIo interface.\r
+  @param[out] StartingLBA         UDF file system starting LBA.\r
+  @param[out] EndingLBA           UDF file system starting LBA.\r
+\r
+  @retval EFI_SUCCESS             UDF file system was found.\r
+  @retval other                   UDF file system was not found.\r
+\r
+**/\r
+EFI_STATUS\r
+FindUdfFileSystem (\r
+  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,\r
+  IN EFI_DISK_IO_PROTOCOL   *DiskIo,\r
+  OUT EFI_LBA               *StartingLBA,\r
+  OUT EFI_LBA               *EndingLBA\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;\r
+\r
+  //\r
+  // Find UDF volume identifiers\r
+  //\r
+  Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
   }\r
 \r
+  //\r
+  // Find Anchor Volume Descriptor Pointer\r
+  //\r
   Status = FindAnchorVolumeDescriptorPointer (BlockIo, DiskIo, &AnchorPoint);\r
   if (EFI_ERROR (Status)) {\r
-    return EFI_UNSUPPORTED;\r
+    return Status;\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  //\r
+  // Find Logical Volume location\r
+  //\r
+  Status = FindLogicalVolumeLocation (\r
+    BlockIo,\r
+    DiskIo,\r
+    &AnchorPoint,\r
+    (UINT64 *)StartingLBA,\r
+    (UINT64 *)EndingLBA\r
+    );\r
+\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -263,9 +537,9 @@ PartitionInstallUdfChildHandles (
   UINT32                       RemainderByMediaBlockSize;\r
   EFI_STATUS                   Status;\r
   EFI_BLOCK_IO_MEDIA           *Media;\r
-  EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode;\r
-  EFI_GUID                     *VendorDefinedGuid;\r
   EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;\r
+  EFI_LBA                      StartingLBA;\r
+  EFI_LBA                      EndingLBA;\r
 \r
   Media = BlockIo->Media;\r
 \r
@@ -281,35 +555,10 @@ PartitionInstallUdfChildHandles (
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  DevicePathNode = DevicePath;\r
-  while (!IsDevicePathEnd (DevicePathNode)) {\r
-    //\r
-    // Do not allow checking for UDF file systems in CDROM "El Torito"\r
-    // partitions, and skip duplicate installation of UDF file system child\r
-    // nodes.\r
-    //\r
-    if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {\r
-      if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {\r
-        return EFI_NOT_FOUND;\r
-      }\r
-      if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP) {\r
-        VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +\r
-                                         OFFSET_OF (VENDOR_DEVICE_PATH, Guid));\r
-        if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {\r
-          return EFI_NOT_FOUND;\r
-        }\r
-      }\r
-    }\r
-    //\r
-    // Try next device path node\r
-    //\r
-    DevicePathNode = NextDevicePathNode (DevicePathNode);\r
-  }\r
-\r
   //\r
-  // Check if block device supports an UDF file system\r
+  // Search for an UDF file system on block device\r
   //\r
-  Status = SupportUdfFileSystem (BlockIo, DiskIo);\r
+  Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA, &EndingLBA);\r
   if (EFI_ERROR (Status)) {\r
     return EFI_NOT_FOUND;\r
   }\r
@@ -334,13 +583,10 @@ PartitionInstallUdfChildHandles (
     DevicePath,\r
     (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,\r
     &PartitionInfo,\r
-    0,\r
-    Media->LastBlock,\r
+    StartingLBA,\r
+    EndingLBA,\r
     Media->BlockSize\r
     );\r
-  if (!EFI_ERROR (Status)) {\r
-    Status = EFI_NOT_FOUND;\r
-  }\r
 \r
   return Status;\r
 }\r
index 625f2c5637d4b2c974f947fb42b1e4b07feb2dde..6f07bf2066dced6e3836ecfa659b3e984c71f063 100644 (file)
@@ -131,7 +131,6 @@ Error_Alloc_Priv_File_Data:
   CleanupFileInformation (&PrivFsData->Root);\r
 \r
 Error_Find_Root_Dir:\r
-  CleanupVolumeInformation (&PrivFsData->Volume);\r
 \r
 Error_Read_Udf_Volume:\r
 Error_Invalid_Params:\r
@@ -429,7 +428,7 @@ UdfRead (
     }\r
     ASSERT (NewFileEntryData != NULL);\r
 \r
-    if (IS_FE_SYMLINK (NewFileEntryData)) {\r
+    if (FE_ICB_FILE_TYPE (NewFileEntryData) == UdfFileEntrySymlink) {\r
       Status = ResolveSymlink (\r
         BlockIo,\r
         DiskIo,\r
@@ -529,7 +528,6 @@ UdfClose (
   EFI_TPL                     OldTpl;\r
   EFI_STATUS                  Status;\r
   PRIVATE_UDF_FILE_DATA       *PrivFileData;\r
-  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;\r
 \r
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
@@ -542,8 +540,6 @@ UdfClose (
 \r
   PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);\r
 \r
-  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData->SimpleFs);\r
-\r
   if (!PrivFileData->IsRootDirectory) {\r
     CleanupFileInformation (&PrivFileData->File);\r
 \r
@@ -552,10 +548,6 @@ UdfClose (
     }\r
   }\r
 \r
-  if (--PrivFsData->OpenFiles == 0) {\r
-    CleanupVolumeInformation (&PrivFsData->Volume);\r
-  }\r
-\r
   FreePool ((VOID *)PrivFileData);\r
 \r
 Exit:\r
@@ -652,7 +644,7 @@ UdfGetPosition (
   // As per UEFI spec, if the file handle is a directory, then the current file\r
   // position has no meaning and the operation is not supported.\r
   //\r
-  if (IS_FID_DIRECTORY_FILE (&PrivFileData->File.FileIdentifierDesc)) {\r
+  if (IS_FID_DIRECTORY_FILE (PrivFileData->File.FileIdentifierDesc)) {\r
     return  EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -788,7 +780,7 @@ UdfGetInfo (
   } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {\r
     String = VolumeLabel;\r
 \r
-    FileSetDesc = PrivFsData->Volume.FileSetDescs[0];\r
+    FileSetDesc = &PrivFsData->Volume.FileSetDesc;\r
 \r
     OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];\r
 \r
@@ -847,7 +839,7 @@ UdfGetInfo (
     FileSystemInfo->Size        = FileSystemInfoLength;\r
     FileSystemInfo->ReadOnly    = TRUE;\r
     FileSystemInfo->BlockSize   =\r
-      LV_BLOCK_SIZE (&PrivFsData->Volume, UDF_DEFAULT_LV_NUM);\r
+      PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;\r
     FileSystemInfo->VolumeSize  = VolumeSize;\r
     FileSystemInfo->FreeSpace   = FreeSpaceSize;\r
 \r
index 5df267761ff6e2c0c115a17342136b38f4834b60..b336ffc553fde30e1b4f426e2429487c4f3a569f 100644 (file)
@@ -38,11 +38,12 @@ FindAnchorVolumeDescriptorPointer (
   OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-  UINT32      BlockSize;\r
-  EFI_LBA     EndLBA;\r
-  EFI_LBA     DescriptorLBAs[4];\r
-  UINTN       Index;\r
+  EFI_STATUS          Status;\r
+  UINT32              BlockSize;\r
+  EFI_LBA             EndLBA;\r
+  EFI_LBA             DescriptorLBAs[4];\r
+  UINTN               Index;\r
+  UDF_DESCRIPTOR_TAG  *DescriptorTag;\r
 \r
   BlockSize = BlockIo->Media->BlockSize;\r
   EndLBA = BlockIo->Media->LastBlock;\r
@@ -62,10 +63,13 @@ FindAnchorVolumeDescriptorPointer (
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
+\r
+    DescriptorTag = &AnchorPoint->DescriptorTag;\r
+\r
     //\r
     // Check if read LBA has a valid AVDP descriptor.\r
     //\r
-    if (IS_AVDP (AnchorPoint)) {\r
+    if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {\r
       return EFI_SUCCESS;\r
     }\r
   }\r
@@ -99,148 +103,98 @@ StartMainVolumeDescriptorSequence (
   OUT  UDF_VOLUME_INFO                       *Volume\r
   )\r
 {\r
-  EFI_STATUS                     Status;\r
-  UINT32                         BlockSize;\r
-  UDF_EXTENT_AD                  *ExtentAd;\r
-  UINT64                         StartingLsn;\r
-  UINT64                         EndingLsn;\r
-  VOID                           *Buffer;\r
-  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;\r
-  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;\r
-  UINTN                          Index;\r
-  UINT32                         LogicalBlockSize;\r
+  EFI_STATUS            Status;\r
+  UINT32                BlockSize;\r
+  UDF_EXTENT_AD         *ExtentAd;\r
+  EFI_LBA               SeqStartBlock;\r
+  EFI_LBA               SeqEndBlock;\r
+  BOOLEAN               StopSequence;\r
+  VOID                  *Buffer;\r
+  UDF_DESCRIPTOR_TAG    *DescriptorTag;\r
+  UINT32                LogicalBlockSize;\r
+\r
+  BlockSize = BlockIo->Media->BlockSize;\r
+  ExtentAd = &AnchorPoint->MainVolumeDescriptorSequenceExtent;\r
 \r
   //\r
-  // We've already found an ADVP on the volume. It contains the extent\r
-  // (MainVolumeDescriptorSequenceExtent) where the Main Volume Descriptor\r
-  // Sequence starts. Therefore, we'll look for Logical Volume Descriptors and\r
-  // Partitions Descriptors and save them in memory, accordingly.\r
-  //\r
-  // Note also that each descriptor will be aligned on a block size (BlockSize)\r
-  // boundary, so we need to read one block at a time.\r
+  // Allocate buffer for reading disk blocks\r
   //\r
-  BlockSize    = BlockIo->Media->BlockSize;\r
-  ExtentAd     = &AnchorPoint->MainVolumeDescriptorSequenceExtent;\r
-  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;\r
-  EndingLsn    = StartingLsn + DivU64x32 (\r
-                                     (UINT64)ExtentAd->ExtentLength,\r
-                                     BlockSize\r
-                                     );\r
-\r
-  Volume->LogicalVolDescs =\r
-    (UDF_LOGICAL_VOLUME_DESCRIPTOR **)AllocateZeroPool (ExtentAd->ExtentLength);\r
-  if (Volume->LogicalVolDescs == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Volume->PartitionDescs =\r
-    (UDF_PARTITION_DESCRIPTOR **)AllocateZeroPool (ExtentAd->ExtentLength);\r
-  if (Volume->PartitionDescs == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Error_Alloc_Pds;\r
-  }\r
-\r
-  Buffer = AllocateZeroPool (BlockSize);\r
+  Buffer = AllocateZeroPool ((UINTN)BlockSize);\r
   if (Buffer == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Error_Alloc_Buf;\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  Volume->LogicalVolDescsNo  = 0;\r
-  Volume->PartitionDescsNo   = 0;\r
-\r
-  while (StartingLsn <= EndingLsn) {\r
-    Status = DiskIo->ReadDisk (\r
-      DiskIo,\r
+  //\r
+  // The logical partition created by Partition driver is relative to the main\r
+  // VDS extent location, so we start the Main Volume Descriptor Sequence at\r
+  // LBA 0.\r
+  //\r
+  // We don't need to check again if we have valid Volume Descriptors here since\r
+  // Partition driver already did.\r
+  //\r
+  SeqStartBlock = 0;\r
+  SeqEndBlock = SeqStartBlock + DivU64x32 ((UINT64)ExtentAd->ExtentLength,\r
+                                           BlockSize);\r
+  StopSequence = FALSE;\r
+  for (; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {\r
+    //\r
+    // Read disk block\r
+    //\r
+    Status = BlockIo->ReadBlocks (\r
+      BlockIo,\r
       BlockIo->Media->MediaId,\r
-      MultU64x32 (StartingLsn, BlockSize),\r
+      SeqStartBlock,\r
       BlockSize,\r
       Buffer\r
       );\r
     if (EFI_ERROR (Status)) {\r
-      goto Error_Read_Disk_Blk;\r
+      goto Out_Free;\r
     }\r
 \r
-    if (IS_TD (Buffer)) {\r
+    DescriptorTag = Buffer;\r
+\r
+    switch (DescriptorTag->TagIdentifier) {\r
+    case UdfPartitionDescriptor:\r
       //\r
-      // Found a Terminating Descriptor. Stop the sequence then.\r
+      // Save Partition Descriptor\r
       //\r
+      CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume->PartitionDesc));\r
       break;\r
-    }\r
 \r
-    if (IS_LVD (Buffer)) {\r
+    case UdfLogicalVolumeDescriptor:\r
       //\r
-      // Found a Logical Volume Descriptor.\r
+      // Save Logical Volume Descriptor\r
       //\r
-      LogicalVolDesc =\r
-        (UDF_LOGICAL_VOLUME_DESCRIPTOR *)\r
-        AllocateZeroPool (sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));\r
-      if (LogicalVolDesc == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Error_Alloc_Lvd;\r
-      }\r
+      CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume->LogicalVolDesc));\r
+      break;\r
 \r
-      CopyMem ((VOID *)LogicalVolDesc, Buffer,\r
-               sizeof (UDF_LOGICAL_VOLUME_DESCRIPTOR));\r
-      Volume->LogicalVolDescs[Volume->LogicalVolDescsNo++] = LogicalVolDesc;\r
-    } else if (IS_PD (Buffer)) {\r
-      //\r
-      // Found a Partition Descriptor.\r
-      //\r
-      PartitionDesc =\r
-        (UDF_PARTITION_DESCRIPTOR *)\r
-        AllocateZeroPool (sizeof (UDF_PARTITION_DESCRIPTOR));\r
-      if (PartitionDesc == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Error_Alloc_Pd;\r
-      }\r
+    case UdfTerminatingDescriptor:\r
+      StopSequence = TRUE;\r
+      break;\r
 \r
-      CopyMem ((VOID *)PartitionDesc, Buffer,\r
-               sizeof (UDF_PARTITION_DESCRIPTOR));\r
-      Volume->PartitionDescs[Volume->PartitionDescsNo++] = PartitionDesc;\r
+    default:\r
+      ;\r
     }\r
-\r
-    StartingLsn++;\r
   }\r
 \r
   //\r
-  // When an UDF volume (revision 2.00 or higher) contains a File Entry rather\r
-  // than an Extended File Entry (which is not recommended as per spec), we need\r
-  // to make sure the size of a FE will be _at least_ 2048\r
-  // (UDF_LOGICAL_SECTOR_SIZE) bytes long to keep backward compatibility.\r
+  // Determine FE (File Entry) size\r
   //\r
-  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);\r
+  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;\r
   if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {\r
-    Volume->FileEntrySize = LogicalBlockSize;\r
+    Volume->FileEntrySize = (UINTN)LogicalBlockSize;\r
   } else {\r
     Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;\r
   }\r
 \r
-  FreePool (Buffer);\r
+  Status = EFI_SUCCESS;\r
 \r
-  return EFI_SUCCESS;\r
-\r
-Error_Alloc_Pd:\r
-Error_Alloc_Lvd:\r
-  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {\r
-    FreePool ((VOID *)Volume->PartitionDescs[Index]);\r
-  }\r
-\r
-  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {\r
-    FreePool ((VOID *)Volume->LogicalVolDescs[Index]);\r
-  }\r
-\r
-Error_Read_Disk_Blk:\r
+Out_Free:\r
+  //\r
+  // Free block read buffer\r
+  //\r
   FreePool (Buffer);\r
 \r
-Error_Alloc_Buf:\r
-  FreePool ((VOID *)Volume->PartitionDescs);\r
-  Volume->PartitionDescs = NULL;\r
-\r
-Error_Alloc_Pds:\r
-  FreePool ((VOID *)Volume->LogicalVolDescs);\r
-  Volume->LogicalVolDescs = NULL;\r
-\r
   return Status;\r
 }\r
 \r
@@ -262,48 +216,53 @@ GetPdFromLongAd (
   )\r
 {\r
   UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;\r
-  UINTN                          Index;\r
-  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;\r
   UINT16                         PartitionNum;\r
 \r
-  LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];\r
+  LogicalVolDesc = &Volume->LogicalVolDesc;\r
 \r
-  switch (LV_UDF_REVISION (LogicalVolDesc)) {\r
+  switch (LogicalVolDesc->DomainIdentifier.Suffix.Domain.UdfRevision) {\r
   case 0x0102:\r
+  case 0x0150:\r
+  case 0x0200:\r
+  case 0x0201:\r
+  case 0x0250:\r
+  case 0x0260:\r
     //\r
-    // As per UDF 1.02 specification:\r
+    // UDF 1.02 specification:\r
     //\r
     // There shall be exactly one prevailing Logical Volume Descriptor recorded\r
     // per Volume Set. The Partition Maps field shall contain only Type 1\r
     // Partition Maps.\r
     //\r
-    PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);\r
-    break;\r
-  case 0x0150:\r
+    // UDF 1.50 through 2.60 specs say:\r
     //\r
-    // Ensure Type 1 Partition map. Other types aren't supported in this\r
-    // implementation.\r
+    // For the purpose of interchange partition maps shall be limited to\r
+    // Partition Map type 1, except type 2 maps as described in the document.\r
+    //\r
+    // NOTE: Only one Type 1 (Physical) Partition is supported. It has been\r
+    // checked already in Partition driver for existence of a single Type 1\r
+    // Partition map, so we don't have to double check here.\r
+    //\r
+    // Partition reference number can also be retrieved from\r
+    // LongAd->ExtentLocation.PartitionReferenceNumber, however the spec says\r
+    // it may be 0, so let's not rely on it.\r
     //\r
-    if (LogicalVolDesc->PartitionMaps[0] != 1 ||\r
-        LogicalVolDesc->PartitionMaps[1] != 6) {\r
-      return NULL;\r
-    }\r
     PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);\r
     break;\r
-  case 0x0260:\r
+\r
+  default:\r
     //\r
-    // Fall through.\r
+    // Unsupported UDF revision\r
     //\r
-  default:\r
-    PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;\r
-    break;\r
+    return NULL;\r
   }\r
 \r
-  for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {\r
-    PartitionDesc = Volume->PartitionDescs[Index];\r
-    if (PartitionDesc->PartitionNumber == PartitionNum) {\r
-      return PartitionDesc;\r
-    }\r
+  //\r
+  // Check if partition number matches Partition Descriptor found in Main Volume\r
+  // Descriptor Sequence.\r
+  //\r
+  if (Volume->PartitionDesc.PartitionNumber == PartitionNum) {\r
+    return &Volume->PartitionDesc;\r
   }\r
 \r
   return NULL;\r
@@ -329,13 +288,15 @@ GetLongAdLsn (
   PartitionDesc = GetPdFromLongAd (Volume, LongAd);\r
   ASSERT (PartitionDesc != NULL);\r
 \r
-  return (UINT64)PartitionDesc->PartitionStartingLocation +\r
-                 LongAd->ExtentLocation.LogicalBlockNumber;\r
+  return (UINT64)PartitionDesc->PartitionStartingLocation -\r
+    Volume->MainVdsStartLocation +\r
+    LongAd->ExtentLocation.LogicalBlockNumber;\r
 }\r
 \r
 /**\r
   Return logical sector number of a given Short Allocation Descriptor.\r
 \r
+  @param[in]  Volume              Volume pointer.\r
   @param[in]  PartitionDesc       Partition Descriptor pointer.\r
   @param[in]  ShortAd             Short Allocation Descriptor pointer.\r
 \r
@@ -344,14 +305,13 @@ GetLongAdLsn (
 **/\r
 UINT64\r
 GetShortAdLsn (\r
+  IN UDF_VOLUME_INFO                  *Volume,\r
   IN UDF_PARTITION_DESCRIPTOR         *PartitionDesc,\r
   IN UDF_SHORT_ALLOCATION_DESCRIPTOR  *ShortAd\r
   )\r
 {\r
-  ASSERT (PartitionDesc != NULL);\r
-\r
-  return (UINT64)PartitionDesc->PartitionStartingLocation +\r
-    ShortAd->ExtentPosition;\r
+  return (UINT64)PartitionDesc->PartitionStartingLocation -\r
+    Volume->MainVdsStartLocation + ShortAd->ExtentPosition;\r
 }\r
 \r
 /**\r
@@ -363,8 +323,6 @@ GetShortAdLsn (
   @param[in]  BlockIo             BlockIo interface.\r
   @param[in]  DiskIo              DiskIo interface.\r
   @param[in]  Volume              Volume information pointer.\r
-  @param[in]  LogicalVolDescNum   Index of Logical Volume Descriptor\r
-  @param[out] FileSetDesc         File Set Descriptor pointer.\r
 \r
   @retval EFI_SUCCESS             File Set Descriptor pointer found.\r
   @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.\r
@@ -375,118 +333,48 @@ EFI_STATUS
 FindFileSetDescriptor (\r
   IN   EFI_BLOCK_IO_PROTOCOL    *BlockIo,\r
   IN   EFI_DISK_IO_PROTOCOL     *DiskIo,\r
-  IN   UDF_VOLUME_INFO          *Volume,\r
-  IN   UINTN                    LogicalVolDescNum,\r
-  OUT  UDF_FILE_SET_DESCRIPTOR  *FileSetDesc\r
+  IN   UDF_VOLUME_INFO          *Volume\r
   )\r
 {\r
   EFI_STATUS                     Status;\r
   UINT64                         Lsn;\r
   UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;\r
+  UDF_DESCRIPTOR_TAG             *DescriptorTag;\r
 \r
-  LogicalVolDesc = Volume->LogicalVolDescs[LogicalVolDescNum];\r
+  LogicalVolDesc = &Volume->LogicalVolDesc;\r
   Lsn = GetLongAdLsn (Volume, &LogicalVolDesc->LogicalVolumeContentsUse);\r
 \r
   //\r
-  // Read extent (Long Ad).\r
+  // As per UDF 2.60 specification:\r
+  //\r
+  // There shall be exactly one File Set Descriptor recorded per Logical\r
+  // Volume.\r
+  //\r
+  // Read disk block\r
   //\r
   Status = DiskIo->ReadDisk (\r
     DiskIo,\r
     BlockIo->Media->MediaId,\r
     MultU64x32 (Lsn, LogicalVolDesc->LogicalBlockSize),\r
-    sizeof (UDF_FILE_SET_DESCRIPTOR),\r
-    (VOID *)FileSetDesc\r
+    sizeof (Volume->FileSetDesc),\r
+    &Volume->FileSetDesc\r
     );\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
+  DescriptorTag = &Volume->FileSetDesc.DescriptorTag;\r
+\r
   //\r
-  // Check if the read extent contains a valid FSD's tag identifier.\r
+  // Check if read block is a File Set Descriptor\r
   //\r
-  if (!IS_FSD (FileSetDesc)) {\r
+  if (DescriptorTag->TagIdentifier != UdfFileSetDescriptor) {\r
     return EFI_VOLUME_CORRUPTED;\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-/**\r
-  Get all File Set Descriptors for each Logical Volume Descriptor.\r
-\r
-  @param[in]      BlockIo         BlockIo interface.\r
-  @param[in]      DiskIo          DiskIo interface.\r
-  @param[in, out] Volume          Volume information pointer.\r
-\r
-  @retval EFI_SUCCESS             File Set Descriptors were got.\r
-  @retval EFI_OUT_OF_RESOURCES    File Set Descriptors were not got due to lack\r
-                                  of resources.\r
-  @retval other                   Error occured when finding File Set\r
-                                  Descriptor in Logical Volume Descriptor.\r
-\r
-**/\r
-EFI_STATUS\r
-GetFileSetDescriptors (\r
-  IN      EFI_BLOCK_IO_PROTOCOL  *BlockIo,\r
-  IN      EFI_DISK_IO_PROTOCOL   *DiskIo,\r
-  IN OUT  UDF_VOLUME_INFO        *Volume\r
-  )\r
-{\r
-  EFI_STATUS               Status;\r
-  UINTN                    Index;\r
-  UDF_FILE_SET_DESCRIPTOR  *FileSetDesc;\r
-  UINTN                    Count;\r
-\r
-  Volume->FileSetDescs =\r
-    (UDF_FILE_SET_DESCRIPTOR **)AllocateZeroPool (\r
-      Volume->LogicalVolDescsNo * sizeof (UDF_FILE_SET_DESCRIPTOR));\r
-  if (Volume->FileSetDescs == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {\r
-    FileSetDesc = AllocateZeroPool (sizeof (UDF_FILE_SET_DESCRIPTOR));\r
-    if (FileSetDesc == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      goto Error_Alloc_Fsd;\r
-    }\r
-\r
-    //\r
-    // Find a FSD for this LVD.\r
-    //\r
-    Status = FindFileSetDescriptor (\r
-      BlockIo,\r
-      DiskIo,\r
-      Volume,\r
-      Index,\r
-      FileSetDesc\r
-      );\r
-    if (EFI_ERROR (Status)) {\r
-      goto Error_Find_Fsd;\r
-    }\r
-\r
-    //\r
-    // Got one. Save it.\r
-    //\r
-    Volume->FileSetDescs[Index] = FileSetDesc;\r
-  }\r
-\r
-  Volume->FileSetDescsNo = Volume->LogicalVolDescsNo;\r
-  return EFI_SUCCESS;\r
-\r
-Error_Find_Fsd:\r
-  Count = Index + 1;\r
-  for (Index = 0; Index < Count; Index++) {\r
-    FreePool ((VOID *)Volume->FileSetDescs[Index]);\r
-  }\r
-\r
-  FreePool ((VOID *)Volume->FileSetDescs);\r
-  Volume->FileSetDescs = NULL;\r
-\r
-Error_Alloc_Fsd:\r
-  return Status;\r
-}\r
-\r
 /**\r
   Read Volume and File Structure on an UDF file system.\r
 \r
@@ -507,9 +395,10 @@ ReadVolumeFileStructure (
 {\r
   EFI_STATUS                            Status;\r
   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;\r
+  UDF_EXTENT_AD                         *ExtentAd;\r
 \r
   //\r
-  // Find an AVDP.\r
+  // Find Anchor Volume Descriptor Pointer\r
   //\r
   Status = FindAnchorVolumeDescriptorPointer (\r
     BlockIo,\r
@@ -521,7 +410,14 @@ ReadVolumeFileStructure (
   }\r
 \r
   //\r
-  // AVDP has been found. Start MVDS.\r
+  // Save Main VDS start block number\r
+  //\r
+  ExtentAd = &AnchorPoint.MainVolumeDescriptorSequenceExtent;\r
+\r
+  Volume->MainVdsStartLocation = (UINT64)ExtentAd->ExtentLocation;\r
+\r
+  //\r
+  // Start Main Volume Descriptor Sequence.\r
   //\r
   Status = StartMainVolumeDescriptorSequence (\r
     BlockIo,\r
@@ -620,16 +516,19 @@ GetFileEntryData (
   OUT  UINT64  *Length\r
   )\r
 {\r
+  UDF_DESCRIPTOR_TAG       *DescriptorTag;\r
   UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;\r
   UDF_FILE_ENTRY           *FileEntry;\r
 \r
-  if (IS_EFE (FileEntryData)) {\r
+  DescriptorTag = FileEntryData;\r
+\r
+  if (DescriptorTag->TagIdentifier == UdfExtendedFileEntry) {\r
     ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;\r
 \r
     *Length  = ExtendedFileEntry->InformationLength;\r
     *Data    = (VOID *)((UINT8 *)ExtendedFileEntry->Data +\r
                         ExtendedFileEntry->LengthOfExtendedAttributes);\r
-  } else if (IS_FE (FileEntryData)) {\r
+  } else if (DescriptorTag->TagIdentifier == UdfFileEntry) {\r
     FileEntry = (UDF_FILE_ENTRY *)FileEntryData;\r
 \r
     *Length  = FileEntry->InformationLength;\r
@@ -654,16 +553,19 @@ GetAdsInformation (
   OUT  UINT64  *Length\r
   )\r
 {\r
+  UDF_DESCRIPTOR_TAG       *DescriptorTag;\r
   UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;\r
   UDF_FILE_ENTRY           *FileEntry;\r
 \r
-  if (IS_EFE (FileEntryData)) {\r
+  DescriptorTag = FileEntryData;\r
+\r
+  if (DescriptorTag->TagIdentifier == UdfExtendedFileEntry) {\r
     ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;\r
 \r
     *Length = ExtendedFileEntry->LengthOfAllocationDescriptors;\r
     *AdsData = (VOID *)((UINT8 *)ExtendedFileEntry->Data +\r
                         ExtendedFileEntry->LengthOfExtendedAttributes);\r
-  } else if (IS_FE (FileEntryData)) {\r
+  } else if (DescriptorTag->TagIdentifier == UdfFileEntry) {\r
     FileEntry = (UDF_FILE_ENTRY *)FileEntryData;\r
 \r
     *Length = FileEntry->LengthOfAllocationDescriptors;\r
@@ -850,6 +752,7 @@ GetAllocationDescriptorLsn (
     return GetLongAdLsn (Volume, (UDF_LONG_ALLOCATION_DESCRIPTOR *)Ad);\r
   } else if (RecordingFlags == ShortAdsSequence) {\r
     return GetShortAdLsn (\r
+      Volume,\r
       GetPdFromLongAd (Volume, ParentIcb),\r
       (UDF_SHORT_ALLOCATION_DESCRIPTOR *)Ad\r
       );\r
@@ -897,6 +800,7 @@ GetAedAdsOffset (
   VOID                              *Data;\r
   UINT32                            LogicalBlockSize;\r
   UDF_ALLOCATION_EXTENT_DESCRIPTOR  *AllocExtDesc;\r
+  UDF_DESCRIPTOR_TAG                *DescriptorTag;\r
 \r
   ExtentLength  = GET_EXTENT_LENGTH (RecordingFlags, Ad);\r
   Lsn           = GetAllocationDescriptorLsn (RecordingFlags,\r
@@ -909,7 +813,7 @@ GetAedAdsOffset (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);\r
+  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;\r
 \r
   //\r
   // Read extent.\r
@@ -925,11 +829,14 @@ GetAedAdsOffset (
     goto Exit;\r
   }\r
 \r
+  AllocExtDesc = (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data;\r
+\r
+  DescriptorTag = &AllocExtDesc->DescriptorTag;\r
+\r
   //\r
   // Check if read extent contains a valid tag identifier for AED.\r
   //\r
-  AllocExtDesc = (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data;\r
-  if (!IS_AED (AllocExtDesc)) {\r
+  if (DescriptorTag->TagIdentifier != UdfAllocationExtentDescriptor) {\r
     Status = EFI_VOLUME_CORRUPTED;\r
     goto Exit;\r
   }\r
@@ -1102,7 +1009,7 @@ ReadFile (
   UINT32                  ExtentLength;\r
   UDF_FE_RECORDING_FLAGS  RecordingFlags;\r
 \r
-  LogicalBlockSize  = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);\r
+  LogicalBlockSize  = Volume->LogicalVolDesc.LogicalBlockSize;\r
   DoFreeAed         = FALSE;\r
 \r
   //\r
@@ -1444,7 +1351,7 @@ InternalFindFile (
   //\r
   // Check if parent file is really directory.\r
   //\r
-  if (!IS_FE_DIRECTORY (Parent->FileEntry)) {\r
+  if (FE_ICB_FILE_TYPE (Parent->FileEntry) != UdfFileEntryDirectory) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
@@ -1489,7 +1396,7 @@ InternalFindFile (
       break;\r
     }\r
 \r
-    if (IS_FID_PARENT_FILE (FileIdentifierDesc)) {\r
+    if (FileIdentifierDesc->FileCharacteristics & PARENT_FILE) {\r
       //\r
       // This FID contains the location (FE/EFE) of the parent directory of this\r
       // directory (Parent), and if FileName is either ".." or "\\", then it's\r
@@ -1592,6 +1499,9 @@ ReadUdfVolumeInformation (
 {\r
   EFI_STATUS Status;\r
 \r
+  //\r
+  // Read all necessary UDF volume information and keep it private to the driver\r
+  //\r
   Status = ReadVolumeFileStructure (\r
     BlockIo,\r
     DiskIo,\r
@@ -1601,13 +1511,12 @@ ReadUdfVolumeInformation (
     return Status;\r
   }\r
 \r
-  Status = GetFileSetDescriptors (\r
-    BlockIo,\r
-    DiskIo,\r
-    Volume\r
-    );\r
+  //\r
+  // Find File Set Descriptor\r
+  //\r
+  Status = FindFileSetDescriptor (BlockIo, DiskIo, Volume);\r
   if (EFI_ERROR (Status)) {\r
-    CleanupVolumeInformation (Volume);\r
+    return Status;\r
   }\r
 \r
   return Status;\r
@@ -1644,7 +1553,7 @@ FindRootDirectory (
     BlockIo,\r
     DiskIo,\r
     Volume,\r
-    &Volume->FileSetDescs[0]->RootDirectoryIcb,\r
+    &Volume->FileSetDesc.RootDirectoryIcb,\r
     &File->FileEntry\r
     );\r
   if (EFI_ERROR (Status)) {\r
@@ -1661,7 +1570,7 @@ FindRootDirectory (
     L"\\",\r
     NULL,\r
     &Parent,\r
-    &Volume->FileSetDescs[0]->RootDirectoryIcb,\r
+    &Volume->FileSetDesc.RootDirectoryIcb,\r
     File\r
     );\r
   if (EFI_ERROR (Status)) {\r
@@ -1697,12 +1606,13 @@ FindFileEntry (
   OUT  VOID                            **FileEntry\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-  UINT64      Lsn;\r
-  UINT32      LogicalBlockSize;\r
+  EFI_STATUS          Status;\r
+  UINT64              Lsn;\r
+  UINT32              LogicalBlockSize;\r
+  UDF_DESCRIPTOR_TAG  *DescriptorTag;\r
 \r
   Lsn               = GetLongAdLsn (Volume, Icb);\r
-  LogicalBlockSize  = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);\r
+  LogicalBlockSize  = Volume->LogicalVolDesc.LogicalBlockSize;\r
 \r
   *FileEntry = AllocateZeroPool (Volume->FileEntrySize);\r
   if (*FileEntry == NULL) {\r
@@ -1723,11 +1633,14 @@ FindFileEntry (
     goto Error_Read_Disk_Blk;\r
   }\r
 \r
+  DescriptorTag = *FileEntry;\r
+\r
   //\r
   // Check if the read extent contains a valid Tag Identifier for the expected\r
   // FE/EFE.\r
   //\r
-  if (!IS_FE (*FileEntry) && !IS_EFE (*FileEntry)) {\r
+  if (DescriptorTag->TagIdentifier != UdfFileEntry &&\r
+      DescriptorTag->TagIdentifier != UdfExtendedFileEntry) {\r
     Status = EFI_VOLUME_CORRUPTED;\r
     goto Error_Invalid_Fe;\r
   }\r
@@ -1837,7 +1750,7 @@ FindFile (
     // If the found file is a symlink, then find its respective FE/EFE and\r
     // FID descriptors.\r
     //\r
-    if (IS_FE_SYMLINK (File->FileEntry)) {\r
+    if (FE_ICB_FILE_TYPE (File->FileEntry) == UdfFileEntrySymlink) {\r
       FreePool ((VOID *)File->FileIdentifierDesc);\r
 \r
       FileEntry = File->FileEntry;\r
@@ -1951,7 +1864,7 @@ ReadDirectoryEntry (
     // Update FidOffset to point to next FID.\r
     //\r
     ReadDirInfo->FidOffset += GetFidDescriptorLength (FileIdentifierDesc);\r
-  } while (IS_FID_DELETED_FILE (FileIdentifierDesc));\r
+  } while (FileIdentifierDesc->FileCharacteristics & DELETED_FILE);\r
 \r
   DuplicateFid (FileIdentifierDesc, FoundFid);\r
 \r
@@ -2196,43 +2109,6 @@ Error_Find_File:
   return Status;\r
 }\r
 \r
-/**\r
-  Clean up in-memory UDF volume information.\r
-\r
-  @param[in] Volume Volume information pointer.\r
-\r
-**/\r
-VOID\r
-CleanupVolumeInformation (\r
-  IN UDF_VOLUME_INFO *Volume\r
-  )\r
-{\r
-  UINTN Index;\r
-\r
-  if (Volume->LogicalVolDescs != NULL) {\r
-    for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {\r
-      FreePool ((VOID *)Volume->LogicalVolDescs[Index]);\r
-    }\r
-    FreePool ((VOID *)Volume->LogicalVolDescs);\r
-  }\r
-\r
-  if (Volume->PartitionDescs != NULL) {\r
-    for (Index = 0; Index < Volume->PartitionDescsNo; Index++) {\r
-      FreePool ((VOID *)Volume->PartitionDescs[Index]);\r
-    }\r
-    FreePool ((VOID *)Volume->PartitionDescs);\r
-  }\r
-\r
-  if (Volume->FileSetDescs != NULL) {\r
-    for (Index = 0; Index < Volume->FileSetDescsNo; Index++) {\r
-      FreePool ((VOID *)Volume->FileSetDescs[Index]);\r
-    }\r
-    FreePool ((VOID *)Volume->FileSetDescs);\r
-  }\r
-\r
-  ZeroMem ((VOID *)Volume, sizeof (UDF_VOLUME_INFO));\r
-}\r
-\r
 /**\r
   Clean up in-memory UDF file information.\r
 \r
@@ -2333,6 +2209,7 @@ SetFileInfo (
   EFI_FILE_INFO            *FileInfo;\r
   UDF_FILE_ENTRY           *FileEntry;\r
   UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;\r
+  UDF_DESCRIPTOR_TAG       *DescriptorTag;\r
 \r
   //\r
   // Calculate the needed size for the EFI_FILE_INFO structure.\r
@@ -2367,7 +2244,9 @@ SetFileInfo (
     FileInfo->Attribute |= EFI_FILE_HIDDEN;\r
   }\r
 \r
-  if (IS_FE (File->FileEntry)) {\r
+  DescriptorTag = File->FileEntry;\r
+\r
+  if (DescriptorTag->TagIdentifier == UdfFileEntry) {\r
     FileEntry = (UDF_FILE_ENTRY *)File->FileEntry;\r
 \r
     //\r
@@ -2403,7 +2282,7 @@ SetFileInfo (
                                    FileEntry->AccessTime.Second;\r
     FileInfo->LastAccessTime.Nanosecond  =\r
                                    FileEntry->AccessTime.HundredsOfMicroseconds;\r
-  } else if (IS_EFE (File->FileEntry)) {\r
+  } else if (DescriptorTag->TagIdentifier == UdfExtendedFileEntry) {\r
     ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)File->FileEntry;\r
 \r
     //\r
@@ -2487,91 +2366,103 @@ GetVolumeSize (
   OUT  UINT64                 *FreeSpaceSize\r
   )\r
 {\r
-  UDF_EXTENT_AD                 ExtentAd;\r
-  UINT32                        LogicalBlockSize;\r
-  UINT64                        Lsn;\r
-  EFI_STATUS                    Status;\r
-  UDF_LOGICAL_VOLUME_INTEGRITY  *LogicalVolInt;\r
-  UINTN                         Index;\r
-  UINTN                         Length;\r
-  UINT32                        LsnsNo;\r
-\r
-  *VolumeSize     = 0;\r
-  *FreeSpaceSize  = 0;\r
-\r
-  for (Index = 0; Index < Volume->LogicalVolDescsNo; Index++) {\r
-    CopyMem ((VOID *)&ExtentAd,\r
-             (VOID *)&Volume->LogicalVolDescs[Index]->IntegritySequenceExtent,\r
-             sizeof (UDF_EXTENT_AD));\r
-    if (ExtentAd.ExtentLength == 0) {\r
-      continue;\r
-    }\r
+  EFI_STATUS                     Status;\r
+  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;\r
+  UDF_EXTENT_AD                  *ExtentAd;\r
+  UINT64                         Lsn;\r
+  UINT32                         LogicalBlockSize;\r
+  UDF_LOGICAL_VOLUME_INTEGRITY   *LogicalVolInt;\r
+  UDF_DESCRIPTOR_TAG             *DescriptorTag;\r
+  UINTN                          Index;\r
+  UINTN                          Length;\r
+  UINT32                         LsnsNo;\r
 \r
-    LogicalBlockSize = LV_BLOCK_SIZE (Volume, Index);\r
+  LogicalVolDesc = &Volume->LogicalVolDesc;\r
 \r
-  Read_Next_Sequence:\r
-    LogicalVolInt = (UDF_LOGICAL_VOLUME_INTEGRITY *)\r
-      AllocatePool (ExtentAd.ExtentLength);\r
-    if (LogicalVolInt == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
+  ExtentAd = &LogicalVolDesc->IntegritySequenceExtent;\r
+\r
+  if (ExtentAd->ExtentLength == 0) {\r
+    return EFI_VOLUME_CORRUPTED;\r
+  }\r
 \r
-    Lsn = (UINT64)ExtentAd.ExtentLocation;\r
+  LogicalVolInt = AllocatePool (ExtentAd->ExtentLength);\r
+  if (LogicalVolInt == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
 \r
-    Status = DiskIo->ReadDisk (\r
-      DiskIo,\r
-      BlockIo->Media->MediaId,\r
-      MultU64x32 (Lsn, LogicalBlockSize),\r
-      ExtentAd.ExtentLength,\r
-      (VOID *)LogicalVolInt\r
-      );\r
-    if (EFI_ERROR (Status)) {\r
-      FreePool ((VOID *)LogicalVolInt);\r
-      return Status;\r
-    }\r
+  //\r
+  // Get location of Logical Volume Integrity Descriptor\r
+  //\r
+  Lsn = (UINT64)ExtentAd->ExtentLocation - Volume->MainVdsStartLocation;\r
 \r
-    if (!IS_LVID (LogicalVolInt)) {\r
-      FreePool ((VOID *)LogicalVolInt);\r
-      return EFI_VOLUME_CORRUPTED;\r
-    }\r
+  LogicalBlockSize = LogicalVolDesc->LogicalBlockSize;\r
 \r
-    Length = LogicalVolInt->NumberOfPartitions;\r
-    for (Index = 0; Index < Length; Index += sizeof (UINT32)) {\r
-      LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);\r
-      if (LsnsNo == 0xFFFFFFFFUL) {\r
-        //\r
-        // Size not specified.\r
-        //\r
-        continue;\r
-      }\r
+  //\r
+  // Read disk block\r
+  //\r
+  Status = DiskIo->ReadDisk (\r
+    DiskIo,\r
+    BlockIo->Media->MediaId,\r
+    MultU64x32 (Lsn, LogicalBlockSize),\r
+    ExtentAd->ExtentLength,\r
+    LogicalVolInt\r
+    );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Out_Free;\r
+  }\r
 \r
-      *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);\r
-    }\r
+  DescriptorTag = &LogicalVolInt->DescriptorTag;\r
 \r
-    Length = (LogicalVolInt->NumberOfPartitions * sizeof (UINT32)) << 1;\r
-    for (; Index < Length; Index += sizeof (UINT32)) {\r
-      LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);\r
-      if (LsnsNo == 0xFFFFFFFFUL) {\r
-        //\r
-        // Size not specified.\r
-        //\r
-        continue;\r
-      }\r
+  //\r
+  // Check if read block is a Logical Volume Integrity Descriptor\r
+  //\r
+  if (DescriptorTag->TagIdentifier != UdfLogicalVolumeIntegrityDescriptor) {\r
+    Status = EFI_VOLUME_CORRUPTED;\r
+    goto Out_Free;\r
+  }\r
 \r
-      *VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);\r
-    }\r
+  *VolumeSize = 0;\r
+  *FreeSpaceSize = 0;\r
 \r
-    CopyMem ((VOID *)&ExtentAd,(VOID *)&LogicalVolInt->NextIntegrityExtent,\r
-             sizeof (UDF_EXTENT_AD));\r
-    if (ExtentAd.ExtentLength > 0) {\r
-      FreePool ((VOID *)LogicalVolInt);\r
-      goto Read_Next_Sequence;\r
+  Length = LogicalVolInt->NumberOfPartitions;\r
+  for (Index = 0; Index < Length; Index += sizeof (UINT32)) {\r
+    LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);\r
+    //\r
+    // Check if size is not specified\r
+    //\r
+    if (LsnsNo == 0xFFFFFFFFUL) {\r
+      continue;\r
     }\r
+    //\r
+    // Accumulate free space size\r
+    //\r
+    *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);\r
+  }\r
 \r
-    FreePool ((VOID *)LogicalVolInt);\r
+  Length = LogicalVolInt->NumberOfPartitions * sizeof (UINT32) * 2;\r
+  for (; Index < Length; Index += sizeof (UINT32)) {\r
+    LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);\r
+    //\r
+    // Check if size is not specified\r
+    //\r
+    if (LsnsNo == 0xFFFFFFFFUL) {\r
+      continue;\r
+    }\r
+    //\r
+    // Accumulate used volume space\r
+    //\r
+    *VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  Status = EFI_SUCCESS;\r
+\r
+Out_Free:\r
+  //\r
+  // Free Logical Volume Integrity Descriptor\r
+  //\r
+  FreePool (LogicalVolInt);\r
+\r
+  return Status;\r
 }\r
 \r
 /**\r
index 49dc7077b7f4da034c1ee62c98493d75e4a1af3d..d4163b89ca3e1141f63dc01a1a5eec42bc22ff12 100644 (file)
@@ -276,13 +276,6 @@ UdfDriverBindingStop (
       NULL\r
       );\r
 \r
-    //\r
-    // Check if there's any open file. If so, clean them up.\r
-    //\r
-    if (PrivFsData->OpenFiles > 0) {\r
-      CleanupVolumeInformation (&PrivFsData->Volume);\r
-    }\r
-\r
     FreePool ((VOID *)PrivFsData);\r
   }\r
 \r
index 44c843fd4d33c7ab9cc24ef401c7daff44ffccaa..d441539d162de92e5a56b21d0519b870e639ca1b 100644 (file)
     { 0x89, 0x56, 0x73, 0xCD, 0xA3, 0x26, 0xCD, 0x0A }  \\r
   }\r
 \r
-#define UDF_DEFAULT_LV_NUM 0\r
-\r
-#define IS_PVD(_Pointer) \\r
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 1))\r
-#define IS_PD(_Pointer) \\r
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 5))\r
-#define IS_LVD(_Pointer) \\r
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 6))\r
-#define IS_TD(_Pointer) \\r
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 8))\r
-#define IS_FSD(_Pointer) \\r
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 256))\r
-#define IS_FE(_Pointer) \\r
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 261))\r
-#define IS_EFE(_Pointer) \\r
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 266))\r
-#define IS_FID(_Pointer) \\r
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 257))\r
-#define IS_AED(_Pointer) \\r
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 258))\r
-#define IS_LVID(_Pointer) \\r
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 9))\r
-\r
-#define _GET_FILETYPE(_Pointer) \\r
-  (IS_FE (_Pointer) ? \\r
-   (((UDF_FILE_ENTRY *)(_Pointer))->IcbTag.FileType) \\r
-   : \\r
-   (((UDF_EXTENDED_FILE_ENTRY *)(_Pointer))->IcbTag.FileType))\r
-\r
-#define IS_FE_DIRECTORY(_Pointer) \\r
-  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 4))\r
-#define IS_FE_STANDARD_FILE(_Pointer) \\r
-  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 5))\r
-#define IS_FE_SYMLINK(_Pointer) \\r
-  ((BOOLEAN)(_GET_FILETYPE (_Pointer) == 12))\r
+#define FE_ICB_FILE_TYPE(_Ptr)                                      \\r
+  (UDF_FILE_ENTRY_TYPE)(                                            \\r
+    ((UDF_DESCRIPTOR_TAG *)(_Ptr))->TagIdentifier == UdfFileEntry ? \\r
+    ((UDF_FILE_ENTRY *)(_Ptr))->IcbTag.FileType :                   \\r
+    ((UDF_EXTENDED_FILE_ENTRY *)(_Ptr))->IcbTag.FileType)\r
+\r
+typedef enum {\r
+  UdfFileEntryDirectory = 4,\r
+  UdfFileEntryStandardFile = 5,\r
+  UdfFileEntrySymlink = 12,\r
+} UDF_FILE_ENTRY_TYPE;\r
 \r
 #define HIDDEN_FILE     (1 << 0)\r
 #define DIRECTORY_FILE  (1 << 1)\r
 #define DELETED_FILE    (1 << 2)\r
 #define PARENT_FILE     (1 << 3)\r
 \r
-#define _GET_FILE_CHARS(_Pointer) \\r
-  (((UDF_FILE_IDENTIFIER_DESCRIPTOR *)(_Pointer))->FileCharacteristics)\r
-\r
-#define IS_FID_HIDDEN_FILE(_Pointer) \\r
-  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & HIDDEN_FILE))\r
-#define IS_FID_DIRECTORY_FILE(_Pointer) \\r
-  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & DIRECTORY_FILE))\r
-#define IS_FID_DELETED_FILE(_Pointer) \\r
-  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & DELETED_FILE))\r
-#define IS_FID_PARENT_FILE(_Pointer) \\r
-  ((BOOLEAN)(_GET_FILE_CHARS (_Pointer) & PARENT_FILE))\r
-#define IS_FID_NORMAL_FILE(_Pointer) \\r
-  ((BOOLEAN)(!IS_FID_DIRECTORY_FILE (_Pointer) && \\r
-         !IS_FID_PARENT_FILE (_Pointer)))\r
+#define IS_FID_HIDDEN_FILE(_Fid) \\r
+  (BOOLEAN)((_Fid)->FileCharacteristics & HIDDEN_FILE)\r
+#define IS_FID_DIRECTORY_FILE(_Fid) \\r
+  (BOOLEAN)((_Fid)->FileCharacteristics & DIRECTORY_FILE)\r
+#define IS_FID_DELETED_FILE(_Fid) \\r
+  (BOOLEAN)((_Fid)->FileCharacteristics & DELETED_FILE)\r
+#define IS_FID_PARENT_FILE(_Fid) \\r
+  (BOOLEAN)((_Fid)->FileCharacteristics & PARENT_FILE)\r
+#define IS_FID_NORMAL_FILE(_Fid) \\r
+  (BOOLEAN)(!IS_FID_DIRECTORY_FILE (_Fid) && \\r
+            !IS_FID_PARENT_FILE (_Fid))\r
 \r
 typedef enum {\r
   ShortAdsSequence,\r
@@ -152,14 +125,8 @@ typedef enum {
 #define IS_VALID_COMPRESSION_ID(_CompId) \\r
   ((BOOLEAN)((_CompId) == 8 || (_CompId) == 16))\r
 \r
-#define LV_BLOCK_SIZE(_Vol, _LvNum) \\r
-  (_Vol)->LogicalVolDescs[(_LvNum)]->LogicalBlockSize\r
-\r
 #define UDF_STANDARD_IDENTIFIER_LENGTH   5\r
 \r
-#define LV_UDF_REVISION(_Lv) \\r
-  *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix\r
-\r
 #pragma pack(1)\r
 \r
 typedef struct {\r
@@ -185,17 +152,6 @@ typedef struct {
 \r
 #pragma pack(1)\r
 \r
-typedef struct {\r
-  UINT8           CharacterSetType;\r
-  UINT8           CharacterSetInfo[63];\r
-} UDF_CHAR_SPEC;\r
-\r
-typedef struct {\r
-  UINT8           Flags;\r
-  UINT8           Identifier[23];\r
-  UINT8           IdentifierSuffix[8];\r
-} UDF_ENTITY_ID;\r
-\r
 typedef struct {\r
   UINT16          TypeAndTimezone;\r
   INT16           Year;\r
@@ -209,17 +165,6 @@ typedef struct {
   UINT8           Microseconds;\r
 } UDF_TIMESTAMP;\r
 \r
-typedef struct {\r
-  UINT32        LogicalBlockNumber;\r
-  UINT16        PartitionReferenceNumber;\r
-} UDF_LB_ADDR;\r
-\r
-typedef struct {\r
-  UINT32                           ExtentLength;\r
-  UDF_LB_ADDR                      ExtentLocation;\r
-  UINT8                            ImplementationUse[6];\r
-} UDF_LONG_ALLOCATION_DESCRIPTOR;\r
-\r
 typedef struct {\r
   UDF_DESCRIPTOR_TAG                 DescriptorTag;\r
   UINT32                             PrevAllocationExtentDescriptor;\r
@@ -234,6 +179,17 @@ typedef struct {
   UINT8                   StructureData[2040];\r
 } UDF_VOLUME_DESCRIPTOR;\r
 \r
+typedef struct {\r
+  UDF_DESCRIPTOR_TAG             DescriptorTag;\r
+  UDF_TIMESTAMP                  RecordingDateTime;\r
+  UINT32                         IntegrityType;\r
+  UDF_EXTENT_AD                  NextIntegrityExtent;\r
+  UINT8                          LogicalVolumeContentsUse[32];\r
+  UINT32                         NumberOfPartitions;\r
+  UINT32                         LengthOfImplementationUse;\r
+  UINT8                          Data[0];\r
+} UDF_LOGICAL_VOLUME_INTEGRITY;\r
+\r
 typedef struct {\r
   UDF_DESCRIPTOR_TAG         DescriptorTag;\r
   UINT32                     VolumeDescriptorSequenceNumber;\r
@@ -249,33 +205,6 @@ typedef struct {
   UINT8                      Reserved[156];\r
 } UDF_PARTITION_DESCRIPTOR;\r
 \r
-typedef struct {\r
-  UDF_DESCRIPTOR_TAG              DescriptorTag;\r
-  UINT32                          VolumeDescriptorSequenceNumber;\r
-  UDF_CHAR_SPEC                   DescriptorCharacterSet;\r
-  UINT8                           LogicalVolumeIdentifier[128];\r
-  UINT32                          LogicalBlockSize;\r
-  UDF_ENTITY_ID                   DomainIdentifier;\r
-  UDF_LONG_ALLOCATION_DESCRIPTOR  LogicalVolumeContentsUse;\r
-  UINT32                          MapTableLength;\r
-  UINT32                          NumberOfPartitionMaps;\r
-  UDF_ENTITY_ID                   ImplementationIdentifier;\r
-  UINT8                           ImplementationUse[128];\r
-  UDF_EXTENT_AD                   IntegritySequenceExtent;\r
-  UINT8                           PartitionMaps[6];\r
-} UDF_LOGICAL_VOLUME_DESCRIPTOR;\r
-\r
-typedef struct {\r
-  UDF_DESCRIPTOR_TAG             DescriptorTag;\r
-  UDF_TIMESTAMP                  RecordingDateTime;\r
-  UINT32                         IntegrityType;\r
-  UDF_EXTENT_AD                  NextIntegrityExtent;\r
-  UINT8                          LogicalVolumeContentsUse[32];\r
-  UINT32                         NumberOfPartitions;\r
-  UINT32                         LengthOfImplementationUse;\r
-  UINT8                          Data[0];\r
-} UDF_LOGICAL_VOLUME_INTEGRITY;\r
-\r
 typedef struct {\r
   UDF_DESCRIPTOR_TAG              DescriptorTag;\r
   UDF_TIMESTAMP                   RecordingDateAndTime;\r
@@ -389,12 +318,10 @@ typedef struct {
 // UDF filesystem driver's private data\r
 //\r
 typedef struct {\r
-  UDF_LOGICAL_VOLUME_DESCRIPTOR  **LogicalVolDescs;\r
-  UINTN                          LogicalVolDescsNo;\r
-  UDF_PARTITION_DESCRIPTOR       **PartitionDescs;\r
-  UINTN                          PartitionDescsNo;\r
-  UDF_FILE_SET_DESCRIPTOR        **FileSetDescs;\r
-  UINTN                          FileSetDescsNo;\r
+  UINT64                         MainVdsStartLocation;\r
+  UDF_LOGICAL_VOLUME_DESCRIPTOR  LogicalVolDesc;\r
+  UDF_PARTITION_DESCRIPTOR       PartitionDesc;\r
+  UDF_FILE_SET_DESCRIPTOR        FileSetDesc;\r
   UINTN                          FileEntrySize;\r
 } UDF_VOLUME_INFO;\r
 \r
@@ -883,17 +810,6 @@ ResolveSymlink (
   OUT  UDF_FILE_INFO          *File\r
   );\r
 \r
-/**\r
-  Clean up in-memory UDF volume information.\r
-\r
-  @param[in] Volume Volume information pointer.\r
-\r
-**/\r
-VOID\r
-CleanupVolumeInformation (\r
-  IN UDF_VOLUME_INFO *Volume\r
-  );\r
-\r
 /**\r
   Clean up in-memory UDF file information.\r
 \r