]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
MdeModulePkg/UdfDxe: Refine boundary checks for file/path name string
[mirror_edk2.git] / MdeModulePkg / Universal / Disk / UdfDxe / FileSystemOperations.c
index 842c7f8f090adbbd6f7b2d56c12adcf3b011aee7..b3ac673cac4952518d65cbe6635566abc2a605f4 100644 (file)
@@ -2,6 +2,7 @@
   Handle on-disk format and volume structures in UDF/ECMA-167 file systems.\r
 \r
   Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>\r
   Handle on-disk format and volume structures in UDF/ECMA-167 file systems.\r
 \r
   Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>\r
+  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials are licensed and made available\r
   under the terms and conditions of the BSD License which accompanies this\r
 \r
   This program and the accompanying materials are licensed and made available\r
   under the terms and conditions of the BSD License which accompanies this\r
 \r
 #include "Udf.h"\r
 \r
 \r
 #include "Udf.h"\r
 \r
+//\r
+// Vendor-Defined Device Path GUID for UDF file system\r
+//\r
+EFI_GUID gUdfDevPathGuid = EFI_UDF_DEVICE_PATH_GUID;\r
+\r
+/**\r
+  Find the anchor volume descriptor pointer.\r
+\r
+  @param[in]  BlockIo             BlockIo interface.\r
+  @param[in]  DiskIo              DiskIo interface.\r
+  @param[out] AnchorPoint         Anchor volume descriptor pointer.\r
+\r
+  @retval EFI_SUCCESS             Anchor volume descriptor pointer found.\r
+  @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.\r
+  @retval other                   Anchor volume descriptor pointer not found.\r
+\r
+**/\r
 EFI_STATUS\r
 FindAnchorVolumeDescriptorPointer (\r
   IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,\r
 EFI_STATUS\r
 FindAnchorVolumeDescriptorPointer (\r
   IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,\r
@@ -21,11 +39,12 @@ FindAnchorVolumeDescriptorPointer (
   OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint\r
   )\r
 {\r
   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
 \r
   BlockSize = BlockIo->Media->BlockSize;\r
   EndLBA = BlockIo->Media->LastBlock;\r
@@ -45,10 +64,13 @@ FindAnchorVolumeDescriptorPointer (
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
     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
     //\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
       return EFI_SUCCESS;\r
     }\r
   }\r
@@ -58,6 +80,22 @@ FindAnchorVolumeDescriptorPointer (
   return EFI_VOLUME_CORRUPTED;\r
 }\r
 \r
   return EFI_VOLUME_CORRUPTED;\r
 }\r
 \r
+/**\r
+  Save the content of Logical Volume Descriptors and Partitions Descriptors in\r
+  memory.\r
+\r
+  @param[in]  BlockIo             BlockIo interface.\r
+  @param[in]  DiskIo              DiskIo interface.\r
+  @param[in]  AnchorPoint         Anchor volume descriptor pointer.\r
+  @param[out] Volume              UDF volume information structure.\r
+\r
+  @retval EFI_SUCCESS             The descriptors were saved.\r
+  @retval EFI_OUT_OF_RESOURCES    The descriptors were not saved due to lack of\r
+                                  resources.\r
+  @retval other                   The descriptors were not saved due to\r
+                                  ReadDisk error.\r
+\r
+**/\r
 EFI_STATUS\r
 StartMainVolumeDescriptorSequence (\r
   IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,\r
 EFI_STATUS\r
 StartMainVolumeDescriptorSequence (\r
   IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,\r
@@ -66,156 +104,112 @@ StartMainVolumeDescriptorSequence (
   OUT  UDF_VOLUME_INFO                       *Volume\r
   )\r
 {\r
   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
 \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
   //\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
   if (Buffer == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Error_Alloc_Buf;\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \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
       BlockIo->Media->MediaId,\r
-      MultU64x32 (StartingLsn, BlockSize),\r
+      SeqStartBlock,\r
       BlockSize,\r
       Buffer\r
       );\r
     if (EFI_ERROR (Status)) {\r
       BlockSize,\r
       Buffer\r
       );\r
     if (EFI_ERROR (Status)) {\r
-      goto Error_Read_Disk_Blk;\r
+      goto Out_Free;\r
     }\r
 \r
     }\r
 \r
-    if (IS_TD (Buffer)) {\r
+    DescriptorTag = Buffer;\r
+\r
+    switch (DescriptorTag->TagIdentifier) {\r
+    case UdfPartitionDescriptor:\r
       //\r
       //\r
-      // Found a Terminating Descriptor. Stop the sequence then.\r
+      // Save Partition Descriptor\r
       //\r
       //\r
+      CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume->PartitionDesc));\r
       break;\r
       break;\r
-    }\r
 \r
 \r
-    if (IS_LVD (Buffer)) {\r
+    case UdfLogicalVolumeDescriptor:\r
       //\r
       //\r
-      // Found a Logical Volume Descriptor.\r
+      // Save Logical Volume Descriptor\r
       //\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
 \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
 \r
-      CopyMem ((VOID *)PartitionDesc, Buffer,\r
-               sizeof (UDF_PARTITION_DESCRIPTOR));\r
-      Volume->PartitionDescs[Volume->PartitionDescsNo++] = PartitionDesc;\r
+    default:\r
+      ;\r
     }\r
     }\r
-\r
-    StartingLsn++;\r
   }\r
 \r
   //\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
   //\r
-  LogicalBlockSize = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);\r
+  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;\r
   if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {\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
   } else {\r
     Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;\r
   }\r
 \r
-  FreePool (Buffer);\r
-\r
-  return EFI_SUCCESS;\r
+  Status = EFI_SUCCESS;\r
 \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
   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
   return Status;\r
 }\r
 \r
-//\r
-// Return a Partition Descriptor given a Long Allocation Descriptor. This is\r
-// necessary to calculate the right extent (LongAd) offset which is added up\r
-// with partition's starting location.\r
-//\r
+/**\r
+  Return a Partition Descriptor given a Long Allocation Descriptor. This is\r
+  necessary to calculate the right extent (LongAd) offset which is added up\r
+  with partition's starting location.\r
+\r
+  @param[in]  Volume              Volume information pointer.\r
+  @param[in]  LongAd              Long Allocation Descriptor pointer.\r
+\r
+  @return A pointer to a Partition Descriptor.\r
+\r
+**/\r
 UDF_PARTITION_DESCRIPTOR *\r
 GetPdFromLongAd (\r
   IN UDF_VOLUME_INFO                 *Volume,\r
 UDF_PARTITION_DESCRIPTOR *\r
 GetPdFromLongAd (\r
   IN UDF_VOLUME_INFO                 *Volume,\r
@@ -223,198 +217,192 @@ GetPdFromLongAd (
   )\r
 {\r
   UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;\r
   )\r
 {\r
   UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;\r
-  UINTN                          Index;\r
-  UDF_PARTITION_DESCRIPTOR       *PartitionDesc;\r
   UINT16                         PartitionNum;\r
 \r
   UINT16                         PartitionNum;\r
 \r
-  LogicalVolDesc = Volume->LogicalVolDescs[UDF_DEFAULT_LV_NUM];\r
+  LogicalVolDesc = &Volume->LogicalVolDesc;\r
 \r
 \r
-  switch (LV_UDF_REVISION (LogicalVolDesc)) {\r
+  switch (LogicalVolDesc->DomainIdentifier.Suffix.Domain.UdfRevision) {\r
   case 0x0102:\r
   case 0x0102:\r
+  case 0x0150:\r
+  case 0x0200:\r
+  case 0x0201:\r
+  case 0x0250:\r
+  case 0x0260:\r
     //\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
     //\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
     //\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
     //\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
     PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);\r
     break;\r
-  case 0x0260:\r
+\r
+  default:\r
     //\r
     //\r
-    // Fall through.\r
+    // Unsupported UDF revision\r
     //\r
     //\r
-  default:\r
-    PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;\r
-    break;\r
+    return NULL;\r
   }\r
 \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
 }\r
 \r
   }\r
 \r
   return NULL;\r
 }\r
 \r
-//\r
-// Return logical sector number of a given Long Allocation Descriptor.\r
-//\r
-UINT64\r
+/**\r
+  Return logical sector number of a given Long Allocation Descriptor.\r
+\r
+  @param[in]   Volume             Volume information pointer.\r
+  @param[in]   LongAd             Long Allocation Descriptor pointer.\r
+  @param[out]  Lsn                Logical sector number pointer.\r
+\r
+  @retval EFI_SUCCESS             Logical sector number successfully returned.\r
+  @retval EFI_UNSUPPORTED         Logical sector number is not returned due to\r
+                                  unrecognized format.\r
+\r
+**/\r
+EFI_STATUS\r
 GetLongAdLsn (\r
 GetLongAdLsn (\r
-  IN UDF_VOLUME_INFO                 *Volume,\r
-  IN UDF_LONG_ALLOCATION_DESCRIPTOR  *LongAd\r
+  IN  UDF_VOLUME_INFO                 *Volume,\r
+  IN  UDF_LONG_ALLOCATION_DESCRIPTOR  *LongAd,\r
+  OUT UINT64                          *Lsn\r
   )\r
 {\r
   UDF_PARTITION_DESCRIPTOR *PartitionDesc;\r
 \r
   PartitionDesc = GetPdFromLongAd (Volume, LongAd);\r
   )\r
 {\r
   UDF_PARTITION_DESCRIPTOR *PartitionDesc;\r
 \r
   PartitionDesc = GetPdFromLongAd (Volume, LongAd);\r
-  ASSERT (PartitionDesc != NULL);\r
+  if (PartitionDesc == NULL) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "%a: Fail to get the Partition Descriptor from the given Long Allocation Descriptor.\n",\r
+      __FUNCTION__\r
+      ));\r
+    return EFI_UNSUPPORTED;\r
+  }\r
 \r
 \r
