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.d...@intel.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Reported-by: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
Tested-by: Hao Wu <hao.a...@intel.com>
Build-tested-by: Laszlo Ersek <ler...@redhat.com>
Reviewed-by: Star Zeng <star.z...@intel.com>
Build-tested-by: Star Zeng <star.z...@intel.com>
Build-tested-by: Paulo Alcantara <pa...@hp.com>
---
 MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c            | 366 ++++++++++--
 MdeModulePkg/Universal/Disk/UdfDxe/File.c                 |  16 +-
 MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627 
++++++++------------
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.c                  |   7 -
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.h                  | 158 ++---
 5 files changed, 606 insertions(+), 568 deletions(-)

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

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to