-  return (UINT64)PartitionDesc->PartitionStartingLocation +\r
-                 LongAd->ExtentLocation.LogicalBlockNumber;\r
+  *Lsn = (UINT64)PartitionDesc->PartitionStartingLocation -\r
+         Volume->MainVdsStartLocation +\r
+         LongAd->ExtentLocation.LogicalBlockNumber;\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 }\r
 \r
-//\r
-// Return logical sector number of a given Short Allocation Descriptor.\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
+  @return The logical sector number of a given Short Allocation Descriptor.\r
+\r
+**/\r
 UINT64\r
 GetShortAdLsn (\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
   IN UDF_PARTITION_DESCRIPTOR         *PartitionDesc,\r
   IN UDF_SHORT_ALLOCATION_DESCRIPTOR  *ShortAd\r
   )\r
 {\r
-  return (UINT64)PartitionDesc->PartitionStartingLocation +\r
-    ShortAd->ExtentPosition;\r
+  return (UINT64)PartitionDesc->PartitionStartingLocation -\r
+    Volume->MainVdsStartLocation + ShortAd->ExtentPosition;\r
 }\r
 \r
 }\r
 \r
-//\r
-// Find File Set Descriptor of a given Logical Volume Descriptor.\r
-//\r
-// The found FSD will contain the extent (LogicalVolumeContentsUse) where our\r
-// root directory is.\r
-//\r
+/**\r
+  Find File Set Descriptor of a given Logical Volume Descriptor.\r
+\r
+  The found FSD will contain the extent (LogicalVolumeContentsUse) where our\r
+  root directory is.\r
+\r
+  @param[in]  BlockIo             BlockIo interface.\r
+  @param[in]  DiskIo              DiskIo interface.\r
+  @param[in]  Volume              Volume information pointer.\r
+\r
+  @retval EFI_SUCCESS             File Set Descriptor pointer found.\r
+  @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.\r
+  @retval other                   File Set Descriptor pointer not found.\r
+\r
+**/\r
 EFI_STATUS\r
 FindFileSetDescriptor (\r
   IN   EFI_BLOCK_IO_PROTOCOL    *BlockIo,\r
   IN   EFI_DISK_IO_PROTOCOL     *DiskIo,\r
 EFI_STATUS\r
 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
   )\r
 {\r
   EFI_STATUS                     Status;\r
   UINT64                         Lsn;\r
   UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;\r
+  UDF_DESCRIPTOR_TAG             *DescriptorTag;\r
 \r
 \r
-  LogicalVolDesc = Volume->LogicalVolDescs[LogicalVolDescNum];\r
-  Lsn = GetLongAdLsn (Volume, &LogicalVolDesc->LogicalVolumeContentsUse);\r
+  LogicalVolDesc = &Volume->LogicalVolDesc;\r
+  Status = GetLongAdLsn (Volume, &LogicalVolDesc->LogicalVolumeContentsUse, &Lsn);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   //\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
   //\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
     );\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
+  DescriptorTag = &Volume->FileSetDesc.DescriptorTag;\r
+\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
   //\r
-  if (!IS_FSD (FileSetDesc)) {\r
+  if (DescriptorTag->TagIdentifier != UdfFileSetDescriptor) {\r
     return EFI_VOLUME_CORRUPTED;\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \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
-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
+  Read Volume and File Structure on an UDF file system.\r
 \r
 \r
-  FreePool ((VOID *)Volume->FileSetDescs);\r
-  Volume->FileSetDescs = NULL;\r
+  @param[in]   BlockIo            BlockIo interface.\r
+  @param[in]   DiskIo             DiskIo interface.\r
+  @param[out]  Volume             Volume information pointer.\r
 \r
 \r
-Error_Alloc_Fsd:\r
-  return Status;\r
-}\r
+  @retval EFI_SUCCESS             Volume and File Structure were read.\r
+  @retval other                   Volume and File Structure were not read.\r
 \r
 \r
-//\r
-// Read Volume and File Structure on an UDF file system.\r
-//\r
+**/\r
 EFI_STATUS\r
 ReadVolumeFileStructure (\r
   IN   EFI_BLOCK_IO_PROTOCOL  *BlockIo,\r
 EFI_STATUS\r
 ReadVolumeFileStructure (\r
   IN   EFI_BLOCK_IO_PROTOCOL  *BlockIo,\r
@@ -424,9 +412,10 @@ ReadVolumeFileStructure (
 {\r
   EFI_STATUS                            Status;\r
   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;\r
 {\r
   EFI_STATUS                            Status;\r
   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;\r
+  UDF_EXTENT_AD                         *ExtentAd;\r
 \r
   //\r
 \r
   //\r
-  // Find an AVDP.\r
+  // Find Anchor Volume Descriptor Pointer\r
   //\r
   Status = FindAnchorVolumeDescriptorPointer (\r
     BlockIo,\r
   //\r
   Status = FindAnchorVolumeDescriptorPointer (\r
     BlockIo,\r
@@ -438,7 +427,14 @@ ReadVolumeFileStructure (
   }\r
 \r
   //\r
   }\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
   //\r
   Status = StartMainVolumeDescriptorSequence (\r
     BlockIo,\r
@@ -453,9 +449,14 @@ ReadVolumeFileStructure (
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r
-//\r
-// Calculate length of a given File Identifier Descriptor.\r
-//\r
+/**\r
+  Calculate length of a given File Identifier Descriptor.\r
+\r
+  @param[in]  FileIdentifierDesc  File Identifier Descriptor pointer.\r
+\r
+  @return The length of a given File Identifier Descriptor.\r
+\r
+**/\r
 UINT64\r
 GetFidDescriptorLength (\r
   IN UDF_FILE_IDENTIFIER_DESCRIPTOR  *FileIdentifierDesc\r
 UINT64\r
 GetFidDescriptorLength (\r
   IN UDF_FILE_IDENTIFIER_DESCRIPTOR  *FileIdentifierDesc\r
@@ -468,9 +469,13 @@ GetFidDescriptorLength (
              );\r
 }\r
 \r
              );\r
 }\r
 \r
-//\r
-// Duplicate a given File Identifier Descriptor.\r
-//\r
+/**\r
+  Duplicate a given File Identifier Descriptor.\r
+\r
+  @param[in]  FileIdentifierDesc     File Identifier Descriptor pointer.\r
+  @param[out] NewFileIdentifierDesc  The duplicated File Identifier Descriptor.\r
+\r
+**/\r
 VOID\r
 DuplicateFid (\r
   IN   UDF_FILE_IDENTIFIER_DESCRIPTOR  *FileIdentifierDesc,\r
 VOID\r
 DuplicateFid (\r
   IN   UDF_FILE_IDENTIFIER_DESCRIPTOR  *FileIdentifierDesc,\r
@@ -482,9 +487,15 @@ DuplicateFid (
       (UINTN) GetFidDescriptorLength (FileIdentifierDesc), FileIdentifierDesc);\r
 }\r
 \r
       (UINTN) GetFidDescriptorLength (FileIdentifierDesc), FileIdentifierDesc);\r
 }\r
 \r
-//\r
-// Duplicate either a given File Entry or a given Extended File Entry.\r
-//\r
+/**\r
+  Duplicate either a given File Entry or a given Extended File Entry.\r
+\r
+  @param[in]  BlockIo             BlockIo interface.\r
+  @param[in]  Volume              Volume information pointer.\r
+  @param[in]  FileEntry           (Extended) File Entry pointer.\r
+  @param[out] NewFileEntry        The duplicated (Extended) File Entry.\r
+\r
+**/\r
 VOID\r
 DuplicateFe (\r
   IN   EFI_BLOCK_IO_PROTOCOL  *BlockIo,\r
 VOID\r
 DuplicateFe (\r
   IN   EFI_BLOCK_IO_PROTOCOL  *BlockIo,\r
@@ -496,15 +507,21 @@ DuplicateFe (
   *NewFileEntry = AllocateCopyPool (Volume->FileEntrySize, FileEntry);\r
 }\r
 \r
   *NewFileEntry = AllocateCopyPool (Volume->FileEntrySize, FileEntry);\r
 }\r
 \r
-//\r
-// Get raw data + length of a given File Entry or Extended File Entry.\r
-//\r
-// The file's recorded data can contain either real file content (inline) or\r
-// a sequence of extents (or Allocation Descriptors) which tells where file's\r
-// content is stored in.\r
-//\r
-// NOTE: The FE/EFE can be thought it was an inode.\r
-//\r
+/**\r
+  Get raw data + length of a given File Entry or Extended File Entry.\r
+\r
+  The file's recorded data can contain either real file content (inline) or\r
+  a sequence of extents (or Allocation Descriptors) which tells where file's\r
+  content is stored in.\r
+\r
+  NOTE: The FE/EFE can be thought it was an inode.\r
+\r
+  @param[in]  FileEntryData       (Extended) File Entry pointer.\r
+  @param[out] Data                Buffer contains the raw data of a given\r
+                                  (Extended) File Entry.\r
+  @param[out] Length              Length of the data in Buffer.\r
+\r
+**/\r
 VOID\r
 GetFileEntryData (\r
   IN   VOID    *FileEntryData,\r
 VOID\r
 GetFileEntryData (\r
   IN   VOID    *FileEntryData,\r
@@ -512,16 +529,19 @@ GetFileEntryData (
   OUT  UINT64  *Length\r
   )\r
 {\r
   OUT  UINT64  *Length\r
   )\r
 {\r
+  UDF_DESCRIPTOR_TAG       *DescriptorTag;\r
   UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;\r
   UDF_FILE_ENTRY           *FileEntry;\r
 \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
     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
     FileEntry = (UDF_FILE_ENTRY *)FileEntryData;\r
 \r
     *Length  = FileEntry->InformationLength;\r
@@ -530,9 +550,15 @@ GetFileEntryData (
   }\r
 }\r
 \r
   }\r
 }\r
 \r
-//\r
-// Get Allocation Descriptors' data information from a given FE/EFE.\r
-//\r
+/**\r
+  Get Allocation Descriptors' data information from a given FE/EFE.\r
+\r
+  @param[in]  FileEntryData       (Extended) File Entry pointer.\r
+  @param[out] AdsData             Buffer contains the Allocation Descriptors'\r
+                                  data from a given FE/EFE.\r
+  @param[out] Length              Length of the data in AdsData.\r
+\r
+**/\r
 VOID\r
 GetAdsInformation (\r
   IN   VOID    *FileEntryData,\r
 VOID\r
 GetAdsInformation (\r
   IN   VOID    *FileEntryData,\r
@@ -540,16 +566,19 @@ GetAdsInformation (
   OUT  UINT64  *Length\r
   )\r
 {\r
   OUT  UINT64  *Length\r
   )\r
 {\r
+  UDF_DESCRIPTOR_TAG       *DescriptorTag;\r
   UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;\r
   UDF_FILE_ENTRY           *FileEntry;\r
 \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
     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
     FileEntry = (UDF_FILE_ENTRY *)FileEntryData;\r
 \r
     *Length = FileEntry->LengthOfAllocationDescriptors;\r
@@ -558,9 +587,18 @@ GetAdsInformation (
   }\r
 }\r
 \r
   }\r
 }\r
 \r
-//\r
-// Read next Long Allocation Descriptor from a given file's data.\r
-//\r
+/**\r
+  Read next Long Allocation Descriptor from a given file's data.\r
+\r
+  @param[in]     Data             File's data pointer.\r
+  @param[in,out] Offset           Starting offset of the File's data to read.\r
+  @param[in]     Length           Length of the data to read.\r
+  @param[out]    FoundLongAd      Long Allocation Descriptor pointer.\r
+\r
+  @retval EFI_SUCCESS             A Long Allocation Descriptor was found.\r
+  @retval EFI_DEVICE_ERROR        No more Long Allocation Descriptors.\r
+\r
+**/\r
 EFI_STATUS\r
 GetLongAdFromAds (\r
   IN      VOID                            *Data,\r
 EFI_STATUS\r
 GetLongAdFromAds (\r
   IN      VOID                            *Data,\r
@@ -587,9 +625,9 @@ GetLongAdFromAds (
     // If it's either an indirect AD (Extended Alllocation Descriptor) or an\r
     // allocated AD, then return it.\r
     //\r
     // If it's either an indirect AD (Extended Alllocation Descriptor) or an\r
     // allocated AD, then return it.\r
     //\r
-    ExtentFlags = GET_EXTENT_FLAGS (LONG_ADS_SEQUENCE, LongAd);\r
-    if (ExtentFlags == EXTENT_IS_NEXT_EXTENT ||\r
-        ExtentFlags == EXTENT_RECORDED_AND_ALLOCATED) {\r
+    ExtentFlags = GET_EXTENT_FLAGS (LongAdsSequence, LongAd);\r
+    if (ExtentFlags == ExtentIsNextExtent ||\r
+        ExtentFlags == ExtentRecordedAndAllocated) {\r
       break;\r
     }\r
 \r
       break;\r
     }\r
 \r
@@ -597,7 +635,7 @@ GetLongAdFromAds (
     // This AD is either not recorded but allocated, or not recorded and not\r
     // allocated. Skip it.\r
     //\r
     // This AD is either not recorded but allocated, or not recorded and not\r
     // allocated. Skip it.\r
     //\r
-    *Offset += AD_LENGTH (LONG_ADS_SEQUENCE);\r
+    *Offset += AD_LENGTH (LongAdsSequence);\r
   }\r
 \r
   *FoundLongAd = LongAd;\r
   }\r
 \r
   *FoundLongAd = LongAd;\r
@@ -605,9 +643,18 @@ GetLongAdFromAds (
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-//\r
-// Read next Short Allocation Descriptor from a given file's data.\r
-//\r
+/**\r
+  Read next Short Allocation Descriptor from a given file's data.\r
+\r
+  @param[in]     Data             File's data pointer.\r
+  @param[in,out] Offset           Starting offset of the File's data to read.\r
+  @param[in]     Length           Length of the data to read.\r
+  @param[out]    FoundShortAd     Short Allocation Descriptor pointer.\r
+\r
+  @retval EFI_SUCCESS             A Short Allocation Descriptor was found.\r
+  @retval EFI_DEVICE_ERROR        No more Short Allocation Descriptors.\r
+\r
+**/\r
 EFI_STATUS\r
 GetShortAdFromAds (\r
   IN      VOID                             *Data,\r
 EFI_STATUS\r
 GetShortAdFromAds (\r
   IN      VOID                             *Data,\r
@@ -634,9 +681,9 @@ GetShortAdFromAds (
     // If it's either an indirect AD (Extended Alllocation Descriptor) or an\r
     // allocated AD, then return it.\r
     //\r
     // If it's either an indirect AD (Extended Alllocation Descriptor) or an\r
     // allocated AD, then return it.\r
     //\r
-    ExtentFlags = GET_EXTENT_FLAGS (SHORT_ADS_SEQUENCE, ShortAd);\r
-    if (ExtentFlags == EXTENT_IS_NEXT_EXTENT ||\r
-        ExtentFlags == EXTENT_RECORDED_AND_ALLOCATED) {\r
+    ExtentFlags = GET_EXTENT_FLAGS (ShortAdsSequence, ShortAd);\r
+    if (ExtentFlags == ExtentIsNextExtent ||\r
+        ExtentFlags == ExtentRecordedAndAllocated) {\r
       break;\r
     }\r
 \r
       break;\r
     }\r
 \r
@@ -644,7 +691,7 @@ GetShortAdFromAds (
     // This AD is either not recorded but allocated, or not recorded and not\r
     // allocated. Skip it.\r
     //\r
     // This AD is either not recorded but allocated, or not recorded and not\r
     // allocated. Skip it.\r
     //\r
-    *Offset += AD_LENGTH (SHORT_ADS_SEQUENCE);\r
+    *Offset += AD_LENGTH (ShortAdsSequence);\r
   }\r
 \r
   *FoundShortAd = ShortAd;\r
   }\r
 \r
   *FoundShortAd = ShortAd;\r
@@ -652,10 +699,21 @@ GetShortAdFromAds (
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-//\r
-// Get either a Short Allocation Descriptor or a Long Allocation Descriptor from\r
-// file's data.\r
-//\r
+/**\r
+  Get either a Short Allocation Descriptor or a Long Allocation Descriptor from\r
+  file's data.\r
+\r
+  @param[in]     RecordingFlags   Flag to indicate the type of descriptor.\r
+  @param[in]     Data             File's data pointer.\r
+  @param[in,out] Offset           Starting offset of the File's data to read.\r
+  @param[in]     Length           Length of the data to read.\r
+  @param[out]    FoundAd          Allocation Descriptor pointer.\r
+\r
+  @retval EFI_SUCCESS             A Short Allocation Descriptor was found.\r
+  @retval EFI_DEVICE_ERROR        No more Allocation Descriptors.\r
+                                  Invalid type of descriptor was given.\r
+\r
+**/\r
 EFI_STATUS\r
 GetAllocationDescriptor (\r
   IN      UDF_FE_RECORDING_FLAGS  RecordingFlags,\r
 EFI_STATUS\r
 GetAllocationDescriptor (\r
   IN      UDF_FE_RECORDING_FLAGS  RecordingFlags,\r
@@ -665,14 +723,14 @@ GetAllocationDescriptor (
   OUT     VOID                    **FoundAd\r
   )\r
 {\r
   OUT     VOID                    **FoundAd\r
   )\r
 {\r
-  if (RecordingFlags == LONG_ADS_SEQUENCE) {\r
+  if (RecordingFlags == LongAdsSequence) {\r
     return GetLongAdFromAds (\r
       Data,\r
       Offset,\r
       Length,\r
       (UDF_LONG_ALLOCATION_DESCRIPTOR **)FoundAd\r
       );\r
     return GetLongAdFromAds (\r
       Data,\r
       Offset,\r
       Length,\r
       (UDF_LONG_ALLOCATION_DESCRIPTOR **)FoundAd\r
       );\r
-  } else if (RecordingFlags == SHORT_ADS_SEQUENCE) {\r
+  } else if (RecordingFlags == ShortAdsSequence) {\r
     return GetShortAdFromAds (\r
       Data,\r
       Offset,\r
     return GetShortAdFromAds (\r
       Data,\r
       Offset,\r
@@ -681,35 +739,84 @@ GetAllocationDescriptor (
       );\r
   }\r
 \r
       );\r
   }\r
 \r
+  //\r
+  // Code should never reach here.\r
+  //\r
+  ASSERT (FALSE);\r
   return EFI_DEVICE_ERROR;\r
 }\r
 \r
   return EFI_DEVICE_ERROR;\r
 }\r
 \r
-//\r
-// Return logical sector number of either Short or Long Allocation Descriptor.\r
-//\r
-UINT64\r
+/**\r
+  Return logical sector number of either Short or Long Allocation Descriptor.\r
+\r
+  @param[in]  RecordingFlags      Flag to indicate the type of descriptor.\r
+  @param[in]  Volume              Volume information pointer.\r
+  @param[in]  ParentIcb           Long Allocation Descriptor pointer.\r
+  @param[in]  Ad                  Allocation Descriptor pointer.\r
+  @param[out] Lsn                 Logical sector number pointer.\r
+\r
+  @retval EFI_SUCCESS             Logical sector number of the given Allocation\r
+                                  Descriptor successfully returned.\r
+  @retval EFI_UNSUPPORTED         Logical sector number of the given Allocation\r
+                                  Descriptor is not returned due to unrecognized\r
+                                  format.\r
+\r
+**/\r
+EFI_STATUS\r
 GetAllocationDescriptorLsn (\r
 GetAllocationDescriptorLsn (\r
-  IN UDF_FE_RECORDING_FLAGS          RecordingFlags,\r
-  IN UDF_VOLUME_INFO                 *Volume,\r
-  IN UDF_LONG_ALLOCATION_DESCRIPTOR  *ParentIcb,\r
-  IN VOID                            *Ad\r
+  IN  UDF_FE_RECORDING_FLAGS          RecordingFlags,\r
+  IN  UDF_VOLUME_INFO                 *Volume,\r
+  IN  UDF_LONG_ALLOCATION_DESCRIPTOR  *ParentIcb,\r
+  IN  VOID                            *Ad,\r
+  OUT UINT64                          *Lsn\r
   )\r
 {\r
   )\r
 {\r
-  if (RecordingFlags == LONG_ADS_SEQUENCE) {\r
-    return GetLongAdLsn (Volume, (UDF_LONG_ALLOCATION_DESCRIPTOR *)Ad);\r
-  } else if (RecordingFlags == SHORT_ADS_SEQUENCE) {\r
-    return GetShortAdLsn (\r
-      GetPdFromLongAd (Volume, ParentIcb),\r
-      (UDF_SHORT_ALLOCATION_DESCRIPTOR *)Ad\r
-      );\r
+  UDF_PARTITION_DESCRIPTOR *PartitionDesc;\r
+\r
+  if (RecordingFlags == LongAdsSequence) {\r
+    return GetLongAdLsn (Volume, (UDF_LONG_ALLOCATION_DESCRIPTOR *)Ad, Lsn);\r
+  } else if (RecordingFlags == ShortAdsSequence) {\r
+    PartitionDesc = GetPdFromLongAd (Volume, ParentIcb);\r
+    if (PartitionDesc == NULL) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+\r
+    *Lsn = GetShortAdLsn (\r
+             Volume,\r
+             PartitionDesc,\r
+             (UDF_SHORT_ALLOCATION_DESCRIPTOR *)Ad\r
+             );\r
+    return EFI_SUCCESS;\r
   }\r
 \r
   }\r
 \r
-  return 0;\r
+  //\r
+  // Code should never reach here.\r
+  //\r
+  ASSERT (FALSE);\r
+  return EFI_UNSUPPORTED;\r
 }\r
 \r
 }\r
 \r
-//\r
-// Return offset + length of a given indirect Allocation Descriptor (AED).\r
-//\r
+/**\r
+  Return offset + length of a given indirect Allocation Descriptor (AED).\r
+\r
+  @param[in]  BlockIo             BlockIo interface.\r
+  @param[in]  DiskIo              DiskIo interface.\r
+  @param[in]  Volume              Volume information pointer.\r
+  @param[in]  ParentIcb           Long Allocation Descriptor pointer.\r
+  @param[in]  RecordingFlags      Flag to indicate the type of descriptor.\r
+  @param[in]  Ad                  Allocation Descriptor pointer.\r
+  @param[out] Offset              Offset of a given indirect Allocation\r
+                                  Descriptor.\r
+  @param[out] Length              Length of a given indirect Allocation\r
+                                  Descriptor.\r
+\r
+  @retval EFI_SUCCESS             The offset and length were returned.\r
+  @retval EFI_OUT_OF_RESOURCES    The offset and length were not returned due\r
+                                  to lack of resources.\r
+  @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.\r
+  @retval other                   The offset and length were not returned.\r
+\r
+**/\r
 EFI_STATUS\r
 GetAedAdsOffset (\r
   IN   EFI_BLOCK_IO_PROTOCOL           *BlockIo,\r
 EFI_STATUS\r
 GetAedAdsOffset (\r
   IN   EFI_BLOCK_IO_PROTOCOL           *BlockIo,\r
@@ -728,19 +835,24 @@ GetAedAdsOffset (
   VOID                              *Data;\r
   UINT32                            LogicalBlockSize;\r
   UDF_ALLOCATION_EXTENT_DESCRIPTOR  *AllocExtDesc;\r
   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
 \r
   ExtentLength  = GET_EXTENT_LENGTH (RecordingFlags, Ad);\r
-  Lsn           = GetAllocationDescriptorLsn (RecordingFlags,\r
+  Status        = GetAllocationDescriptorLsn (RecordingFlags,\r
                                               Volume,\r
                                               ParentIcb,\r
                                               Volume,\r
                                               ParentIcb,\r
-                                              Ad);\r
+                                              Ad,\r
+                                              &Lsn);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   Data = AllocatePool (ExtentLength);\r
   if (Data == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
 \r
   Data = AllocatePool (ExtentLength);\r
   if (Data == NULL) {\r
     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
 \r
   //\r
   // Read extent.\r
@@ -756,11 +868,14 @@ GetAedAdsOffset (
     goto Exit;\r
   }\r
 \r
     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
   //\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
     Status = EFI_VOLUME_CORRUPTED;\r
     goto Exit;\r
   }\r
@@ -778,9 +893,25 @@ Exit:
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r
-//\r
-// Read Allocation Extent Descriptor into memory.\r
-//\r
+/**\r
+  Read Allocation Extent Descriptor into memory.\r
+\r
+  @param[in]  BlockIo             BlockIo interface.\r
+  @param[in]  DiskIo              DiskIo interface.\r
+  @param[in]  Volume              Volume information pointer.\r
+  @param[in]  ParentIcb           Long Allocation Descriptor pointer.\r
+  @param[in]  RecordingFlags      Flag to indicate the type of descriptor.\r
+  @param[in]  Ad                  Allocation Descriptor pointer.\r
+  @param[out] Data                Buffer that contains the Allocation Extent\r
+                                  Descriptor.\r
+  @param[out] Length              Length of Data.\r
+\r
+  @retval EFI_SUCCESS             The Allocation Extent Descriptor was read.\r
+  @retval EFI_OUT_OF_RESOURCES    The Allocation Extent Descriptor was not read\r
+                                  due to lack of resources.\r
+  @retval other                   Fail to read the disk.\r
+\r
+**/\r
 EFI_STATUS\r
 GetAedAdsData (\r
   IN   EFI_BLOCK_IO_PROTOCOL           *BlockIo,\r
 EFI_STATUS\r
 GetAedAdsData (\r
   IN   EFI_BLOCK_IO_PROTOCOL           *BlockIo,\r
@@ -830,9 +961,19 @@ GetAedAdsData (
     );\r
 }\r
 \r
     );\r
 }\r
 \r
-//\r
-// Function used to serialise reads of Allocation Descriptors.\r
-//\r
+/**\r
+  Function used to serialise reads of Allocation Descriptors.\r
+\r
+  @param[in]      RecordingFlags  Flag to indicate the type of descriptor.\r
+  @param[in]      Ad              Allocation Descriptor pointer.\r
+  @param[in, out] Buffer          Buffer to hold the next Allocation Descriptor.\r
+  @param[in]      Length          Length of Buffer.\r
+\r
+  @retval EFI_SUCCESS             Buffer was grown to hold the next Allocation\r
+                                  Descriptor.\r
+  @retval EFI_OUT_OF_RESOURCES    Buffer was not grown due to lack of resources.\r
+\r
+**/\r
 EFI_STATUS\r
 GrowUpBufferToNextAd (\r
   IN      UDF_FE_RECORDING_FLAGS  RecordingFlags,\r
 EFI_STATUS\r
 GrowUpBufferToNextAd (\r
   IN      UDF_FE_RECORDING_FLAGS  RecordingFlags,\r
@@ -860,9 +1001,26 @@ GrowUpBufferToNextAd (
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-//\r
-// Read data or size of either a File Entry or an Extended File Entry.\r
-//\r
+/**\r
+  Read data or size of either a File Entry or an Extended File Entry.\r
+\r
+  @param[in]      BlockIo         BlockIo interface.\r
+  @param[in]      DiskIo          DiskIo interface.\r
+  @param[in]      Volume          Volume information pointer.\r
+  @param[in]      ParentIcb       Long Allocation Descriptor pointer.\r
+  @param[in]      FileEntryData   FE/EFE structure pointer.\r
+  @param[in, out] ReadFileInfo    Read file information pointer.\r
+\r
+  @retval EFI_SUCCESS             Data or size of a FE/EFE was read.\r
+  @retval EFI_OUT_OF_RESOURCES    Data or size of a FE/EFE was not read due to\r
+                                  lack of resources.\r
+  @retval EFI_INVALID_PARAMETER   The read file flag given in ReadFileInfo is\r
+                                  invalid.\r
+  @retval EFI_UNSUPPORTED         The FE recording flag given in FileEntryData\r
+                                  is not supported.\r
+  @retval other                   Data or size of a FE/EFE was not read.\r
+\r
+**/\r
 EFI_STATUS\r
 ReadFile (\r
   IN      EFI_BLOCK_IO_PROTOCOL           *BlockIo,\r
 EFI_STATUS\r
 ReadFile (\r
   IN      EFI_BLOCK_IO_PROTOCOL           *BlockIo,\r
@@ -890,12 +1048,21 @@ ReadFile (
   UINT32                  ExtentLength;\r
   UDF_FE_RECORDING_FLAGS  RecordingFlags;\r
 \r
   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
   DoFreeAed         = FALSE;\r
 \r
+  //\r
+  // set BytesLeft to suppress incorrect compiler/analyzer warnings\r
+  //\r
+  BytesLeft = 0;\r
+  DataOffset = 0;\r
+  FilePosition = 0;\r
+  FinishedSeeking = FALSE;\r
+  Data = NULL;\r
+\r
   switch (ReadFileInfo->Flags) {\r
   switch (ReadFileInfo->Flags) {\r
-  case READ_FILE_GET_FILESIZE:\r
-  case READ_FILE_ALLOCATE_AND_READ:\r
+  case ReadFileGetFileSize:\r
+  case ReadFileAllocateAndRead:\r
     //\r
     // Initialise ReadFileInfo structure for either getting file size, or\r
     // reading file's recorded data.\r
     //\r
     // Initialise ReadFileInfo structure for either getting file size, or\r
     // reading file's recorded data.\r
@@ -903,7 +1070,7 @@ ReadFile (
     ReadFileInfo->ReadLength = 0;\r
     ReadFileInfo->FileData = NULL;\r
     break;\r
     ReadFileInfo->ReadLength = 0;\r
     ReadFileInfo->FileData = NULL;\r
     break;\r
-  case READ_FILE_SEEK_AND_READ:\r
+  case ReadFileSeekAndRead:\r
     //\r
     // About to seek a file and/or read its data.\r
     //\r
     //\r
     // About to seek a file and/or read its data.\r
     //\r
@@ -928,15 +1095,15 @@ ReadFile (
 \r
   RecordingFlags = GET_FE_RECORDING_FLAGS (FileEntryData);\r
   switch (RecordingFlags) {\r
 \r
   RecordingFlags = GET_FE_RECORDING_FLAGS (FileEntryData);\r
   switch (RecordingFlags) {\r
-  case INLINE_DATA:\r
+  case InlineData:\r
     //\r
     // There are no extents for this FE/EFE. All data is inline.\r
     //\r
     GetFileEntryData (FileEntryData, &Data, &Length);\r
 \r
     //\r
     // There are no extents for this FE/EFE. All data is inline.\r
     //\r
     GetFileEntryData (FileEntryData, &Data, &Length);\r
 \r
-    if (ReadFileInfo->Flags == READ_FILE_GET_FILESIZE) {\r
+    if (ReadFileInfo->Flags == ReadFileGetFileSize) {\r
       ReadFileInfo->ReadLength = Length;\r
       ReadFileInfo->ReadLength = Length;\r
-    } else if (ReadFileInfo->Flags == READ_FILE_ALLOCATE_AND_READ) {\r
+    } else if (ReadFileInfo->Flags == ReadFileAllocateAndRead) {\r
       //\r
       // Allocate buffer for starting read data.\r
       //\r
       //\r
       // Allocate buffer for starting read data.\r
       //\r
@@ -950,7 +1117,7 @@ ReadFile (
       //\r
       CopyMem (ReadFileInfo->FileData, Data, (UINTN) Length);\r
       ReadFileInfo->ReadLength = Length;\r
       //\r
       CopyMem (ReadFileInfo->FileData, Data, (UINTN) Length);\r
       ReadFileInfo->ReadLength = Length;\r
-    } else if (ReadFileInfo->Flags == READ_FILE_SEEK_AND_READ) {\r
+    } else if (ReadFileInfo->Flags == ReadFileSeekAndRead) {\r
       //\r
       // If FilePosition is non-zero, seek file to FilePosition, read\r
       // FileDataSize bytes and then updates FilePosition.\r
       //\r
       // If FilePosition is non-zero, seek file to FilePosition, read\r
       // FileDataSize bytes and then updates FilePosition.\r
@@ -967,9 +1134,11 @@ ReadFile (
       return EFI_INVALID_PARAMETER;\r
     }\r
 \r
       return EFI_INVALID_PARAMETER;\r
     }\r
 \r
+    Status = EFI_SUCCESS;\r
     break;\r
     break;\r
-  case LONG_ADS_SEQUENCE:\r
-  case SHORT_ADS_SEQUENCE:\r
+\r
+  case LongAdsSequence:\r
+  case ShortAdsSequence:\r
     //\r
     // This FE/EFE contains a run of Allocation Descriptors. Get data + size\r
     // for start reading them out.\r
     //\r
     // This FE/EFE contains a run of Allocation Descriptors. Get data + size\r
     // for start reading them out.\r
@@ -997,7 +1166,7 @@ ReadFile (
       // Check if AD is an indirect AD. If so, read Allocation Extent\r
       // Descriptor and its extents (ADs).\r
       //\r
       // Check if AD is an indirect AD. If so, read Allocation Extent\r
       // Descriptor and its extents (ADs).\r
       //\r
-      if (GET_EXTENT_FLAGS (RecordingFlags, Ad) == EXTENT_IS_NEXT_EXTENT) {\r
+      if (GET_EXTENT_FLAGS (RecordingFlags, Ad) == ExtentIsNextExtent) {\r
         if (!DoFreeAed) {\r
           DoFreeAed = TRUE;\r
         } else {\r
         if (!DoFreeAed) {\r
           DoFreeAed = TRUE;\r
         } else {\r
@@ -1017,6 +1186,7 @@ ReadFile (
         if (EFI_ERROR (Status)) {\r
           goto Error_Get_Aed;\r
         }\r
         if (EFI_ERROR (Status)) {\r
           goto Error_Get_Aed;\r
         }\r
+        ASSERT (Data != NULL);\r
 \r
         AdOffset = 0;\r
         continue;\r
 \r
         AdOffset = 0;\r
         continue;\r
@@ -1024,16 +1194,20 @@ ReadFile (
 \r
       ExtentLength = GET_EXTENT_LENGTH (RecordingFlags, Ad);\r
 \r
 \r
       ExtentLength = GET_EXTENT_LENGTH (RecordingFlags, Ad);\r
 \r
-      Lsn = GetAllocationDescriptorLsn (RecordingFlags,\r
-                                        Volume,\r
-                                        ParentIcb,\r
-                                        Ad);\r
+      Status = GetAllocationDescriptorLsn (RecordingFlags,\r
+                                           Volume,\r
+                                           ParentIcb,\r
+                                           Ad,\r
+                                           &Lsn);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
 \r
       switch (ReadFileInfo->Flags) {\r
 \r
       switch (ReadFileInfo->Flags) {\r
-      case READ_FILE_GET_FILESIZE:\r
+      case ReadFileGetFileSize:\r
         ReadFileInfo->ReadLength += ExtentLength;\r
         break;\r
         ReadFileInfo->ReadLength += ExtentLength;\r
         break;\r
-      case READ_FILE_ALLOCATE_AND_READ:\r
+      case ReadFileAllocateAndRead:\r
         //\r
         // Increase FileData (if necessary) to read next extent.\r
         //\r
         //\r
         // Increase FileData (if necessary) to read next extent.\r
         //\r
@@ -1064,7 +1238,7 @@ ReadFile (
 \r
         ReadFileInfo->ReadLength += ExtentLength;\r
         break;\r
 \r
         ReadFileInfo->ReadLength += ExtentLength;\r
         break;\r
-      case READ_FILE_SEEK_AND_READ:\r
+      case ReadFileSeekAndRead:\r
         //\r
         // Seek file first before reading in its data.\r
         //\r
         //\r
         // Seek file first before reading in its data.\r
         //\r
@@ -1080,9 +1254,6 @@ ReadFile (
 \r
         if (FilePosition + ExtentLength > ReadFileInfo->FilePosition) {\r
           Offset = ReadFileInfo->FilePosition - FilePosition;\r
 \r
         if (FilePosition + ExtentLength > ReadFileInfo->FilePosition) {\r
           Offset = ReadFileInfo->FilePosition - FilePosition;\r
-          if (Offset < 0) {\r
-            Offset = -(Offset);\r
-          }\r
         } else {\r
           Offset = 0;\r
         }\r
         } else {\r
           Offset = 0;\r
         }\r
@@ -1143,11 +1314,19 @@ ReadFile (
     }\r
 \r
     break;\r
     }\r
 \r
     break;\r
-  case EXTENDED_ADS_SEQUENCE:\r
+  case ExtendedAdsSequence:\r
      // FIXME: Not supported. Got no volume with it, yet.\r
     ASSERT (FALSE);\r
     Status = EFI_UNSUPPORTED;\r
     break;\r
      // FIXME: Not supported. Got no volume with it, yet.\r
     ASSERT (FALSE);\r
     Status = EFI_UNSUPPORTED;\r
     break;\r
+\r
+  default:\r
+    //\r
+    // A flag value reserved by the ECMA-167 standard (3rd Edition - June\r
+    // 1997); 14.6 ICB Tag; 14.6.8 Flags (RBP 18); was found.\r
+    //\r
+    Status = EFI_UNSUPPORTED;\r
+    break;\r
   }\r
 \r
 Done:\r
   }\r
 \r
 Done:\r
@@ -1159,7 +1338,7 @@ Done:
 \r
 Error_Read_Disk_Blk:\r
 Error_Alloc_Buffer_To_Next_Ad:\r
 \r
 Error_Read_Disk_Blk:\r
 Error_Alloc_Buffer_To_Next_Ad:\r
-  if (ReadFileInfo->Flags != READ_FILE_SEEK_AND_READ) {\r
+  if (ReadFileInfo->Flags != ReadFileSeekAndRead) {\r
     FreePool (ReadFileInfo->FileData);\r
   }\r
 \r
     FreePool (ReadFileInfo->FileData);\r
   }\r
 \r
@@ -1171,9 +1350,22 @@ Error_Get_Aed:
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r
-//\r
-// Find a file by its filename from a given Parent file.\r
-//\r
+/**\r
+  Find a file by its filename from a given Parent file.\r
+\r
+  @param[in]  BlockIo             BlockIo interface.\r
+  @param[in]  DiskIo              DiskIo interface.\r
+  @param[in]  Volume              Volume information pointer.\r
+  @param[in]  FileName            File name string.\r
+  @param[in]  Parent              Parent directory file.\r
+  @param[in]  Icb                 Long Allocation Descriptor pointer.\r
+  @param[out] File                Found file.\r
+\r
+  @retval EFI_SUCCESS             The file was found.\r
+  @retval EFI_INVALID_PARAMETER   One or more input parameters are invalid.\r
+  @retval EFI_NOT_FOUND           The file was not found.\r
+\r
+**/\r
 EFI_STATUS\r
 InternalFindFile (\r
   IN   EFI_BLOCK_IO_PROTOCOL           *BlockIo,\r
 EFI_STATUS\r
 InternalFindFile (\r
   IN   EFI_BLOCK_IO_PROTOCOL           *BlockIo,\r
@@ -1192,10 +1384,17 @@ InternalFindFile (
   CHAR16                          FoundFileName[UDF_FILENAME_LENGTH];\r
   VOID                            *CompareFileEntry;\r
 \r
   CHAR16                          FoundFileName[UDF_FILENAME_LENGTH];\r
   VOID                            *CompareFileEntry;\r
 \r
+  //\r
+  // Check if both Parent->FileIdentifierDesc and Icb are NULL.\r
+  //\r
+  if ((Parent->FileIdentifierDesc == NULL) && (Icb == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   //\r
   // Check if parent file is really directory.\r
   //\r
   //\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
     return EFI_NOT_FOUND;\r
   }\r
 \r
@@ -1204,8 +1403,20 @@ InternalFindFile (
   // FE/EFE and FID descriptors.\r
   //\r
   if (StrCmp (FileName, L".") == 0) {\r
   // FE/EFE and FID descriptors.\r
   //\r
   if (StrCmp (FileName, L".") == 0) {\r
+    if (Parent->FileIdentifierDesc == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
     DuplicateFe (BlockIo, Volume, Parent->FileEntry, &File->FileEntry);\r
     DuplicateFe (BlockIo, Volume, Parent->FileEntry, &File->FileEntry);\r
+    if (File->FileEntry == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
     DuplicateFid (Parent->FileIdentifierDesc, &File->FileIdentifierDesc);\r
     DuplicateFid (Parent->FileIdentifierDesc, &File->FileIdentifierDesc);\r
+    if (File->FileIdentifierDesc == NULL) {\r
+      FreePool (File->FileEntry);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
 \r
     return EFI_SUCCESS;\r
   }\r
 \r
     return EFI_SUCCESS;\r
   }\r
@@ -1221,7 +1432,7 @@ InternalFindFile (
       BlockIo,\r
       DiskIo,\r
       Volume,\r
       BlockIo,\r
       DiskIo,\r
       Volume,\r
-      Parent->FileIdentifierDesc ?\r
+      (Parent->FileIdentifierDesc != NULL) ?\r
       &Parent->FileIdentifierDesc->Icb :\r
       Icb,\r
       Parent->FileEntry,\r
       &Parent->FileIdentifierDesc->Icb :\r
       Icb,\r
       Parent->FileEntry,\r
@@ -1235,8 +1446,17 @@ InternalFindFile (
 \r
       break;\r
     }\r
 \r
       break;\r
     }\r
+    //\r
+    // After calling function ReadDirectoryEntry(), if 'FileIdentifierDesc' is\r
+    // NULL, then the 'Status' must be EFI_OUT_OF_RESOURCES. Hence, if the code\r
+    // reaches here, 'FileIdentifierDesc' must be not NULL.\r
+    //\r
+    // The ASSERT here is for addressing a false positive NULL pointer\r
+    // dereference issue raised from static analysis.\r
+    //\r
+    ASSERT (FileIdentifierDesc != NULL);\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
       //\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
@@ -1247,7 +1467,7 @@ InternalFindFile (
         break;\r
       }\r
     } else {\r
         break;\r
       }\r
     } else {\r
-      Status = GetFileNameFromFid (FileIdentifierDesc, FoundFileName);\r
+      Status = GetFileNameFromFid (FileIdentifierDesc, ARRAY_SIZE (FoundFileName), FoundFileName);\r
       if (EFI_ERROR (Status)) {\r
         break;\r
       }\r
       if (EFI_ERROR (Status)) {\r
         break;\r
       }\r
@@ -1339,6 +1559,9 @@ ReadUdfVolumeInformation (
 {\r
   EFI_STATUS Status;\r
 \r
 {\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
   Status = ReadVolumeFileStructure (\r
     BlockIo,\r
     DiskIo,\r
@@ -1348,13 +1571,12 @@ ReadUdfVolumeInformation (
     return Status;\r
   }\r
 \r
     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
   if (EFI_ERROR (Status)) {\r
-    CleanupVolumeInformation (Volume);\r
+    return Status;\r
   }\r
 \r
   return Status;\r
   }\r
 \r
   return Status;\r
@@ -1391,7 +1613,7 @@ FindRootDirectory (
     BlockIo,\r
     DiskIo,\r
     Volume,\r
     BlockIo,\r
     DiskIo,\r
     Volume,\r
-    &Volume->FileSetDescs[0]->RootDirectoryIcb,\r
+    &Volume->FileSetDesc.RootDirectoryIcb,\r
     &File->FileEntry\r
     );\r
   if (EFI_ERROR (Status)) {\r
     &File->FileEntry\r
     );\r
   if (EFI_ERROR (Status)) {\r
@@ -1408,7 +1630,7 @@ FindRootDirectory (
     L"\\",\r
     NULL,\r
     &Parent,\r
     L"\\",\r
     NULL,\r
     &Parent,\r
-    &Volume->FileSetDescs[0]->RootDirectoryIcb,\r
+    &Volume->FileSetDesc.RootDirectoryIcb,\r
     File\r
     );\r
   if (EFI_ERROR (Status)) {\r
     File\r
     );\r
   if (EFI_ERROR (Status)) {\r
@@ -1444,15 +1666,21 @@ FindFileEntry (
   OUT  VOID                            **FileEntry\r
   )\r
 {\r
   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
+  VOID                *ReadBuffer;\r
 \r
 \r
-  Lsn               = GetLongAdLsn (Volume, Icb);\r
-  LogicalBlockSize  = LV_BLOCK_SIZE (Volume, UDF_DEFAULT_LV_NUM);\r
+  Status = GetLongAdLsn (Volume, Icb, &Lsn);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  LogicalBlockSize  = Volume->LogicalVolDesc.LogicalBlockSize;\r
 \r
 \r
-  *FileEntry = AllocateZeroPool (Volume->FileEntrySize);\r
-  if (*FileEntry == NULL) {\r
+  ReadBuffer = AllocateZeroPool (Volume->FileEntrySize);\r
+  if (ReadBuffer == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
@@ -1464,26 +1692,30 @@ FindFileEntry (
     BlockIo->Media->MediaId,\r
     MultU64x32 (Lsn, LogicalBlockSize),\r
     Volume->FileEntrySize,\r
     BlockIo->Media->MediaId,\r
     MultU64x32 (Lsn, LogicalBlockSize),\r
     Volume->FileEntrySize,\r
-    *FileEntry\r
+    ReadBuffer\r
     );\r
   if (EFI_ERROR (Status)) {\r
     goto Error_Read_Disk_Blk;\r
   }\r
 \r
     );\r
   if (EFI_ERROR (Status)) {\r
     goto Error_Read_Disk_Blk;\r
   }\r
 \r
+  DescriptorTag = ReadBuffer;\r
+\r
   //\r
   // Check if the read extent contains a valid Tag Identifier for the expected\r
   // FE/EFE.\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
 \r
     Status = EFI_VOLUME_CORRUPTED;\r
     goto Error_Invalid_Fe;\r
   }\r
 \r
+  *FileEntry = ReadBuffer;\r
   return EFI_SUCCESS;\r
 \r
 Error_Invalid_Fe:\r
 Error_Read_Disk_Blk:\r
   return EFI_SUCCESS;\r
 \r
 Error_Invalid_Fe:\r
 Error_Read_Disk_Blk:\r
-  FreePool (*FileEntry);\r
+  FreePool (ReadBuffer);\r
 \r
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
@@ -1497,13 +1729,14 @@ Error_Read_Disk_Blk:
   @param[in]   FilePath  File's absolute path.\r
   @param[in]   Root      Root directory file.\r
   @param[in]   Parent    Parent directory file.\r
   @param[in]   FilePath  File's absolute path.\r
   @param[in]   Root      Root directory file.\r
   @param[in]   Parent    Parent directory file.\r
+  @param[in]   Icb       ICB of Parent.\r
   @param[out]  File      Found file.\r
 \r
   @param[out]  File      Found file.\r
 \r
-  @retval EFI_SUCCESS          @p FilePath was found.\r
+  @retval EFI_SUCCESS          FilePath was 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_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 @p FilePath file was not found due to lack of\r
+  @retval EFI_OUT_OF_RESOURCES The FilePath file was not found due to lack of\r
                                resources.\r
 \r
 **/\r
                                resources.\r
 \r
 **/\r
@@ -1531,6 +1764,11 @@ FindFile (
   while (*FilePath != L'\0') {\r
     FileNamePointer = FileName;\r
     while (*FilePath != L'\0' && *FilePath != L'\\') {\r
   while (*FilePath != L'\0') {\r
     FileNamePointer = FileName;\r
     while (*FilePath != L'\0' && *FilePath != L'\\') {\r
+      if ((((UINTN)FileNamePointer - (UINTN)FileName) / sizeof (CHAR16)) >=\r
+          (ARRAY_SIZE (FileName) - 1)) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
       *FileNamePointer++ = *FilePath++;\r
     }\r
 \r
       *FileNamePointer++ = *FilePath++;\r
     }\r
 \r
@@ -1558,9 +1796,20 @@ FindFile (
         // We've already a file pointer (Root) for the root directory. Duplicate\r
         // its FE/EFE and FID descriptors.\r
         //\r
         // We've already a file pointer (Root) for the root directory. Duplicate\r
         // its FE/EFE and FID descriptors.\r
         //\r
-        DuplicateFe (BlockIo, Volume, Root->FileEntry, &File->FileEntry);\r
-        DuplicateFid (Root->FileIdentifierDesc, &File->FileIdentifierDesc);\r
         Status = EFI_SUCCESS;\r
         Status = EFI_SUCCESS;\r
+        DuplicateFe (BlockIo, Volume, Root->FileEntry, &File->FileEntry);\r
+        if (File->FileEntry == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+        } else {\r
+          //\r
+          // File->FileEntry is not NULL.\r
+          //\r
+          DuplicateFid (Root->FileIdentifierDesc, &File->FileIdentifierDesc);\r
+          if (File->FileIdentifierDesc == NULL) {\r
+            FreePool (File->FileEntry);\r
+            Status = EFI_OUT_OF_RESOURCES;\r
+          }\r
+        }\r
       }\r
     } else {\r
       //\r
       }\r
     } else {\r
       //\r
@@ -1583,7 +1832,7 @@ FindFile (
     // If the found file is a symlink, then find its respective FE/EFE and\r
     // FID descriptors.\r
     //\r
     // 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
       FreePool ((VOID *)File->FileIdentifierDesc);\r
 \r
       FileEntry = File->FileEntry;\r
@@ -1624,7 +1873,7 @@ FindFile (
   @param[in]      Volume         UDF volume information structure.\r
   @param[in]      ParentIcb      ICB of the parent file.\r
   @param[in]      FileEntryData  FE/EFE of the parent file.\r
   @param[in]      Volume         UDF volume information structure.\r
   @param[in]      ParentIcb      ICB of the parent file.\r
   @param[in]      FileEntryData  FE/EFE of the parent file.\r
-  @param[in out]  ReadDirInfo    Next read directory listing structure\r
+  @param[in, out] ReadDirInfo    Next read directory listing structure\r
                                  information.\r
   @param[out]     FoundFid       File Identifier Descriptor pointer.\r
 \r
                                  information.\r
   @param[out]     FoundFid       File Identifier Descriptor pointer.\r
 \r
@@ -1657,7 +1906,7 @@ ReadDirectoryEntry (
     // The directory's recorded data has not been read yet. So let's cache it\r
     // into memory and the next calls won't need to read it again.\r
     //\r
     // The directory's recorded data has not been read yet. So let's cache it\r
     // into memory and the next calls won't need to read it again.\r
     //\r
-    ReadFileInfo.Flags = READ_FILE_ALLOCATE_AND_READ;\r
+    ReadFileInfo.Flags = ReadFileAllocateAndRead;\r
 \r
     Status = ReadFile (\r
       BlockIo,\r
 \r
     Status = ReadFile (\r
       BlockIo,\r
@@ -1697,9 +1946,12 @@ ReadDirectoryEntry (
     // Update FidOffset to point to next FID.\r
     //\r
     ReadDirInfo->FidOffset += GetFidDescriptorLength (FileIdentifierDesc);\r
     // 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
   DuplicateFid (FileIdentifierDesc, FoundFid);\r
+  if (*FoundFid == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -1708,22 +1960,38 @@ ReadDirectoryEntry (
   Get a filename (encoded in OSTA-compressed format) from a File Identifier\r
   Descriptor on an UDF volume.\r
 \r
   Get a filename (encoded in OSTA-compressed format) from a File Identifier\r
   Descriptor on an UDF volume.\r
 \r
+  @attention This is boundary function that may receive untrusted input.\r
+  @attention The input is from FileSystem.\r
+\r
+  The File Identifier Descriptor is external input, so this routine will do\r
+  basic validation for File Identifier Descriptor and report status.\r
+\r
   @param[in]   FileIdentifierDesc  File Identifier Descriptor pointer.\r
   @param[in]   FileIdentifierDesc  File Identifier Descriptor pointer.\r
+  @param[in]   CharMax             The maximum number of FileName Unicode char,\r
+                                   including terminating null char.\r
   @param[out]  FileName            Decoded filename.\r
 \r
   @retval EFI_SUCCESS           Filename decoded and read.\r
   @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
   @param[out]  FileName            Decoded filename.\r
 \r
   @retval EFI_SUCCESS           Filename decoded and read.\r
   @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.\r
+  @retval EFI_BUFFER_TOO_SMALL  The string buffer FileName cannot hold the\r
+                                decoded filename.\r
 **/\r
 EFI_STATUS\r
 GetFileNameFromFid (\r
   IN   UDF_FILE_IDENTIFIER_DESCRIPTOR  *FileIdentifierDesc,\r
 **/\r
 EFI_STATUS\r
 GetFileNameFromFid (\r
   IN   UDF_FILE_IDENTIFIER_DESCRIPTOR  *FileIdentifierDesc,\r
+  IN   UINTN                           CharMax,\r
   OUT  CHAR16                          *FileName\r
   )\r
 {\r
   OUT  CHAR16                          *FileName\r
   )\r
 {\r
-  UINT8 *OstaCompressed;\r
-  UINT8 CompressionId;\r
-  UINT8 Length;\r
-  UINTN Index;\r
+  UINT8  *OstaCompressed;\r
+  UINT8  CompressionId;\r
+  UINT8  Length;\r
+  UINTN  Index;\r
+  CHAR16 *FileNameBak;\r
+\r
+  if (CharMax == 0) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
 \r
   OstaCompressed =\r
     (UINT8 *)(\r
 \r
   OstaCompressed =\r
     (UINT8 *)(\r
@@ -1736,10 +2004,22 @@ GetFileNameFromFid (
     return EFI_VOLUME_CORRUPTED;\r
   }\r
 \r
     return EFI_VOLUME_CORRUPTED;\r
   }\r
 \r
+  FileNameBak = FileName;\r
+\r
   //\r
   // Decode filename.\r
   //\r
   Length = FileIdentifierDesc->LengthOfFileIdentifier;\r
   //\r
   // Decode filename.\r
   //\r
   Length = FileIdentifierDesc->LengthOfFileIdentifier;\r
+  if (CompressionId == 16) {\r
+    if (((UINTN)Length >> 1) > CharMax) {\r
+      return EFI_BUFFER_TOO_SMALL;\r
+    }\r
+  } else {\r
+    if ((Length != 0) && ((UINTN)Length - 1 > CharMax)) {\r
+      return EFI_BUFFER_TOO_SMALL;\r
+    }\r
+  }\r
+\r
   for (Index = 1; Index < Length; Index++) {\r
     if (CompressionId == 16) {\r
       *FileName = OstaCompressed[Index++] << 8;\r
   for (Index = 1; Index < Length; Index++) {\r
     if (CompressionId == 16) {\r
       *FileName = OstaCompressed[Index++] << 8;\r
@@ -1748,13 +2028,17 @@ GetFileNameFromFid (
     }\r
 \r
     if (Index < Length) {\r
     }\r
 \r
     if (Index < Length) {\r
-      *FileName |= OstaCompressed[Index];\r
+      *FileName |= (CHAR16)(OstaCompressed[Index]);\r
     }\r
 \r
     FileName++;\r
   }\r
 \r
     }\r
 \r
     FileName++;\r
   }\r
 \r
-  *FileName = L'\0';\r
+  Index = ((UINTN)FileName - (UINTN)FileNameBak) / sizeof (CHAR16);\r
+  if (Index > CharMax - 1) {\r
+    Index = CharMax - 1;\r
+  }\r
+  FileNameBak[Index] = L'\0';\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -1762,6 +2046,12 @@ GetFileNameFromFid (
 /**\r
   Resolve a symlink file on an UDF volume.\r
 \r
 /**\r
   Resolve a symlink file on an UDF volume.\r
 \r
+  @attention This is boundary function that may receive untrusted input.\r
+  @attention The input is from FileSystem.\r
+\r
+  The Path Component is external input, so this routine will do basic\r
+  validation for Path Component and report status.\r
+\r
   @param[in]   BlockIo        BlockIo interface.\r
   @param[in]   DiskIo         DiskIo interface.\r
   @param[in]   Volume         UDF volume information structure.\r
   @param[in]   BlockIo        BlockIo interface.\r
   @param[in]   DiskIo         DiskIo interface.\r
   @param[in]   Volume         UDF volume information structure.\r
@@ -1796,7 +2086,7 @@ ResolveSymlink (
   UDF_PATH_COMPONENT  *PathComp;\r
   UINT8               PathCompLength;\r
   CHAR16              FileName[UDF_FILENAME_LENGTH];\r
   UDF_PATH_COMPONENT  *PathComp;\r
   UINT8               PathCompLength;\r
   CHAR16              FileName[UDF_FILENAME_LENGTH];\r
-  CHAR16              *C;\r
+  CHAR16              *Char;\r
   UINTN               Index;\r
   UINT8               CompressionId;\r
   UDF_FILE_INFO       PreviousFile;\r
   UINTN               Index;\r
   UINT8               CompressionId;\r
   UDF_FILE_INFO       PreviousFile;\r
@@ -1807,7 +2097,7 @@ ResolveSymlink (
   // all its data here -- usually the data will be inline with the FE/EFE for\r
   // lower filenames.\r
   //\r
   // all its data here -- usually the data will be inline with the FE/EFE for\r
   // lower filenames.\r
   //\r
-  ReadFileInfo.Flags = READ_FILE_ALLOCATE_AND_READ;\r
+  ReadFileInfo.Flags = ReadFileAllocateAndRead;\r
 \r
   Status = ReadFile (\r
     BlockIo,\r
 \r
   Status = ReadFile (\r
     BlockIo,\r
@@ -1857,8 +2147,18 @@ ResolveSymlink (
       // "." (current file). Duplicate both FE/EFE and FID of this file.\r
       //\r
       DuplicateFe (BlockIo, Volume, PreviousFile.FileEntry, &File->FileEntry);\r
       // "." (current file). Duplicate both FE/EFE and FID of this file.\r
       //\r
       DuplicateFe (BlockIo, Volume, PreviousFile.FileEntry, &File->FileEntry);\r
+      if (File->FileEntry == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Error_Find_File;\r
+      }\r
+\r
       DuplicateFid (PreviousFile.FileIdentifierDesc,\r
                     &File->FileIdentifierDesc);\r
       DuplicateFid (PreviousFile.FileIdentifierDesc,\r
                     &File->FileIdentifierDesc);\r
+      if (File->FileIdentifierDesc == NULL) {\r
+        FreePool (File->FileEntry);\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Error_Find_File;\r
+      }\r
       goto Next_Path_Component;\r
     case 5:\r
       //\r
       goto Next_Path_Component;\r
     case 5:\r
       //\r
@@ -1873,24 +2173,31 @@ ResolveSymlink (
         return EFI_VOLUME_CORRUPTED;\r
       }\r
 \r
         return EFI_VOLUME_CORRUPTED;\r
       }\r
 \r
-      C = FileName;\r
+      Char = FileName;\r
       for (Index = 1; Index < PathCompLength; Index++) {\r
         if (CompressionId == 16) {\r
       for (Index = 1; Index < PathCompLength; Index++) {\r
         if (CompressionId == 16) {\r
-          *C = *(UINT8 *)((UINT8 *)PathComp->ComponentIdentifier +\r
+          *Char = *(UINT8 *)((UINT8 *)PathComp->ComponentIdentifier +\r
                           Index) << 8;\r
           Index++;\r
         } else {\r
                           Index) << 8;\r
           Index++;\r
         } else {\r
-          *C = 0;\r
+          if (Index > ARRAY_SIZE (FileName)) {\r
+            return EFI_UNSUPPORTED;\r
+          }\r
+          *Char = 0;\r
         }\r
 \r
         if (Index < Length) {\r
         }\r
 \r
         if (Index < Length) {\r
-          *C |= *(UINT8 *)((UINT8 *)PathComp->ComponentIdentifier + Index);\r
+          *Char |= (CHAR16)(*(UINT8 *)((UINT8 *)PathComp->ComponentIdentifier + Index));\r
         }\r
 \r
         }\r
 \r
-        C++;\r
+        Char++;\r
       }\r
 \r
       }\r
 \r
-      *C = L'\0';\r
+      Index = ((UINTN)Char - (UINTN)FileName) / sizeof (CHAR16);\r
+      if (Index > ARRAY_SIZE (FileName) - 1) {\r
+        Index = ARRAY_SIZE (FileName) - 1;\r
+      }\r
+      FileName[Index] = L'\0';\r
       break;\r
     }\r
 \r
       break;\r
     }\r
 \r
@@ -1942,43 +2249,6 @@ Error_Find_File:
   return Status;\r
 }\r
 \r
   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
 /**\r
   Clean up in-memory UDF file information.\r
 \r
@@ -2009,7 +2279,7 @@ CleanupFileInformation (
   @param[in]   File     File information structure.\r
   @param[out]  Size     Size of the file.\r
 \r
   @param[in]   File     File information structure.\r
   @param[out]  Size     Size of the file.\r
 \r
-  @retval EFI_SUCCESS          File size calculated and set in @p Size.\r
+  @retval EFI_SUCCESS          File size calculated and set in Size.\r
   @retval EFI_UNSUPPORTED      Extended Allocation Descriptors not supported.\r
   @retval EFI_NO_MEDIA         The device has no media.\r
   @retval EFI_DEVICE_ERROR     The device reported an error.\r
   @retval EFI_UNSUPPORTED      Extended Allocation Descriptors not supported.\r
   @retval EFI_NO_MEDIA         The device has no media.\r
   @retval EFI_DEVICE_ERROR     The device reported an error.\r
@@ -2030,7 +2300,7 @@ GetFileSize (
   EFI_STATUS          Status;\r
   UDF_READ_FILE_INFO  ReadFileInfo;\r
 \r
   EFI_STATUS          Status;\r
   UDF_READ_FILE_INFO  ReadFileInfo;\r
 \r
-  ReadFileInfo.Flags = READ_FILE_GET_FILESIZE;\r
+  ReadFileInfo.Flags = ReadFileGetFileSize;\r
 \r
   Status = ReadFile (\r
     BlockIo,\r
 \r
   Status = ReadFile (\r
     BlockIo,\r
@@ -2055,7 +2325,7 @@ GetFileSize (
   @param[in]      File        File pointer.\r
   @param[in]      FileSize    Size of the file.\r
   @param[in]      FileName    Filename of the file.\r
   @param[in]      File        File pointer.\r
   @param[in]      FileSize    Size of the file.\r
   @param[in]      FileName    Filename of the file.\r
-  @param[in out]  BufferSize  Size of the returned file infomation.\r
+  @param[in, out] BufferSize  Size of the returned file infomation.\r
   @param[out]     Buffer      Data of the returned file information.\r
 \r
   @retval EFI_SUCCESS          File information set.\r
   @param[out]     Buffer      Data of the returned file information.\r
 \r
   @retval EFI_SUCCESS          File information set.\r
@@ -2079,11 +2349,12 @@ SetFileInfo (
   EFI_FILE_INFO            *FileInfo;\r
   UDF_FILE_ENTRY           *FileEntry;\r
   UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;\r
   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
   //\r
 \r
   //\r
   // Calculate the needed size for the EFI_FILE_INFO structure.\r
   //\r
-  FileInfoLength = sizeof (EFI_FILE_INFO) + (FileName ?\r
+  FileInfoLength = sizeof (EFI_FILE_INFO) + ((FileName != NULL) ?\r
                                              StrSize (FileName) :\r
                                              sizeof (CHAR16));\r
   if (*BufferSize < FileInfoLength) {\r
                                              StrSize (FileName) :\r
                                              sizeof (CHAR16));\r
   if (*BufferSize < FileInfoLength) {\r
@@ -2113,7 +2384,9 @@ SetFileInfo (
     FileInfo->Attribute |= EFI_FILE_HIDDEN;\r
   }\r
 \r
     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
     FileEntry = (UDF_FILE_ENTRY *)File->FileEntry;\r
 \r
     //\r
@@ -2149,7 +2422,7 @@ SetFileInfo (
                                    FileEntry->AccessTime.Second;\r
     FileInfo->LastAccessTime.Nanosecond  =\r
                                    FileEntry->AccessTime.HundredsOfMicroseconds;\r
                                    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
     ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)File->FileEntry;\r
 \r
     //\r
@@ -2233,91 +2506,103 @@ GetVolumeSize (
   OUT  UINT64                 *FreeSpaceSize\r
   )\r
 {\r
   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
 \r
-    LogicalBlockSize = LV_BLOCK_SIZE (Volume, Index);\r
+  LogicalVolDesc = &Volume->LogicalVolDesc;\r
 \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
 \r
-    Lsn = (UINT64)ExtentAd.ExtentLocation;\r
+  LogicalVolInt = AllocatePool (ExtentAd->ExtentLength);\r
+  if (LogicalVolInt == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\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
 \r
-    if (!IS_LVID (LogicalVolInt)) {\r
-      FreePool ((VOID *)LogicalVolInt);\r
-      return EFI_VOLUME_CORRUPTED;\r
-    }\r
+  LogicalBlockSize = LogicalVolDesc->LogicalBlockSize;\r
 \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
 \r
-      *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);\r
-    }\r
+  DescriptorTag = &LogicalVolInt->DescriptorTag;\r
 \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
 \r
-      *VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);\r
-    }\r
+  *VolumeSize = 0;\r
+  *FreeSpaceSize = 0;\r
 \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
+    //\r
+    // Accumulate free space size\r
+    //\r
+    *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);\r
+  }\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
   }\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
 }\r
 \r
 /**\r
@@ -2328,9 +2613,9 @@ GetVolumeSize (
   @param[in]      Volume        UDF volume information structure.\r
   @param[in]      File          File information structure.\r
   @param[in]      FileSize      Size of the file.\r
   @param[in]      Volume        UDF volume information structure.\r
   @param[in]      File          File information structure.\r
   @param[in]      FileSize      Size of the file.\r
-  @param[in out]  FilePosition  File position.\r
-  @param[in out]  Buffer        File data.\r
-  @param[in out]  BufferSize    Read size.\r
+  @param[in, out] FilePosition  File position.\r
+  @param[in, out] Buffer        File data.\r
+  @param[in, out] BufferSize    Read size.\r
 \r
   @retval EFI_SUCCESS          File seeked and read.\r
   @retval EFI_UNSUPPORTED      Extended Allocation Descriptors not supported.\r
 \r
   @retval EFI_SUCCESS          File seeked and read.\r
   @retval EFI_UNSUPPORTED      Extended Allocation Descriptors not supported.\r
@@ -2356,7 +2641,7 @@ ReadFileData (
   EFI_STATUS          Status;\r
   UDF_READ_FILE_INFO  ReadFileInfo;\r
 \r
   EFI_STATUS          Status;\r
   UDF_READ_FILE_INFO  ReadFileInfo;\r
 \r
-  ReadFileInfo.Flags         = READ_FILE_SEEK_AND_READ;\r
+  ReadFileInfo.Flags         = ReadFileSeekAndRead;\r
   ReadFileInfo.FilePosition  = *FilePosition;\r
   ReadFileInfo.FileData      = Buffer;\r
   ReadFileInfo.FileDataSize  = *BufferSize;\r
   ReadFileInfo.FilePosition  = *FilePosition;\r
   ReadFileInfo.FileData      = Buffer;\r
   ReadFileInfo.FileDataSize  = *BufferSize;\r
@@ -2401,7 +2686,6 @@ SupportUdfFileSystem (
   EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode;\r
   EFI_DEVICE_PATH_PROTOCOL  *LastDevicePathNode;\r
   EFI_GUID                  *VendorDefinedGuid;\r
   EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode;\r
   EFI_DEVICE_PATH_PROTOCOL  *LastDevicePathNode;\r
   EFI_GUID                  *VendorDefinedGuid;\r
-  EFI_GUID                  UdfDevPathGuid = EFI_UDF_DEVICE_PATH_GUID;\r
 \r
   //\r
   // Open Device Path protocol on ControllerHandle\r
 \r
   //\r
   // Open Device Path protocol on ControllerHandle\r
@@ -2438,7 +2722,7 @@ SupportUdfFileSystem (
       DevicePathSubType (LastDevicePathNode) == MEDIA_VENDOR_DP) {\r
     VendorDefinedGuid = (EFI_GUID *)((UINTN)LastDevicePathNode +\r
                                      OFFSET_OF (VENDOR_DEVICE_PATH, Guid));\r
       DevicePathSubType (LastDevicePathNode) == MEDIA_VENDOR_DP) {\r
     VendorDefinedGuid = (EFI_GUID *)((UINTN)LastDevicePathNode +\r
                                      OFFSET_OF (VENDOR_DEVICE_PATH, Guid));\r
-    if (CompareGuid (VendorDefinedGuid, &UdfDevPathGuid)) {\r
+    if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {\r
       Status = EFI_SUCCESS;\r
     }\r
   }\r
       Status = EFI_SUCCESS;\r
     }\r
   }\r