/** @file
  Handle on-disk format and volume structures in UDF/ECMA-167 file systems.

  Copyright (C) 2014-2017 Paulo Alcantara <pcacjr@zytor.com>
  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include "Udf.h"

//
// Vendor-Defined Device Path GUID for UDF file system
//
EFI_GUID  gUdfDevPathGuid = EFI_UDF_DEVICE_PATH_GUID;

/**
  Find the anchor volume descriptor pointer.

  @param[in]  BlockIo             BlockIo interface.
  @param[in]  DiskIo              DiskIo interface.
  @param[out] AnchorPoint         Anchor volume descriptor pointer.

  @retval EFI_SUCCESS             Anchor volume descriptor pointer found.
  @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.
  @retval other                   Anchor volume descriptor pointer not found.

**/
EFI_STATUS
FindAnchorVolumeDescriptorPointer (
  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
  OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
  )
{
  EFI_STATUS          Status;
  UINT32              BlockSize;
  EFI_LBA             EndLBA;
  EFI_LBA             DescriptorLBAs[4];
  UINTN               Index;
  UDF_DESCRIPTOR_TAG  *DescriptorTag;

  BlockSize         = BlockIo->Media->BlockSize;
  EndLBA            = BlockIo->Media->LastBlock;
  DescriptorLBAs[0] = 256;
  DescriptorLBAs[1] = EndLBA - 256;
  DescriptorLBAs[2] = EndLBA;
  DescriptorLBAs[3] = 512;

  for (Index = 0; Index < ARRAY_SIZE (DescriptorLBAs); Index++) {
    Status = DiskIo->ReadDisk (
                       DiskIo,
                       BlockIo->Media->MediaId,
                       MultU64x32 (DescriptorLBAs[Index], BlockSize),
                       sizeof (UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER),
                       (VOID *)AnchorPoint
                       );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    DescriptorTag = &AnchorPoint->DescriptorTag;

    //
    // Check if read LBA has a valid AVDP descriptor.
    //
    if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
      return EFI_SUCCESS;
    }
  }

  //
  // No AVDP found.
  //
  return EFI_VOLUME_CORRUPTED;
}

/**
  Save the content of Logical Volume Descriptors and Partitions Descriptors in
  memory.

  @param[in]  BlockIo             BlockIo interface.
  @param[in]  DiskIo              DiskIo interface.
  @param[in]  AnchorPoint         Anchor volume descriptor pointer.
  @param[out] Volume              UDF volume information structure.

  @retval EFI_SUCCESS             The descriptors were saved.
  @retval EFI_OUT_OF_RESOURCES    The descriptors were not saved due to lack of
                                  resources.
  @retval other                   The descriptors were not saved due to
                                  ReadDisk error.

**/
EFI_STATUS
StartMainVolumeDescriptorSequence (
  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
  OUT  UDF_VOLUME_INFO                       *Volume
  )
{
  EFI_STATUS          Status;
  UINT32              BlockSize;
  UDF_EXTENT_AD       *ExtentAd;
  EFI_LBA             SeqStartBlock;
  EFI_LBA             SeqEndBlock;
  BOOLEAN             StopSequence;
  VOID                *Buffer;
  UDF_DESCRIPTOR_TAG  *DescriptorTag;
  UINT32              LogicalBlockSize;

  BlockSize = BlockIo->Media->BlockSize;
  ExtentAd  = &AnchorPoint->MainVolumeDescriptorSequenceExtent;

  //
  // Allocate buffer for reading disk blocks
  //
  Buffer = AllocateZeroPool ((UINTN)BlockSize);
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // The logical partition created by Partition driver is relative to the main
  // VDS extent location, so we start the Main Volume Descriptor Sequence at
  // LBA 0.
  //
  // We don't need to check again if we have valid Volume Descriptors here since
  // Partition driver already did.
  //
  SeqStartBlock = 0;
  SeqEndBlock   = SeqStartBlock + DivU64x32 (
                                    (UINT64)ExtentAd->ExtentLength,
                                    BlockSize
                                    );
  StopSequence = FALSE;
  for ( ; SeqStartBlock < SeqEndBlock && !StopSequence; SeqStartBlock++) {
    //
    // Read disk block
    //
    Status = BlockIo->ReadBlocks (
                        BlockIo,
                        BlockIo->Media->MediaId,
                        SeqStartBlock,
                        BlockSize,
                        Buffer
                        );
    if (EFI_ERROR (Status)) {
      goto Out_Free;
    }

    DescriptorTag = Buffer;

    switch (DescriptorTag->TagIdentifier) {
      case UdfPartitionDescriptor:
        //
        // Save Partition Descriptor
        //
        CopyMem (&Volume->PartitionDesc, Buffer, sizeof (Volume->PartitionDesc));
        break;

      case UdfLogicalVolumeDescriptor:
        //
        // Save Logical Volume Descriptor
        //
        CopyMem (&Volume->LogicalVolDesc, Buffer, sizeof (Volume->LogicalVolDesc));
        break;

      case UdfTerminatingDescriptor:
        StopSequence = TRUE;
        break;

      default:
        ;
    }
  }

  //
  // Determine FE (File Entry) size
  //
  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
  if (LogicalBlockSize >= UDF_LOGICAL_SECTOR_SIZE) {
    Volume->FileEntrySize = (UINTN)LogicalBlockSize;
  } else {
    Volume->FileEntrySize = UDF_LOGICAL_SECTOR_SIZE;
  }

  Status = EFI_SUCCESS;

Out_Free:
  //
  // Free block read buffer
  //
  FreePool (Buffer);

  return Status;
}

/**
  Return a Partition Descriptor given a Long Allocation Descriptor. This is
  necessary to calculate the right extent (LongAd) offset which is added up
  with partition's starting location.

  @param[in]  Volume              Volume information pointer.
  @param[in]  LongAd              Long Allocation Descriptor pointer.

  @return A pointer to a Partition Descriptor.

**/
UDF_PARTITION_DESCRIPTOR *
GetPdFromLongAd (
  IN UDF_VOLUME_INFO                 *Volume,
  IN UDF_LONG_ALLOCATION_DESCRIPTOR  *LongAd
  )
{
  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
  UINT16                         PartitionNum;

  LogicalVolDesc = &Volume->LogicalVolDesc;

  switch (LogicalVolDesc->DomainIdentifier.Suffix.Domain.UdfRevision) {
    case 0x0102:
    case 0x0150:
    case 0x0200:
    case 0x0201:
    case 0x0250:
    case 0x0260:
      //
      // UDF 1.02 specification:
      //
      // There shall be exactly one prevailing Logical Volume Descriptor recorded
      // per Volume Set. The Partition Maps field shall contain only Type 1
      // Partition Maps.
      //
      // UDF 1.50 through 2.60 specs say:
      //
      // For the purpose of interchange partition maps shall be limited to
      // Partition Map type 1, except type 2 maps as described in the document.
      //
      // NOTE: Only one Type 1 (Physical) Partition is supported. It has been
      // checked already in Partition driver for existence of a single Type 1
      // Partition map. Hence, the 'PartitionReferenceNumber' field (the index
      // used to access Partition Maps data within the Logical Volume Descriptor)
      // in the Long Allocation Descriptor should be 0 to indicate there is only
      // one partition.
      //
      if (LongAd->ExtentLocation.PartitionReferenceNumber != 0) {
        return NULL;
      }

      //
      // Since only one partition, get the first one directly.
      //
      PartitionNum = *(UINT16 *)((UINTN)&LogicalVolDesc->PartitionMaps[4]);
      break;

    default:
      //
      // Unsupported UDF revision
      //
      return NULL;
  }

  //
  // Check if partition number matches Partition Descriptor found in Main Volume
  // Descriptor Sequence.
  //
  if (Volume->PartitionDesc.PartitionNumber == PartitionNum) {
    return &Volume->PartitionDesc;
  }

  return NULL;
}

/**
  Return logical sector number of a given Long Allocation Descriptor.

  @param[in]   Volume             Volume information pointer.
  @param[in]   LongAd             Long Allocation Descriptor pointer.
  @param[out]  Lsn                Logical sector number pointer.

  @retval EFI_SUCCESS             Logical sector number successfully returned.
  @retval EFI_UNSUPPORTED         Logical sector number is not returned due to
                                  unrecognized format.

**/
EFI_STATUS
GetLongAdLsn (
  IN  UDF_VOLUME_INFO                 *Volume,
  IN  UDF_LONG_ALLOCATION_DESCRIPTOR  *LongAd,
  OUT UINT64                          *Lsn
  )
{
  UDF_PARTITION_DESCRIPTOR  *PartitionDesc;

  PartitionDesc = GetPdFromLongAd (Volume, LongAd);
  if (PartitionDesc == NULL) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: Fail to get the Partition Descriptor from the given Long Allocation Descriptor.\n",
      __FUNCTION__
      ));
    return EFI_UNSUPPORTED;
  }

  *Lsn = (UINT64)PartitionDesc->PartitionStartingLocation -
         Volume->MainVdsStartLocation +
         LongAd->ExtentLocation.LogicalBlockNumber;

  return EFI_SUCCESS;
}

/**
  Return logical sector number of a given Short Allocation Descriptor.

  @param[in]  Volume              Volume pointer.
  @param[in]  PartitionDesc       Partition Descriptor pointer.
  @param[in]  ShortAd             Short Allocation Descriptor pointer.

  @return The logical sector number of a given Short Allocation Descriptor.

**/
UINT64
GetShortAdLsn (
  IN UDF_VOLUME_INFO                  *Volume,
  IN UDF_PARTITION_DESCRIPTOR         *PartitionDesc,
  IN UDF_SHORT_ALLOCATION_DESCRIPTOR  *ShortAd
  )
{
  return (UINT64)PartitionDesc->PartitionStartingLocation -
         Volume->MainVdsStartLocation + ShortAd->ExtentPosition;
}

/**
  Find File Set Descriptor of a given Logical Volume Descriptor.

  The found FSD will contain the extent (LogicalVolumeContentsUse) where our
  root directory is.

  @param[in]  BlockIo             BlockIo interface.
  @param[in]  DiskIo              DiskIo interface.
  @param[in]  Volume              Volume information pointer.

  @retval EFI_SUCCESS             File Set Descriptor pointer found.
  @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.
  @retval other                   File Set Descriptor pointer not found.

**/
EFI_STATUS
FindFileSetDescriptor (
  IN   EFI_BLOCK_IO_PROTOCOL  *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL   *DiskIo,
  IN   UDF_VOLUME_INFO        *Volume
  )
{
  EFI_STATUS                     Status;
  UINT64                         Lsn;
  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
  UDF_DESCRIPTOR_TAG             *DescriptorTag;

  LogicalVolDesc = &Volume->LogicalVolDesc;
  Status         = GetLongAdLsn (Volume, &LogicalVolDesc->LogicalVolumeContentsUse, &Lsn);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // As per UDF 2.60 specification:
  //
  // There shall be exactly one File Set Descriptor recorded per Logical
  // Volume.
  //
  // Read disk block
  //
  Status = DiskIo->ReadDisk (
                     DiskIo,
                     BlockIo->Media->MediaId,
                     MultU64x32 (Lsn, LogicalVolDesc->LogicalBlockSize),
                     sizeof (Volume->FileSetDesc),
                     &Volume->FileSetDesc
                     );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  DescriptorTag = &Volume->FileSetDesc.DescriptorTag;

  //
  // Check if read block is a File Set Descriptor
  //
  if (DescriptorTag->TagIdentifier != UdfFileSetDescriptor) {
    return EFI_VOLUME_CORRUPTED;
  }

  return EFI_SUCCESS;
}

/**
  Read Volume and File Structure on an UDF file system.

  @param[in]   BlockIo            BlockIo interface.
  @param[in]   DiskIo             DiskIo interface.
  @param[out]  Volume             Volume information pointer.

  @retval EFI_SUCCESS             Volume and File Structure were read.
  @retval other                   Volume and File Structure were not read.

**/
EFI_STATUS
ReadVolumeFileStructure (
  IN   EFI_BLOCK_IO_PROTOCOL  *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL   *DiskIo,
  OUT  UDF_VOLUME_INFO        *Volume
  )
{
  EFI_STATUS                            Status;
  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
  UDF_EXTENT_AD                         *ExtentAd;

  //
  // Find Anchor Volume Descriptor Pointer
  //
  Status = FindAnchorVolumeDescriptorPointer (
             BlockIo,
             DiskIo,
             &AnchorPoint
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Save Main VDS start block number
  //
  ExtentAd = &AnchorPoint.MainVolumeDescriptorSequenceExtent;

  Volume->MainVdsStartLocation = (UINT64)ExtentAd->ExtentLocation;

  //
  // Start Main Volume Descriptor Sequence.
  //
  Status = StartMainVolumeDescriptorSequence (
             BlockIo,
             DiskIo,
             &AnchorPoint,
             Volume
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return Status;
}

/**
  Calculate length of a given File Identifier Descriptor.

  @param[in]  FileIdentifierDesc  File Identifier Descriptor pointer.

  @return The length of a given File Identifier Descriptor.

**/
UINT64
GetFidDescriptorLength (
  IN UDF_FILE_IDENTIFIER_DESCRIPTOR  *FileIdentifierDesc
  )
{
  return (UINT64)(
                  (INTN)((OFFSET_OF (UDF_FILE_IDENTIFIER_DESCRIPTOR, Data[0]) + 3 +
                          FileIdentifierDesc->LengthOfFileIdentifier +
                          FileIdentifierDesc->LengthOfImplementationUse) >> 2) << 2
                  );
}

/**
  Duplicate a given File Identifier Descriptor.

  @param[in]  FileIdentifierDesc     File Identifier Descriptor pointer.
  @param[out] NewFileIdentifierDesc  The duplicated File Identifier Descriptor.

**/
VOID
DuplicateFid (
  IN   UDF_FILE_IDENTIFIER_DESCRIPTOR  *FileIdentifierDesc,
  OUT  UDF_FILE_IDENTIFIER_DESCRIPTOR  **NewFileIdentifierDesc
  )
{
  *NewFileIdentifierDesc =
    (UDF_FILE_IDENTIFIER_DESCRIPTOR *)AllocateCopyPool (
                                        (UINTN)GetFidDescriptorLength (FileIdentifierDesc),
                                        FileIdentifierDesc
                                        );
}

/**
  Duplicate either a given File Entry or a given Extended File Entry.

  @param[in]  BlockIo             BlockIo interface.
  @param[in]  Volume              Volume information pointer.
  @param[in]  FileEntry           (Extended) File Entry pointer.
  @param[out] NewFileEntry        The duplicated (Extended) File Entry.

**/
VOID
DuplicateFe (
  IN   EFI_BLOCK_IO_PROTOCOL  *BlockIo,
  IN   UDF_VOLUME_INFO        *Volume,
  IN   VOID                   *FileEntry,
  OUT  VOID                   **NewFileEntry
  )
{
  *NewFileEntry = AllocateCopyPool (Volume->FileEntrySize, FileEntry);
}

/**
  Get raw data + length of a given File Entry or Extended File Entry.

  The file's recorded data can contain either real file content (inline) or
  a sequence of extents (or Allocation Descriptors) which tells where file's
  content is stored in.

  NOTE: The FE/EFE can be thought it was an inode.

  @attention This is boundary function that may receive untrusted input.
  @attention The input is from FileSystem.

  The (Extended) File Entry is external input, so this routine will do basic
  validation for (Extended) File Entry and report status.

  @param[in]  FileEntryData       (Extended) File Entry pointer.
  @param[in]  FileEntrySize       Size of the (Extended) File Entry specified
                                  by FileEntryData.
  @param[out] Data                Buffer contains the raw data of a given
                                  (Extended) File Entry.
  @param[out] Length              Length of the data in Buffer.

  @retval EFI_SUCCESS             Raw data and size of the FE/EFE was read.
  @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.

**/
EFI_STATUS
GetFileEntryData (
  IN   VOID    *FileEntryData,
  IN   UINTN   FileEntrySize,
  OUT  VOID    **Data,
  OUT  UINT64  *Length
  )
{
  UDF_DESCRIPTOR_TAG       *DescriptorTag;
  UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
  UDF_FILE_ENTRY           *FileEntry;

  DescriptorTag = FileEntryData;

  if (DescriptorTag->TagIdentifier == UdfExtendedFileEntry) {
    ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;

    *Length = ExtendedFileEntry->InformationLength;
    *Data   = (VOID *)((UINT8 *)ExtendedFileEntry->Data +
                       ExtendedFileEntry->LengthOfExtendedAttributes);
  } else if (DescriptorTag->TagIdentifier == UdfFileEntry) {
    FileEntry = (UDF_FILE_ENTRY *)FileEntryData;

    *Length = FileEntry->InformationLength;
    *Data   = (VOID *)((UINT8 *)FileEntry->Data +
                       FileEntry->LengthOfExtendedAttributes);
  }

  if ((*Length > FileEntrySize) ||
      ((UINTN)FileEntryData > (UINTN)(*Data)) ||
      ((UINTN)(*Data) - (UINTN)FileEntryData > FileEntrySize - *Length))
  {
    return EFI_VOLUME_CORRUPTED;
  }

  return EFI_SUCCESS;
}

/**
  Get Allocation Descriptors' data information from a given FE/EFE.

  @attention This is boundary function that may receive untrusted input.
  @attention The input is from FileSystem.

  The (Extended) File Entry is external input, so this routine will do basic
  validation for (Extended) File Entry and report status.

  @param[in]  FileEntryData       (Extended) File Entry pointer.
  @param[in]  FileEntrySize       Size of the (Extended) File Entry specified
                                  by FileEntryData.
  @param[out] AdsData             Buffer contains the Allocation Descriptors'
                                  data from a given FE/EFE.
  @param[out] Length              Length of the data in AdsData.

  @retval EFI_SUCCESS             The data and size of Allocation Descriptors
                                  were read from the FE/EFE.
  @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.

**/
EFI_STATUS
GetAdsInformation (
  IN   VOID    *FileEntryData,
  IN   UINTN   FileEntrySize,
  OUT  VOID    **AdsData,
  OUT  UINT64  *Length
  )
{
  UDF_DESCRIPTOR_TAG       *DescriptorTag;
  UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
  UDF_FILE_ENTRY           *FileEntry;

  DescriptorTag = FileEntryData;

  if (DescriptorTag->TagIdentifier == UdfExtendedFileEntry) {
    ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)FileEntryData;

    *Length  = ExtendedFileEntry->LengthOfAllocationDescriptors;
    *AdsData = (VOID *)((UINT8 *)ExtendedFileEntry->Data +
                        ExtendedFileEntry->LengthOfExtendedAttributes);
  } else if (DescriptorTag->TagIdentifier == UdfFileEntry) {
    FileEntry = (UDF_FILE_ENTRY *)FileEntryData;

    *Length  = FileEntry->LengthOfAllocationDescriptors;
    *AdsData = (VOID *)((UINT8 *)FileEntry->Data +
                        FileEntry->LengthOfExtendedAttributes);
  }

  if ((*Length > FileEntrySize) ||
      ((UINTN)FileEntryData > (UINTN)(*AdsData)) ||
      ((UINTN)(*AdsData) - (UINTN)FileEntryData > FileEntrySize - *Length))
  {
    return EFI_VOLUME_CORRUPTED;
  }

  return EFI_SUCCESS;
}

/**
  Read next Long Allocation Descriptor from a given file's data.

  @param[in]     Data             File's data pointer.
  @param[in,out] Offset           Starting offset of the File's data to read.
  @param[in]     Length           Length of the data to read.
  @param[out]    FoundLongAd      Long Allocation Descriptor pointer.

  @retval EFI_SUCCESS             A Long Allocation Descriptor was found.
  @retval EFI_DEVICE_ERROR        No more Long Allocation Descriptors.

**/
EFI_STATUS
GetLongAdFromAds (
  IN      VOID                            *Data,
  IN OUT  UINT64                          *Offset,
  IN      UINT64                          Length,
  OUT     UDF_LONG_ALLOCATION_DESCRIPTOR  **FoundLongAd
  )
{
  UDF_LONG_ALLOCATION_DESCRIPTOR  *LongAd;
  UDF_EXTENT_FLAGS                ExtentFlags;

  for ( ; ;) {
    if (*Offset >= Length) {
      //
      // No more Long Allocation Descriptors.
      //
      return EFI_DEVICE_ERROR;
    }

    LongAd =
      (UDF_LONG_ALLOCATION_DESCRIPTOR *)((UINT8 *)Data + *Offset);

    //
    // If it's either an indirect AD (Extended Alllocation Descriptor) or an
    // allocated AD, then return it.
    //
    ExtentFlags = GET_EXTENT_FLAGS (LongAdsSequence, LongAd);
    if ((ExtentFlags == ExtentIsNextExtent) ||
        (ExtentFlags == ExtentRecordedAndAllocated))
    {
      break;
    }

    //
    // This AD is either not recorded but allocated, or not recorded and not
    // allocated. Skip it.
    //
    *Offset += AD_LENGTH (LongAdsSequence);
  }

  *FoundLongAd = LongAd;

  return EFI_SUCCESS;
}

/**
  Read next Short Allocation Descriptor from a given file's data.

  @param[in]     Data             File's data pointer.
  @param[in,out] Offset           Starting offset of the File's data to read.
  @param[in]     Length           Length of the data to read.
  @param[out]    FoundShortAd     Short Allocation Descriptor pointer.

  @retval EFI_SUCCESS             A Short Allocation Descriptor was found.
  @retval EFI_DEVICE_ERROR        No more Short Allocation Descriptors.

**/
EFI_STATUS
GetShortAdFromAds (
  IN      VOID                             *Data,
  IN OUT  UINT64                           *Offset,
  IN      UINT64                           Length,
  OUT     UDF_SHORT_ALLOCATION_DESCRIPTOR  **FoundShortAd
  )
{
  UDF_SHORT_ALLOCATION_DESCRIPTOR  *ShortAd;
  UDF_EXTENT_FLAGS                 ExtentFlags;

  for ( ; ;) {
    if (*Offset >= Length) {
      //
      // No more Short Allocation Descriptors.
      //
      return EFI_DEVICE_ERROR;
    }

    ShortAd =
      (UDF_SHORT_ALLOCATION_DESCRIPTOR *)((UINT8 *)Data + *Offset);

    //
    // If it's either an indirect AD (Extended Alllocation Descriptor) or an
    // allocated AD, then return it.
    //
    ExtentFlags = GET_EXTENT_FLAGS (ShortAdsSequence, ShortAd);
    if ((ExtentFlags == ExtentIsNextExtent) ||
        (ExtentFlags == ExtentRecordedAndAllocated))
    {
      break;
    }

    //
    // This AD is either not recorded but allocated, or not recorded and not
    // allocated. Skip it.
    //
    *Offset += AD_LENGTH (ShortAdsSequence);
  }

  *FoundShortAd = ShortAd;

  return EFI_SUCCESS;
}

/**
  Get either a Short Allocation Descriptor or a Long Allocation Descriptor from
  file's data.

  @param[in]     RecordingFlags   Flag to indicate the type of descriptor.
  @param[in]     Data             File's data pointer.
  @param[in,out] Offset           Starting offset of the File's data to read.
  @param[in]     Length           Length of the data to read.
  @param[out]    FoundAd          Allocation Descriptor pointer.

  @retval EFI_SUCCESS             A Short Allocation Descriptor was found.
  @retval EFI_DEVICE_ERROR        No more Allocation Descriptors.
                                  Invalid type of descriptor was given.

**/
EFI_STATUS
GetAllocationDescriptor (
  IN      UDF_FE_RECORDING_FLAGS  RecordingFlags,
  IN      VOID                    *Data,
  IN OUT  UINT64                  *Offset,
  IN      UINT64                  Length,
  OUT     VOID                    **FoundAd
  )
{
  if (RecordingFlags == LongAdsSequence) {
    return GetLongAdFromAds (
             Data,
             Offset,
             Length,
             (UDF_LONG_ALLOCATION_DESCRIPTOR **)FoundAd
             );
  } else if (RecordingFlags == ShortAdsSequence) {
    return GetShortAdFromAds (
             Data,
             Offset,
             Length,
             (UDF_SHORT_ALLOCATION_DESCRIPTOR **)FoundAd
             );
  }

  //
  // Code should never reach here.
  //
  ASSERT (FALSE);
  return EFI_DEVICE_ERROR;
}

/**
  Return logical sector number of either Short or Long Allocation Descriptor.

  @param[in]  RecordingFlags      Flag to indicate the type of descriptor.
  @param[in]  Volume              Volume information pointer.
  @param[in]  ParentIcb           Long Allocation Descriptor pointer.
  @param[in]  Ad                  Allocation Descriptor pointer.
  @param[out] Lsn                 Logical sector number pointer.

  @retval EFI_SUCCESS             Logical sector number of the given Allocation
                                  Descriptor successfully returned.
  @retval EFI_UNSUPPORTED         Logical sector number of the given Allocation
                                  Descriptor is not returned due to unrecognized
                                  format.

**/
EFI_STATUS
GetAllocationDescriptorLsn (
  IN  UDF_FE_RECORDING_FLAGS          RecordingFlags,
  IN  UDF_VOLUME_INFO                 *Volume,
  IN  UDF_LONG_ALLOCATION_DESCRIPTOR  *ParentIcb,
  IN  VOID                            *Ad,
  OUT UINT64                          *Lsn
  )
{
  UDF_PARTITION_DESCRIPTOR  *PartitionDesc;

  if (RecordingFlags == LongAdsSequence) {
    return GetLongAdLsn (Volume, (UDF_LONG_ALLOCATION_DESCRIPTOR *)Ad, Lsn);
  } else if (RecordingFlags == ShortAdsSequence) {
    PartitionDesc = GetPdFromLongAd (Volume, ParentIcb);
    if (PartitionDesc == NULL) {
      return EFI_UNSUPPORTED;
    }

    *Lsn = GetShortAdLsn (
             Volume,
             PartitionDesc,
             (UDF_SHORT_ALLOCATION_DESCRIPTOR *)Ad
             );
    return EFI_SUCCESS;
  }

  //
  // Code should never reach here.
  //
  ASSERT (FALSE);
  return EFI_UNSUPPORTED;
}

/**
  Return offset + length of a given indirect Allocation Descriptor (AED).

  @param[in]  BlockIo             BlockIo interface.
  @param[in]  DiskIo              DiskIo interface.
  @param[in]  Volume              Volume information pointer.
  @param[in]  ParentIcb           Long Allocation Descriptor pointer.
  @param[in]  RecordingFlags      Flag to indicate the type of descriptor.
  @param[in]  Ad                  Allocation Descriptor pointer.
  @param[out] Offset              Offset of a given indirect Allocation
                                  Descriptor.
  @param[out] Length              Length of a given indirect Allocation
                                  Descriptor.

  @retval EFI_SUCCESS             The offset and length were returned.
  @retval EFI_OUT_OF_RESOURCES    The offset and length were not returned due
                                  to lack of resources.
  @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.
  @retval other                   The offset and length were not returned.

**/
EFI_STATUS
GetAedAdsOffset (
  IN   EFI_BLOCK_IO_PROTOCOL           *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL            *DiskIo,
  IN   UDF_VOLUME_INFO                 *Volume,
  IN   UDF_LONG_ALLOCATION_DESCRIPTOR  *ParentIcb,
  IN   UDF_FE_RECORDING_FLAGS          RecordingFlags,
  IN   VOID                            *Ad,
  OUT  UINT64                          *Offset,
  OUT  UINT64                          *Length
  )
{
  EFI_STATUS                        Status;
  UINT32                            ExtentLength;
  UINT64                            Lsn;
  VOID                              *Data;
  UINT32                            LogicalBlockSize;
  UDF_ALLOCATION_EXTENT_DESCRIPTOR  *AllocExtDesc;
  UDF_DESCRIPTOR_TAG                *DescriptorTag;

  ExtentLength = GET_EXTENT_LENGTH (RecordingFlags, Ad);
  Status       = GetAllocationDescriptorLsn (
                   RecordingFlags,
                   Volume,
                   ParentIcb,
                   Ad,
                   &Lsn
                   );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Data = AllocatePool (ExtentLength);
  if (Data == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;

  //
  // Read extent.
  //
  Status = DiskIo->ReadDisk (
                     DiskIo,
                     BlockIo->Media->MediaId,
                     MultU64x32 (Lsn, LogicalBlockSize),
                     ExtentLength,
                     Data
                     );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  AllocExtDesc = (UDF_ALLOCATION_EXTENT_DESCRIPTOR *)Data;

  DescriptorTag = &AllocExtDesc->DescriptorTag;

  //
  // Check if read extent contains a valid tag identifier for AED.
  //
  if (DescriptorTag->TagIdentifier != UdfAllocationExtentDescriptor) {
    Status = EFI_VOLUME_CORRUPTED;
    goto Exit;
  }

  //
  // Get AED's block offset and its length.
  //
  *Offset = MultU64x32 (Lsn, LogicalBlockSize) +
            sizeof (UDF_ALLOCATION_EXTENT_DESCRIPTOR);
  *Length = AllocExtDesc->LengthOfAllocationDescriptors;

Exit:
  FreePool (Data);

  return Status;
}

/**
  Read Allocation Extent Descriptor into memory.

  @param[in]  BlockIo             BlockIo interface.
  @param[in]  DiskIo              DiskIo interface.
  @param[in]  Volume              Volume information pointer.
  @param[in]  ParentIcb           Long Allocation Descriptor pointer.
  @param[in]  RecordingFlags      Flag to indicate the type of descriptor.
  @param[in]  Ad                  Allocation Descriptor pointer.
  @param[out] Data                Buffer that contains the Allocation Extent
                                  Descriptor.
  @param[out] Length              Length of Data.

  @retval EFI_SUCCESS             The Allocation Extent Descriptor was read.
  @retval EFI_OUT_OF_RESOURCES    The Allocation Extent Descriptor was not read
                                  due to lack of resources.
  @retval other                   Fail to read the disk.

**/
EFI_STATUS
GetAedAdsData (
  IN   EFI_BLOCK_IO_PROTOCOL           *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL            *DiskIo,
  IN   UDF_VOLUME_INFO                 *Volume,
  IN   UDF_LONG_ALLOCATION_DESCRIPTOR  *ParentIcb,
  IN   UDF_FE_RECORDING_FLAGS          RecordingFlags,
  IN   VOID                            *Ad,
  OUT  VOID                            **Data,
  OUT  UINT64                          *Length
  )
{
  EFI_STATUS  Status;
  UINT64      Offset;

  //
  // Get AED's offset + length.
  //
  Status = GetAedAdsOffset (
             BlockIo,
             DiskIo,
             Volume,
             ParentIcb,
             RecordingFlags,
             Ad,
             &Offset,
             Length
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Allocate buffer to read in AED's data.
  //
  *Data = AllocatePool ((UINTN)(*Length));
  if (*Data == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  return DiskIo->ReadDisk (
                   DiskIo,
                   BlockIo->Media->MediaId,
                   Offset,
                   (UINTN)(*Length),
                   *Data
                   );
}

/**
  Function used to serialise reads of Allocation Descriptors.

  @param[in]      RecordingFlags  Flag to indicate the type of descriptor.
  @param[in]      Ad              Allocation Descriptor pointer.
  @param[in, out] Buffer          Buffer to hold the next Allocation Descriptor.
  @param[in]      Length          Length of Buffer.

  @retval EFI_SUCCESS             Buffer was grown to hold the next Allocation
                                  Descriptor.
  @retval EFI_OUT_OF_RESOURCES    Buffer was not grown due to lack of resources.

**/
EFI_STATUS
GrowUpBufferToNextAd (
  IN      UDF_FE_RECORDING_FLAGS  RecordingFlags,
  IN      VOID                    *Ad,
  IN OUT  VOID                    **Buffer,
  IN      UINT64                  Length
  )
{
  UINT32  ExtentLength;

  ExtentLength = GET_EXTENT_LENGTH (RecordingFlags, Ad);

  if (*Buffer == NULL) {
    *Buffer = AllocatePool (ExtentLength);
    if (*Buffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  } else {
    *Buffer = ReallocatePool ((UINTN)Length, (UINTN)(Length + ExtentLength), *Buffer);
    if (*Buffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  return EFI_SUCCESS;
}

/**
  Read data or size of either a File Entry or an Extended File Entry.

  @param[in]      BlockIo         BlockIo interface.
  @param[in]      DiskIo          DiskIo interface.
  @param[in]      Volume          Volume information pointer.
  @param[in]      ParentIcb       Long Allocation Descriptor pointer.
  @param[in]      FileEntryData   FE/EFE structure pointer.
  @param[in, out] ReadFileInfo    Read file information pointer.

  @retval EFI_SUCCESS             Data or size of a FE/EFE was read.
  @retval EFI_OUT_OF_RESOURCES    Data or size of a FE/EFE was not read due to
                                  lack of resources.
  @retval EFI_INVALID_PARAMETER   The read file flag given in ReadFileInfo is
                                  invalid.
  @retval EFI_UNSUPPORTED         The FE recording flag given in FileEntryData
                                  is not supported.
  @retval other                   Data or size of a FE/EFE was not read.

**/
EFI_STATUS
ReadFile (
  IN      EFI_BLOCK_IO_PROTOCOL           *BlockIo,
  IN      EFI_DISK_IO_PROTOCOL            *DiskIo,
  IN      UDF_VOLUME_INFO                 *Volume,
  IN      UDF_LONG_ALLOCATION_DESCRIPTOR  *ParentIcb,
  IN      VOID                            *FileEntryData,
  IN OUT  UDF_READ_FILE_INFO              *ReadFileInfo
  )
{
  EFI_STATUS              Status;
  UINT32                  LogicalBlockSize;
  VOID                    *Data;
  VOID                    *DataBak;
  UINT64                  Length;
  VOID                    *Ad;
  UINT64                  AdOffset;
  UINT64                  Lsn;
  BOOLEAN                 DoFreeAed;
  UINT64                  FilePosition;
  UINT64                  Offset;
  UINT64                  DataOffset;
  UINT64                  BytesLeft;
  UINT64                  DataLength;
  BOOLEAN                 FinishedSeeking;
  UINT32                  ExtentLength;
  UDF_FE_RECORDING_FLAGS  RecordingFlags;

  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;
  DoFreeAed        = FALSE;

  //
  // set BytesLeft to suppress incorrect compiler/analyzer warnings
  //
  BytesLeft       = 0;
  DataOffset      = 0;
  FilePosition    = 0;
  FinishedSeeking = FALSE;
  Data            = NULL;

  switch (ReadFileInfo->Flags) {
    case ReadFileGetFileSize:
    case ReadFileAllocateAndRead:
      //
      // Initialise ReadFileInfo structure for either getting file size, or
      // reading file's recorded data.
      //
      ReadFileInfo->ReadLength = 0;
      ReadFileInfo->FileData   = NULL;
      break;
    case ReadFileSeekAndRead:
      //
      // About to seek a file and/or read its data.
      //
      Length = ReadFileInfo->FileSize - ReadFileInfo->FilePosition;
      if (ReadFileInfo->FileDataSize > Length) {
        //
        // About to read beyond the EOF -- truncate it.
        //
        ReadFileInfo->FileDataSize = Length;
      }

      //
      // Initialise data to start seeking and/or reading a file.
      //
      BytesLeft       = ReadFileInfo->FileDataSize;
      DataOffset      = 0;
      FilePosition    = 0;
      FinishedSeeking = FALSE;

      break;
  }

  RecordingFlags = GET_FE_RECORDING_FLAGS (FileEntryData);
  switch (RecordingFlags) {
    case InlineData:
      //
      // There are no extents for this FE/EFE. All data is inline.
      //
      Status = GetFileEntryData (FileEntryData, Volume->FileEntrySize, &Data, &Length);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      if (ReadFileInfo->Flags == ReadFileGetFileSize) {
        ReadFileInfo->ReadLength = Length;
      } else if (ReadFileInfo->Flags == ReadFileAllocateAndRead) {
        //
        // Allocate buffer for starting read data.
        //
        ReadFileInfo->FileData = AllocatePool ((UINTN)Length);
        if (ReadFileInfo->FileData == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }

        //
        // Read all inline data into ReadFileInfo->FileData
        //
        CopyMem (ReadFileInfo->FileData, Data, (UINTN)Length);
        ReadFileInfo->ReadLength = Length;
      } else if (ReadFileInfo->Flags == ReadFileSeekAndRead) {
        //
        // If FilePosition is non-zero, seek file to FilePosition, read
        // FileDataSize bytes and then updates FilePosition.
        //
        CopyMem (
          ReadFileInfo->FileData,
          (VOID *)((UINT8 *)Data + ReadFileInfo->FilePosition),
          (UINTN)ReadFileInfo->FileDataSize
          );

        ReadFileInfo->FilePosition += ReadFileInfo->FileDataSize;
      } else {
        ASSERT (FALSE);
        return EFI_INVALID_PARAMETER;
      }

      Status = EFI_SUCCESS;
      break;

    case LongAdsSequence:
    case ShortAdsSequence:
      //
      // This FE/EFE contains a run of Allocation Descriptors. Get data + size
      // for start reading them out.
      //
      Status = GetAdsInformation (FileEntryData, Volume->FileEntrySize, &Data, &Length);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      AdOffset = 0;

      for ( ; ;) {
        //
        // Read AD.
        //
        Status = GetAllocationDescriptor (
                   RecordingFlags,
                   Data,
                   &AdOffset,
                   Length,
                   &Ad
                   );
        if (Status == EFI_DEVICE_ERROR) {
          Status = EFI_SUCCESS;
          goto Done;
        }

        //
        // Check if AD is an indirect AD. If so, read Allocation Extent
        // Descriptor and its extents (ADs).
        //
        if (GET_EXTENT_FLAGS (RecordingFlags, Ad) == ExtentIsNextExtent) {
          DataBak = Data;
          Status  = GetAedAdsData (
                      BlockIo,
                      DiskIo,
                      Volume,
                      ParentIcb,
                      RecordingFlags,
                      Ad,
                      &Data,
                      &Length
                      );

          if (!DoFreeAed) {
            DoFreeAed = TRUE;
          } else {
            FreePool (DataBak);
          }

          if (EFI_ERROR (Status)) {
            goto Error_Get_Aed;
          }

          ASSERT (Data != NULL);

          AdOffset = 0;
          continue;
        }

        ExtentLength = GET_EXTENT_LENGTH (RecordingFlags, Ad);

        Status = GetAllocationDescriptorLsn (
                   RecordingFlags,
                   Volume,
                   ParentIcb,
                   Ad,
                   &Lsn
                   );
        if (EFI_ERROR (Status)) {
          goto Done;
        }

        switch (ReadFileInfo->Flags) {
          case ReadFileGetFileSize:
            ReadFileInfo->ReadLength += ExtentLength;
            break;
          case ReadFileAllocateAndRead:
            //
            // Increase FileData (if necessary) to read next extent.
            //
            Status = GrowUpBufferToNextAd (
                       RecordingFlags,
                       Ad,
                       &ReadFileInfo->FileData,
                       ReadFileInfo->ReadLength
                       );
            if (EFI_ERROR (Status)) {
              goto Error_Alloc_Buffer_To_Next_Ad;
            }

            //
            // Read extent's data into FileData.
            //
            Status = DiskIo->ReadDisk (
                               DiskIo,
                               BlockIo->Media->MediaId,
                               MultU64x32 (Lsn, LogicalBlockSize),
                               ExtentLength,
                               (VOID *)((UINT8 *)ReadFileInfo->FileData +
                                        ReadFileInfo->ReadLength)
                               );
            if (EFI_ERROR (Status)) {
              goto Error_Read_Disk_Blk;
            }

            ReadFileInfo->ReadLength += ExtentLength;
            break;
          case ReadFileSeekAndRead:
            //
            // Seek file first before reading in its data.
            //
            if (FinishedSeeking) {
              Offset = 0;
              goto Skip_File_Seek;
            }

            if (FilePosition + ExtentLength < ReadFileInfo->FilePosition) {
              FilePosition += ExtentLength;
              goto Skip_Ad;
            }

            if (FilePosition + ExtentLength > ReadFileInfo->FilePosition) {
              Offset = ReadFileInfo->FilePosition - FilePosition;
            } else {
              Offset = 0;
            }

            //
            // Done with seeking file. Start reading its data.
            //
            FinishedSeeking = TRUE;

Skip_File_Seek:
            //
            // Make sure we don't read more data than really wanted.
            //
            if (ExtentLength - Offset > BytesLeft) {
              DataLength = BytesLeft;
            } else {
              DataLength = ExtentLength - Offset;
            }

            //
            // Read extent's data into FileData.
            //
            Status = DiskIo->ReadDisk (
                               DiskIo,
                               BlockIo->Media->MediaId,
                               Offset + MultU64x32 (Lsn, LogicalBlockSize),
                               (UINTN)DataLength,
                               (VOID *)((UINT8 *)ReadFileInfo->FileData +
                                        DataOffset)
                               );
            if (EFI_ERROR (Status)) {
              goto Error_Read_Disk_Blk;
            }

            //
            // Update current file's position.
            //
            DataOffset                 += DataLength;
            ReadFileInfo->FilePosition += DataLength;

            BytesLeft -= DataLength;
            if (BytesLeft == 0) {
              //
              // There is no more file data to read.
              //
              Status = EFI_SUCCESS;
              goto Done;
            }

            break;
        }

Skip_Ad:
        //
        // Point to the next AD (extent).
        //
        AdOffset += AD_LENGTH (RecordingFlags);
      }

      break;
    case ExtendedAdsSequence:
      // FIXME: Not supported. Got no volume with it, yet.
      ASSERT (FALSE);
      Status = EFI_UNSUPPORTED;
      break;

    default:
      //
      // A flag value reserved by the ECMA-167 standard (3rd Edition - June
      // 1997); 14.6 ICB Tag; 14.6.8 Flags (RBP 18); was found.
      //
      Status = EFI_UNSUPPORTED;
      break;
  }

Done:
  if (DoFreeAed) {
    FreePool (Data);
  }

  return Status;

Error_Read_Disk_Blk:
Error_Alloc_Buffer_To_Next_Ad:
  if (ReadFileInfo->Flags != ReadFileSeekAndRead) {
    FreePool (ReadFileInfo->FileData);
  }

  if (DoFreeAed) {
    FreePool (Data);
  }

Error_Get_Aed:
  return Status;
}

/**
  Find a file by its filename from a given Parent file.

  @param[in]  BlockIo             BlockIo interface.
  @param[in]  DiskIo              DiskIo interface.
  @param[in]  Volume              Volume information pointer.
  @param[in]  FileName            File name string.
  @param[in]  Parent              Parent directory file.
  @param[in]  Icb                 Long Allocation Descriptor pointer.
  @param[out] File                Found file.

  @retval EFI_SUCCESS             The file was found.
  @retval EFI_INVALID_PARAMETER   One or more input parameters are invalid.
  @retval EFI_NOT_FOUND           The file was not found.

**/
EFI_STATUS
InternalFindFile (
  IN   EFI_BLOCK_IO_PROTOCOL           *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL            *DiskIo,
  IN   UDF_VOLUME_INFO                 *Volume,
  IN   CHAR16                          *FileName,
  IN   UDF_FILE_INFO                   *Parent,
  IN   UDF_LONG_ALLOCATION_DESCRIPTOR  *Icb,
  OUT  UDF_FILE_INFO                   *File
  )
{
  EFI_STATUS                      Status;
  UDF_FILE_IDENTIFIER_DESCRIPTOR  *FileIdentifierDesc;
  UDF_READ_DIRECTORY_INFO         ReadDirInfo;
  BOOLEAN                         Found;
  CHAR16                          FoundFileName[UDF_FILENAME_LENGTH];
  VOID                            *CompareFileEntry;

  //
  // Check if both Parent->FileIdentifierDesc and Icb are NULL.
  //
  if ((Parent->FileIdentifierDesc == NULL) && (Icb == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check if parent file is really directory.
  //
  if (FE_ICB_FILE_TYPE (Parent->FileEntry) != UdfFileEntryDirectory) {
    return EFI_NOT_FOUND;
  }

  //
  // If FileName is current file or working directory, just duplicate Parent's
  // FE/EFE and FID descriptors.
  //
  if (StrCmp (FileName, L".") == 0) {
    if (Parent->FileIdentifierDesc == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    DuplicateFe (BlockIo, Volume, Parent->FileEntry, &File->FileEntry);
    if (File->FileEntry == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    DuplicateFid (Parent->FileIdentifierDesc, &File->FileIdentifierDesc);
    if (File->FileIdentifierDesc == NULL) {
      FreePool (File->FileEntry);
      return EFI_OUT_OF_RESOURCES;
    }

    return EFI_SUCCESS;
  }

  //
  // Start directory listing.
  //
  ZeroMem ((VOID *)&ReadDirInfo, sizeof (UDF_READ_DIRECTORY_INFO));
  Found = FALSE;

  for ( ; ;) {
    Status = ReadDirectoryEntry (
               BlockIo,
               DiskIo,
               Volume,
               (Parent->FileIdentifierDesc != NULL) ?
               &Parent->FileIdentifierDesc->Icb :
               Icb,
               Parent->FileEntry,
               &ReadDirInfo,
               &FileIdentifierDesc
               );
    if (EFI_ERROR (Status)) {
      if (Status == EFI_DEVICE_ERROR) {
        Status = EFI_NOT_FOUND;
      }

      break;
    }

    //
    // After calling function ReadDirectoryEntry(), if 'FileIdentifierDesc' is
    // NULL, then the 'Status' must be EFI_OUT_OF_RESOURCES. Hence, if the code
    // reaches here, 'FileIdentifierDesc' must be not NULL.
    //
    // The ASSERT here is for addressing a false positive NULL pointer
    // dereference issue raised from static analysis.
    //
    ASSERT (FileIdentifierDesc != NULL);

    if (FileIdentifierDesc->FileCharacteristics & PARENT_FILE) {
      //
      // This FID contains the location (FE/EFE) of the parent directory of this
      // directory (Parent), and if FileName is either ".." or "\\", then it's
      // the expected FID.
      //
      if ((StrCmp (FileName, L"..") == 0) || (StrCmp (FileName, L"\\") == 0)) {
        Found = TRUE;
        break;
      }
    } else {
      Status = GetFileNameFromFid (FileIdentifierDesc, ARRAY_SIZE (FoundFileName), FoundFileName);
      if (EFI_ERROR (Status)) {
        break;
      }

      if (StrCmp (FileName, FoundFileName) == 0) {
        //
        // FID has been found. Prepare to find its respective FE/EFE.
        //
        Found = TRUE;
        break;
      }
    }

    FreePool ((VOID *)FileIdentifierDesc);
  }

  if (ReadDirInfo.DirectoryData != NULL) {
    //
    // Free all allocated resources for the directory listing.
    //
    FreePool (ReadDirInfo.DirectoryData);
  }

  if (Found) {
    Status = EFI_SUCCESS;

    File->FileIdentifierDesc = FileIdentifierDesc;

    //
    // If the requested file is root directory, then the FE/EFE was already
    // retrieved in UdfOpenVolume() function, thus no need to find it again.
    //
    // Otherwise, find FE/EFE from the respective FID.
    //
    if (StrCmp (FileName, L"\\") != 0) {
      Status = FindFileEntry (
                 BlockIo,
                 DiskIo,
                 Volume,
                 &FileIdentifierDesc->Icb,
                 &CompareFileEntry
                 );
      if (EFI_ERROR (Status)) {
        goto Error_Find_Fe;
      }

      //
      // Make sure that both Parent's FE/EFE and found FE/EFE are not equal.
      //
      if (CompareMem (
            (VOID *)Parent->FileEntry,
            (VOID *)CompareFileEntry,
            Volume->FileEntrySize
            ) != 0)
      {
        File->FileEntry = CompareFileEntry;
      } else {
        FreePool ((VOID *)FileIdentifierDesc);
        FreePool ((VOID *)CompareFileEntry);
        Status = EFI_NOT_FOUND;
      }
    }
  }

  return Status;

Error_Find_Fe:
  FreePool ((VOID *)FileIdentifierDesc);

  return Status;
}

/**
  Read volume information on a medium which contains a valid UDF file system.

  @param[in]   BlockIo  BlockIo interface.
  @param[in]   DiskIo   DiskIo interface.
  @param[out]  Volume   UDF volume information structure.

  @retval EFI_SUCCESS          Volume information read.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_OUT_OF_RESOURCES The volume was not read due to lack of resources.

**/
EFI_STATUS
ReadUdfVolumeInformation (
  IN   EFI_BLOCK_IO_PROTOCOL  *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL   *DiskIo,
  OUT  UDF_VOLUME_INFO        *Volume
  )
{
  EFI_STATUS  Status;

  //
  // Read all necessary UDF volume information and keep it private to the driver
  //
  Status = ReadVolumeFileStructure (
             BlockIo,
             DiskIo,
             Volume
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Find File Set Descriptor
  //
  Status = FindFileSetDescriptor (BlockIo, DiskIo, Volume);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return Status;
}

/**
  Find the root directory on an UDF volume.

  @param[in]   BlockIo  BlockIo interface.
  @param[in]   DiskIo   DiskIo interface.
  @param[in]   Volume   UDF volume information structure.
  @param[out]  File     Root directory file.

  @retval EFI_SUCCESS          Root directory found.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_OUT_OF_RESOURCES The root directory was not found due to lack of
                               resources.

**/
EFI_STATUS
FindRootDirectory (
  IN   EFI_BLOCK_IO_PROTOCOL  *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL   *DiskIo,
  IN   UDF_VOLUME_INFO        *Volume,
  OUT  UDF_FILE_INFO          *File
  )
{
  EFI_STATUS     Status;
  UDF_FILE_INFO  Parent;

  Status = FindFileEntry (
             BlockIo,
             DiskIo,
             Volume,
             &Volume->FileSetDesc.RootDirectoryIcb,
             &File->FileEntry
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Parent.FileEntry          = File->FileEntry;
  Parent.FileIdentifierDesc = NULL;

  Status = FindFile (
             BlockIo,
             DiskIo,
             Volume,
             L"\\",
             NULL,
             &Parent,
             &Volume->FileSetDesc.RootDirectoryIcb,
             File
             );
  if (EFI_ERROR (Status)) {
    FreePool (File->FileEntry);
  }

  return Status;
}

/**
  Find either a File Entry or a Extended File Entry from a given ICB.

  @param[in]   BlockIo    BlockIo interface.
  @param[in]   DiskIo     DiskIo interface.
  @param[in]   Volume     UDF volume information structure.
  @param[in]   Icb        ICB of the FID.
  @param[out]  FileEntry  File Entry or Extended File Entry.

  @retval EFI_SUCCESS          File Entry or Extended File Entry found.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_OUT_OF_RESOURCES The FE/EFE entry was not found due to lack of
                               resources.

**/
EFI_STATUS
FindFileEntry (
  IN   EFI_BLOCK_IO_PROTOCOL           *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL            *DiskIo,
  IN   UDF_VOLUME_INFO                 *Volume,
  IN   UDF_LONG_ALLOCATION_DESCRIPTOR  *Icb,
  OUT  VOID                            **FileEntry
  )
{
  EFI_STATUS          Status;
  UINT64              Lsn;
  UINT32              LogicalBlockSize;
  UDF_DESCRIPTOR_TAG  *DescriptorTag;
  VOID                *ReadBuffer;

  Status = GetLongAdLsn (Volume, Icb, &Lsn);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  LogicalBlockSize = Volume->LogicalVolDesc.LogicalBlockSize;

  ReadBuffer = AllocateZeroPool (Volume->FileEntrySize);
  if (ReadBuffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Read extent.
  //
  Status = DiskIo->ReadDisk (
                     DiskIo,
                     BlockIo->Media->MediaId,
                     MultU64x32 (Lsn, LogicalBlockSize),
                     Volume->FileEntrySize,
                     ReadBuffer
                     );
  if (EFI_ERROR (Status)) {
    goto Error_Read_Disk_Blk;
  }

  DescriptorTag = ReadBuffer;

  //
  // Check if the read extent contains a valid Tag Identifier for the expected
  // FE/EFE.
  //
  if ((DescriptorTag->TagIdentifier != UdfFileEntry) &&
      (DescriptorTag->TagIdentifier != UdfExtendedFileEntry))
  {
    Status = EFI_VOLUME_CORRUPTED;
    goto Error_Invalid_Fe;
  }

  *FileEntry = ReadBuffer;
  return EFI_SUCCESS;

Error_Invalid_Fe:
Error_Read_Disk_Blk:
  FreePool (ReadBuffer);

  return Status;
}

/**
  Find a file given its absolute path on an UDF volume.

  @param[in]   BlockIo   BlockIo interface.
  @param[in]   DiskIo    DiskIo interface.
  @param[in]   Volume    UDF volume information structure.
  @param[in]   FilePath  File's absolute path.
  @param[in]   Root      Root directory file.
  @param[in]   Parent    Parent directory file.
  @param[in]   Icb       ICB of Parent.
  @param[out]  File      Found file.

  @retval EFI_SUCCESS          FilePath was found.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_OUT_OF_RESOURCES The FilePath file was not found due to lack of
                               resources.

**/
EFI_STATUS
FindFile (
  IN   EFI_BLOCK_IO_PROTOCOL           *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL            *DiskIo,
  IN   UDF_VOLUME_INFO                 *Volume,
  IN   CHAR16                          *FilePath,
  IN   UDF_FILE_INFO                   *Root,
  IN   UDF_FILE_INFO                   *Parent,
  IN   UDF_LONG_ALLOCATION_DESCRIPTOR  *Icb,
  OUT  UDF_FILE_INFO                   *File
  )
{
  EFI_STATUS     Status;
  CHAR16         FileName[UDF_FILENAME_LENGTH];
  CHAR16         *FileNamePointer;
  UDF_FILE_INFO  PreviousFile;
  VOID           *FileEntry;

  Status = EFI_NOT_FOUND;

  CopyMem ((VOID *)&PreviousFile, (VOID *)Parent, sizeof (UDF_FILE_INFO));
  while (*FilePath != L'\0') {
    FileNamePointer = FileName;
    while (*FilePath != L'\0' && *FilePath != L'\\') {
      if ((((UINTN)FileNamePointer - (UINTN)FileName) / sizeof (CHAR16)) >=
          (ARRAY_SIZE (FileName) - 1))
      {
        return EFI_NOT_FOUND;
      }

      *FileNamePointer++ = *FilePath++;
    }

    *FileNamePointer = L'\0';
    if (FileName[0] == L'\0') {
      //
      // Open root directory.
      //
      if (Root == NULL) {
        //
        // There is no file found for the root directory yet. So, find only its
        // FID by now.
        //
        // See UdfOpenVolume() function.
        //
        Status = InternalFindFile (
                   BlockIo,
                   DiskIo,
                   Volume,
                   L"\\",
                   &PreviousFile,
                   Icb,
                   File
                   );
      } else {
        //
        // We've already a file pointer (Root) for the root directory. Duplicate
        // its FE/EFE and FID descriptors.
        //
        Status = EFI_SUCCESS;
        DuplicateFe (BlockIo, Volume, Root->FileEntry, &File->FileEntry);
        if (File->FileEntry == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
        } else {
          //
          // File->FileEntry is not NULL.
          //
          DuplicateFid (Root->FileIdentifierDesc, &File->FileIdentifierDesc);
          if (File->FileIdentifierDesc == NULL) {
            FreePool (File->FileEntry);
            Status = EFI_OUT_OF_RESOURCES;
          }
        }
      }
    } else {
      //
      // No root directory. Find filename from the current directory.
      //
      Status = InternalFindFile (
                 BlockIo,
                 DiskIo,
                 Volume,
                 FileName,
                 &PreviousFile,
                 Icb,
                 File
                 );
    }

    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // If the found file is a symlink, then find its respective FE/EFE and
    // FID descriptors.
    //
    if (FE_ICB_FILE_TYPE (File->FileEntry) == UdfFileEntrySymlink) {
      FreePool ((VOID *)File->FileIdentifierDesc);

      FileEntry = File->FileEntry;

      Status = ResolveSymlink (
                 BlockIo,
                 DiskIo,
                 Volume,
                 &PreviousFile,
                 FileEntry,
                 File
                 );

      FreePool (FileEntry);

      if (EFI_ERROR (Status)) {
        return Status;
      }
    }

    if (CompareMem (
          (VOID *)&PreviousFile,
          (VOID *)Parent,
          sizeof (UDF_FILE_INFO)
          ) != 0)
    {
      CleanupFileInformation (&PreviousFile);
    }

    CopyMem ((VOID *)&PreviousFile, (VOID *)File, sizeof (UDF_FILE_INFO));
    if ((*FilePath != L'\0') && (*FilePath == L'\\')) {
      FilePath++;
    }
  }

  return Status;
}

/**
  Read a directory entry at a time on an UDF volume.

  @param[in]      BlockIo        BlockIo interface.
  @param[in]      DiskIo         DiskIo interface.
  @param[in]      Volume         UDF volume information structure.
  @param[in]      ParentIcb      ICB of the parent file.
  @param[in]      FileEntryData  FE/EFE of the parent file.
  @param[in, out] ReadDirInfo    Next read directory listing structure
                                 information.
  @param[out]     FoundFid       File Identifier Descriptor pointer.

  @retval EFI_SUCCESS          Directory entry read.
  @retval EFI_UNSUPPORTED      Extended Allocation Descriptors not supported.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_OUT_OF_RESOURCES The directory entry was not read due to lack of
                               resources.

**/
EFI_STATUS
ReadDirectoryEntry (
  IN      EFI_BLOCK_IO_PROTOCOL           *BlockIo,
  IN      EFI_DISK_IO_PROTOCOL            *DiskIo,
  IN      UDF_VOLUME_INFO                 *Volume,
  IN      UDF_LONG_ALLOCATION_DESCRIPTOR  *ParentIcb,
  IN      VOID                            *FileEntryData,
  IN OUT  UDF_READ_DIRECTORY_INFO         *ReadDirInfo,
  OUT     UDF_FILE_IDENTIFIER_DESCRIPTOR  **FoundFid
  )
{
  EFI_STATUS                      Status;
  UDF_READ_FILE_INFO              ReadFileInfo;
  UDF_FILE_IDENTIFIER_DESCRIPTOR  *FileIdentifierDesc;

  if (ReadDirInfo->DirectoryData == NULL) {
    //
    // The directory's recorded data has not been read yet. So let's cache it
    // into memory and the next calls won't need to read it again.
    //
    ReadFileInfo.Flags = ReadFileAllocateAndRead;

    Status = ReadFile (
               BlockIo,
               DiskIo,
               Volume,
               ParentIcb,
               FileEntryData,
               &ReadFileInfo
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Fill in ReadDirInfo structure with the read directory's data information.
    //
    ReadDirInfo->DirectoryData   = ReadFileInfo.FileData;
    ReadDirInfo->DirectoryLength = ReadFileInfo.ReadLength;
  }

  do {
    if (ReadDirInfo->FidOffset >= ReadDirInfo->DirectoryLength) {
      //
      // There are no longer FIDs for this directory. By returning
      // EFI_DEVICE_ERROR to the callee will indicate end of directory
      // listening.
      //
      return EFI_DEVICE_ERROR;
    }

    //
    // Get FID for this entry.
    //
    FileIdentifierDesc = GET_FID_FROM_ADS (
                           ReadDirInfo->DirectoryData,
                           ReadDirInfo->FidOffset
                           );
    //
    // Update FidOffset to point to next FID.
    //
    ReadDirInfo->FidOffset += GetFidDescriptorLength (FileIdentifierDesc);
  } while (FileIdentifierDesc->FileCharacteristics & DELETED_FILE);

  DuplicateFid (FileIdentifierDesc, FoundFid);
  if (*FoundFid == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  Get a filename (encoded in OSTA-compressed format) from a File Identifier
  Descriptor on an UDF volume.

  @attention This is boundary function that may receive untrusted input.
  @attention The input is from FileSystem.

  The File Identifier Descriptor is external input, so this routine will do
  basic validation for File Identifier Descriptor and report status.

  @param[in]   FileIdentifierDesc  File Identifier Descriptor pointer.
  @param[in]   CharMax             The maximum number of FileName Unicode char,
                                   including terminating null char.
  @param[out]  FileName            Decoded filename.

  @retval EFI_SUCCESS           Filename decoded and read.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_BUFFER_TOO_SMALL  The string buffer FileName cannot hold the
                                decoded filename.
**/
EFI_STATUS
GetFileNameFromFid (
  IN   UDF_FILE_IDENTIFIER_DESCRIPTOR  *FileIdentifierDesc,
  IN   UINTN                           CharMax,
  OUT  CHAR16                          *FileName
  )
{
  UINT8   *OstaCompressed;
  UINT8   CompressionId;
  UINT8   Length;
  UINTN   Index;
  CHAR16  *FileNameBak;

  if (CharMax == 0) {
    return EFI_BUFFER_TOO_SMALL;
  }

  OstaCompressed =
    (UINT8 *)(
              (UINT8 *)FileIdentifierDesc->Data +
              FileIdentifierDesc->LengthOfImplementationUse
              );

  CompressionId = OstaCompressed[0];
  if (!IS_VALID_COMPRESSION_ID (CompressionId)) {
    return EFI_VOLUME_CORRUPTED;
  }

  FileNameBak = FileName;

  //
  // Decode filename.
  //
  Length = FileIdentifierDesc->LengthOfFileIdentifier;
  if (CompressionId == 16) {
    if (((UINTN)Length >> 1) > CharMax) {
      return EFI_BUFFER_TOO_SMALL;
    }
  } else {
    if ((Length != 0) && ((UINTN)Length - 1 > CharMax)) {
      return EFI_BUFFER_TOO_SMALL;
    }
  }

  for (Index = 1; Index < Length; Index++) {
    if (CompressionId == 16) {
      *FileName = OstaCompressed[Index++] << 8;
    } else {
      *FileName = 0;
    }

    if (Index < Length) {
      *FileName |= (CHAR16)(OstaCompressed[Index]);
    }

    FileName++;
  }

  Index = ((UINTN)FileName - (UINTN)FileNameBak) / sizeof (CHAR16);
  if (Index > CharMax - 1) {
    Index = CharMax - 1;
  }

  FileNameBak[Index] = L'\0';

  return EFI_SUCCESS;
}

/**
  Resolve a symlink file on an UDF volume.

  @attention This is boundary function that may receive untrusted input.
  @attention The input is from FileSystem.

  The Path Component is external input, so this routine will do basic
  validation for Path Component and report status.

  @param[in]   BlockIo        BlockIo interface.
  @param[in]   DiskIo         DiskIo interface.
  @param[in]   Volume         UDF volume information structure.
  @param[in]   Parent         Parent file.
  @param[in]   FileEntryData  FE/EFE structure pointer.
  @param[out]  File           Resolved file.

  @retval EFI_SUCCESS          Symlink file resolved.
  @retval EFI_UNSUPPORTED      Extended Allocation Descriptors not supported.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_OUT_OF_RESOURCES The symlink file was not resolved due to lack of
                               resources.

**/
EFI_STATUS
ResolveSymlink (
  IN   EFI_BLOCK_IO_PROTOCOL  *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL   *DiskIo,
  IN   UDF_VOLUME_INFO        *Volume,
  IN   UDF_FILE_INFO          *Parent,
  IN   VOID                   *FileEntryData,
  OUT  UDF_FILE_INFO          *File
  )
{
  EFI_STATUS          Status;
  UDF_READ_FILE_INFO  ReadFileInfo;
  UINT8               *Data;
  UINT64              Length;
  UINT8               *EndData;
  UDF_PATH_COMPONENT  *PathComp;
  UINT8               PathCompLength;
  CHAR16              FileName[UDF_FILENAME_LENGTH];
  CHAR16              *Char;
  UINTN               Index;
  UINT8               CompressionId;
  UDF_FILE_INFO       PreviousFile;
  BOOLEAN             NotParent;
  BOOLEAN             NotFile;

  ZeroMem ((VOID *)File, sizeof (UDF_FILE_INFO));

  //
  // Symlink files on UDF volumes do not contain so much data other than
  // Path Components which resolves to real filenames, so it's OK to read in
  // all its data here -- usually the data will be inline with the FE/EFE for
  // lower filenames.
  //
  ReadFileInfo.Flags = ReadFileAllocateAndRead;

  Status = ReadFile (
             BlockIo,
             DiskIo,
             Volume,
             &Parent->FileIdentifierDesc->Icb,
             FileEntryData,
             &ReadFileInfo
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Length = ReadFileInfo.ReadLength;

  Data    = (UINT8 *)ReadFileInfo.FileData;
  EndData = Data + Length;

  CopyMem ((VOID *)&PreviousFile, (VOID *)Parent, sizeof (UDF_FILE_INFO));

  for ( ; ;) {
    PathComp = (UDF_PATH_COMPONENT *)Data;

    PathCompLength = PathComp->LengthOfComponentIdentifier;

    switch (PathComp->ComponentType) {
      case 1:
      //
      // This Path Component specifies the root directory hierarchy subject to
      // agreement between the originator and recipient of the medium. Skip it.
      //
      // Fall through.
      //
      case 2:
        //
        // "\\." of the current directory. Read next Path Component.
        //
        goto Next_Path_Component;
      case 3:
        //
        // ".." (parent directory). Go to it.
        //
        CopyMem ((VOID *)FileName, L"..", 6);
        break;
      case 4:
        //
        // "." (current file). Duplicate both FE/EFE and FID of this file.
        //
        DuplicateFe (BlockIo, Volume, PreviousFile.FileEntry, &File->FileEntry);
        if (File->FileEntry == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto Error_Find_File;
        }

        DuplicateFid (
          PreviousFile.FileIdentifierDesc,
          &File->FileIdentifierDesc
          );
        if (File->FileIdentifierDesc == NULL) {
          FreePool (File->FileEntry);
          Status = EFI_OUT_OF_RESOURCES;
          goto Error_Find_File;
        }

        goto Next_Path_Component;
      case 5:
        //
        // This Path Component identifies an object, either a file or a
        // directory or an alias.
        //
        // Decode it from the compressed data in ComponentIdentifier and find
        // respective path.
        //
        CompressionId = PathComp->ComponentIdentifier[0];
        if (!IS_VALID_COMPRESSION_ID (CompressionId)) {
          return EFI_VOLUME_CORRUPTED;
        }

        if ((UINTN)PathComp->ComponentIdentifier + PathCompLength > (UINTN)EndData) {
          return EFI_VOLUME_CORRUPTED;
        }

        Char = FileName;
        for (Index = 1; Index < PathCompLength; Index++) {
          if (CompressionId == 16) {
            *Char = *(UINT8 *)((UINT8 *)PathComp->ComponentIdentifier +
                               Index) << 8;
            Index++;
          } else {
            if (Index > ARRAY_SIZE (FileName)) {
              return EFI_UNSUPPORTED;
            }

            *Char = 0;
          }

          if (Index < Length) {
            *Char |= (CHAR16)(*(UINT8 *)((UINT8 *)PathComp->ComponentIdentifier + Index));
          }

          Char++;
        }

        Index = ((UINTN)Char - (UINTN)FileName) / sizeof (CHAR16);
        if (Index > ARRAY_SIZE (FileName) - 1) {
          Index = ARRAY_SIZE (FileName) - 1;
        }

        FileName[Index] = L'\0';
        break;
      default:
        //
        // According to the ECMA-167 standard (3rd Edition - June 1997), Section
        // 14.16.1.1, all other values are reserved.
        //
        Status = EFI_VOLUME_CORRUPTED;
        goto Error_Find_File;
    }

    //
    // Find file from the read filename in symlink's file data.
    //
    Status = InternalFindFile (
               BlockIo,
               DiskIo,
               Volume,
               FileName,
               &PreviousFile,
               NULL,
               File
               );
    if (EFI_ERROR (Status)) {
      goto Error_Find_File;
    }

Next_Path_Component:
    Data += sizeof (UDF_PATH_COMPONENT) + PathCompLength;
    if (Data >= EndData) {
      break;
    }

    //
    // Check the content in the file info pointed by File.
    //
    if ((File->FileEntry == NULL) || (File->FileIdentifierDesc == NULL)) {
      Status = EFI_VOLUME_CORRUPTED;
      goto Error_Find_File;
    }

    NotParent = (CompareMem (
                   (VOID *)&PreviousFile,
                   (VOID *)Parent,
                   sizeof (UDF_FILE_INFO)
                   ) != 0);
    NotFile = (CompareMem (
                 (VOID *)&PreviousFile,
                 (VOID *)File,
                 sizeof (UDF_FILE_INFO)
                 ) != 0);

    if (NotParent && NotFile) {
      CleanupFileInformation (&PreviousFile);
    }

    if (NotFile) {
      CopyMem ((VOID *)&PreviousFile, (VOID *)File, sizeof (UDF_FILE_INFO));
    }
  }

  //
  // Unmap the symlink file.
  //
  FreePool (ReadFileInfo.FileData);

  //
  // Check the content in the resolved file info.
  //
  if ((File->FileEntry == NULL) || (File->FileIdentifierDesc == NULL)) {
    return EFI_VOLUME_CORRUPTED;
  }

  return EFI_SUCCESS;

Error_Find_File:
  if (CompareMem (
        (VOID *)&PreviousFile,
        (VOID *)Parent,
        sizeof (UDF_FILE_INFO)
        ) != 0)
  {
    CleanupFileInformation (&PreviousFile);
  }

  FreePool (ReadFileInfo.FileData);

  return Status;
}

/**
  Clean up in-memory UDF file information.

  @param[in] File File information pointer.

**/
VOID
CleanupFileInformation (
  IN UDF_FILE_INFO  *File
  )
{
  if (File->FileEntry != NULL) {
    FreePool (File->FileEntry);
  }

  if (File->FileIdentifierDesc != NULL) {
    FreePool ((VOID *)File->FileIdentifierDesc);
  }

  ZeroMem ((VOID *)File, sizeof (UDF_FILE_INFO));
}

/**
  Find a file from its absolute path on an UDF volume.

  @param[in]   BlockIo  BlockIo interface.
  @param[in]   DiskIo   DiskIo interface.
  @param[in]   Volume   UDF volume information structure.
  @param[in]   File     File information structure.
  @param[out]  Size     Size of the file.

  @retval EFI_SUCCESS          File size calculated and set in Size.
  @retval EFI_UNSUPPORTED      Extended Allocation Descriptors not supported.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_OUT_OF_RESOURCES The file size was not calculated due to lack of
                               resources.

**/
EFI_STATUS
GetFileSize (
  IN   EFI_BLOCK_IO_PROTOCOL  *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL   *DiskIo,
  IN   UDF_VOLUME_INFO        *Volume,
  IN   UDF_FILE_INFO          *File,
  OUT  UINT64                 *Size
  )
{
  EFI_STATUS          Status;
  UDF_READ_FILE_INFO  ReadFileInfo;

  ReadFileInfo.Flags = ReadFileGetFileSize;

  Status = ReadFile (
             BlockIo,
             DiskIo,
             Volume,
             &File->FileIdentifierDesc->Icb,
             File->FileEntry,
             &ReadFileInfo
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  *Size = ReadFileInfo.ReadLength;

  return EFI_SUCCESS;
}

/**
  Set information about a file on an UDF volume.

  @param[in]      File        File pointer.
  @param[in]      FileSize    Size of the file.
  @param[in]      FileName    Filename of the file.
  @param[in, out] BufferSize  Size of the returned file infomation.
  @param[out]     Buffer      Data of the returned file information.

  @retval EFI_SUCCESS          File information set.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_OUT_OF_RESOURCES The file information was not set due to lack of
                               resources.

**/
EFI_STATUS
SetFileInfo (
  IN      UDF_FILE_INFO  *File,
  IN      UINT64         FileSize,
  IN      CHAR16         *FileName,
  IN OUT  UINTN          *BufferSize,
  OUT     VOID           *Buffer
  )
{
  UINTN                    FileInfoLength;
  EFI_FILE_INFO            *FileInfo;
  UDF_FILE_ENTRY           *FileEntry;
  UDF_EXTENDED_FILE_ENTRY  *ExtendedFileEntry;
  UDF_DESCRIPTOR_TAG       *DescriptorTag;

  //
  // Calculate the needed size for the EFI_FILE_INFO structure.
  //
  FileInfoLength = sizeof (EFI_FILE_INFO) + ((FileName != NULL) ?
                                             StrSize (FileName) :
                                             sizeof (CHAR16));
  if (*BufferSize < FileInfoLength) {
    //
    // The given Buffer has no size enough for EFI_FILE_INFO structure.
    //
    *BufferSize = FileInfoLength;
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Buffer now contains room enough to store EFI_FILE_INFO structure.
  // Now, fill it in with all necessary information about the file.
  //
  FileInfo             = (EFI_FILE_INFO *)Buffer;
  FileInfo->Size       = FileInfoLength;
  FileInfo->Attribute &= ~EFI_FILE_VALID_ATTR;
  FileInfo->Attribute |= EFI_FILE_READ_ONLY;

  if (IS_FID_DIRECTORY_FILE (File->FileIdentifierDesc)) {
    FileInfo->Attribute |= EFI_FILE_DIRECTORY;
  } else if (IS_FID_NORMAL_FILE (File->FileIdentifierDesc)) {
    FileInfo->Attribute |= EFI_FILE_ARCHIVE;
  }

  if (IS_FID_HIDDEN_FILE (File->FileIdentifierDesc)) {
    FileInfo->Attribute |= EFI_FILE_HIDDEN;
  }

  DescriptorTag = File->FileEntry;

  if (DescriptorTag->TagIdentifier == UdfFileEntry) {
    FileEntry = (UDF_FILE_ENTRY *)File->FileEntry;

    //
    // Check if FE has the system attribute set.
    //
    if (FileEntry->IcbTag.Flags & (1 << 10)) {
      FileInfo->Attribute |= EFI_FILE_SYSTEM;
    }

    FileInfo->FileSize     = FileSize;
    FileInfo->PhysicalSize = FileSize;

    FileInfo->CreateTime.Year       = FileEntry->AccessTime.Year;
    FileInfo->CreateTime.Month      = FileEntry->AccessTime.Month;
    FileInfo->CreateTime.Day        = FileEntry->AccessTime.Day;
    FileInfo->CreateTime.Hour       = FileEntry->AccessTime.Hour;
    FileInfo->CreateTime.Minute     = FileEntry->AccessTime.Minute;
    FileInfo->CreateTime.Second     = FileEntry->AccessTime.Second;
    FileInfo->CreateTime.Nanosecond =
      FileEntry->AccessTime.HundredsOfMicroseconds;

    FileInfo->LastAccessTime.Year =
      FileEntry->AccessTime.Year;
    FileInfo->LastAccessTime.Month =
      FileEntry->AccessTime.Month;
    FileInfo->LastAccessTime.Day =
      FileEntry->AccessTime.Day;
    FileInfo->LastAccessTime.Hour =
      FileEntry->AccessTime.Hour;
    FileInfo->LastAccessTime.Minute =
      FileEntry->AccessTime.Minute;
    FileInfo->LastAccessTime.Second =
      FileEntry->AccessTime.Second;
    FileInfo->LastAccessTime.Nanosecond =
      FileEntry->AccessTime.HundredsOfMicroseconds;
  } else if (DescriptorTag->TagIdentifier == UdfExtendedFileEntry) {
    ExtendedFileEntry = (UDF_EXTENDED_FILE_ENTRY *)File->FileEntry;

    //
    // Check if EFE has the system attribute set.
    //
    if (ExtendedFileEntry->IcbTag.Flags & (1 << 10)) {
      FileInfo->Attribute |= EFI_FILE_SYSTEM;
    }

    FileInfo->FileSize     = FileSize;
    FileInfo->PhysicalSize = FileSize;

    FileInfo->CreateTime.Year       = ExtendedFileEntry->CreationTime.Year;
    FileInfo->CreateTime.Month      = ExtendedFileEntry->CreationTime.Month;
    FileInfo->CreateTime.Day        = ExtendedFileEntry->CreationTime.Day;
    FileInfo->CreateTime.Hour       = ExtendedFileEntry->CreationTime.Hour;
    FileInfo->CreateTime.Minute     = ExtendedFileEntry->CreationTime.Second;
    FileInfo->CreateTime.Second     = ExtendedFileEntry->CreationTime.Second;
    FileInfo->CreateTime.Nanosecond =
      ExtendedFileEntry->AccessTime.HundredsOfMicroseconds;

    FileInfo->LastAccessTime.Year =
      ExtendedFileEntry->AccessTime.Year;
    FileInfo->LastAccessTime.Month =
      ExtendedFileEntry->AccessTime.Month;
    FileInfo->LastAccessTime.Day =
      ExtendedFileEntry->AccessTime.Day;
    FileInfo->LastAccessTime.Hour =
      ExtendedFileEntry->AccessTime.Hour;
    FileInfo->LastAccessTime.Minute =
      ExtendedFileEntry->AccessTime.Minute;
    FileInfo->LastAccessTime.Second =
      ExtendedFileEntry->AccessTime.Second;
    FileInfo->LastAccessTime.Nanosecond =
      ExtendedFileEntry->AccessTime.HundredsOfMicroseconds;
  }

  FileInfo->CreateTime.TimeZone     = EFI_UNSPECIFIED_TIMEZONE;
  FileInfo->CreateTime.Daylight     = EFI_TIME_ADJUST_DAYLIGHT;
  FileInfo->LastAccessTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE;
  FileInfo->LastAccessTime.Daylight = EFI_TIME_ADJUST_DAYLIGHT;

  CopyMem (
    (VOID *)&FileInfo->ModificationTime,
    (VOID *)&FileInfo->LastAccessTime,
    sizeof (EFI_TIME)
    );

  if (FileName != NULL) {
    StrCpyS (FileInfo->FileName, StrLen (FileName) + 1, FileName);
  } else {
    FileInfo->FileName[0] = '\0';
  }

  *BufferSize = FileInfoLength;

  return EFI_SUCCESS;
}

/**
  Get volume label of an UDF volume.

  @attention This is boundary function that may receive untrusted input.
  @attention The input is from FileSystem.

  The File Set Descriptor is external input, so this routine will do basic
  validation for File Set Descriptor and report status.

  @param[in]   Volume   Volume information pointer.
  @param[in]   CharMax  The maximum number of Unicode char in String,
                        including terminating null char.
  @param[out]  String   String buffer pointer to store the volume label.

  @retval EFI_SUCCESS           Volume label is returned.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_BUFFER_TOO_SMALL  The string buffer String cannot hold the
                                volume label.

**/
EFI_STATUS
GetVolumeLabel (
  IN   UDF_VOLUME_INFO  *Volume,
  IN   UINTN            CharMax,
  OUT  CHAR16           *String
  )
{
  UDF_FILE_SET_DESCRIPTOR  *FileSetDesc;
  UINTN                    Index;
  UINT8                    *OstaCompressed;
  UINT8                    CompressionId;
  CHAR16                   *StringBak;

  FileSetDesc = &Volume->FileSetDesc;

  OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0];

  CompressionId = OstaCompressed[0];
  if (!IS_VALID_COMPRESSION_ID (CompressionId)) {
    return EFI_VOLUME_CORRUPTED;
  }

  StringBak = String;
  for (Index = 1; Index < 128; Index++) {
    if (CompressionId == 16) {
      if ((Index >> 1) > CharMax) {
        return EFI_BUFFER_TOO_SMALL;
      }

      *String = *(UINT8 *)(OstaCompressed + Index) << 8;
      Index++;
    } else {
      if (Index > CharMax) {
        return EFI_BUFFER_TOO_SMALL;
      }

      *String = 0;
    }

    if (Index < 128) {
      *String |= (CHAR16)(*(UINT8 *)(OstaCompressed + Index));
    }

    //
    // Unlike FID Identifiers, Logical Volume Identifier is stored in a
    // NULL-terminated OSTA compressed format, so we must check for the NULL
    // character.
    //
    if (*String == L'\0') {
      break;
    }

    String++;
  }

  Index = ((UINTN)String - (UINTN)StringBak) / sizeof (CHAR16);
  if (Index > CharMax - 1) {
    Index = CharMax - 1;
  }

  StringBak[Index] = L'\0';

  return EFI_SUCCESS;
}

/**
  Get volume and free space size information of an UDF volume.

  @attention This is boundary function that may receive untrusted input.
  @attention The input is from FileSystem.

  The Logical Volume Descriptor and the Logical Volume Integrity Descriptor are
  external inputs, so this routine will do basic validation for both descriptors
  and report status.

  @param[in]   BlockIo        BlockIo interface.
  @param[in]   DiskIo         DiskIo interface.
  @param[in]   Volume         UDF volume information structure.
  @param[out]  VolumeSize     Volume size.
  @param[out]  FreeSpaceSize  Free space size.

  @retval EFI_SUCCESS          Volume and free space size calculated.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_OUT_OF_RESOURCES The volume and free space size were not
                               calculated due to lack of resources.

**/
EFI_STATUS
GetVolumeSize (
  IN   EFI_BLOCK_IO_PROTOCOL  *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL   *DiskIo,
  IN   UDF_VOLUME_INFO        *Volume,
  OUT  UINT64                 *VolumeSize,
  OUT  UINT64                 *FreeSpaceSize
  )
{
  EFI_STATUS                     Status;
  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
  UDF_EXTENT_AD                  *ExtentAd;
  UINT64                         Lsn;
  UINT32                         LogicalBlockSize;
  UDF_LOGICAL_VOLUME_INTEGRITY   *LogicalVolInt;
  UDF_DESCRIPTOR_TAG             *DescriptorTag;
  UINTN                          Index;
  UINTN                          Length;
  UINT32                         LsnsNo;

  LogicalVolDesc = &Volume->LogicalVolDesc;

  ExtentAd = &LogicalVolDesc->IntegritySequenceExtent;

  if ((ExtentAd->ExtentLength == 0) ||
      (ExtentAd->ExtentLength < sizeof (UDF_LOGICAL_VOLUME_INTEGRITY)))
  {
    return EFI_VOLUME_CORRUPTED;
  }

  LogicalVolInt = AllocatePool (ExtentAd->ExtentLength);
  if (LogicalVolInt == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Get location of Logical Volume Integrity Descriptor
  //
  Lsn = (UINT64)ExtentAd->ExtentLocation - Volume->MainVdsStartLocation;

  LogicalBlockSize = LogicalVolDesc->LogicalBlockSize;

  //
  // Read disk block
  //
  Status = DiskIo->ReadDisk (
                     DiskIo,
                     BlockIo->Media->MediaId,
                     MultU64x32 (Lsn, LogicalBlockSize),
                     ExtentAd->ExtentLength,
                     LogicalVolInt
                     );
  if (EFI_ERROR (Status)) {
    goto Out_Free;
  }

  DescriptorTag = &LogicalVolInt->DescriptorTag;

  //
  // Check if read block is a Logical Volume Integrity Descriptor
  //
  if (DescriptorTag->TagIdentifier != UdfLogicalVolumeIntegrityDescriptor) {
    Status = EFI_VOLUME_CORRUPTED;
    goto Out_Free;
  }

  if ((LogicalVolInt->NumberOfPartitions > MAX_UINT32 / sizeof (UINT32) / 2) ||
      (LogicalVolInt->NumberOfPartitions * sizeof (UINT32) * 2 >
       ExtentAd->ExtentLength - sizeof (UDF_LOGICAL_VOLUME_INTEGRITY)))
  {
    Status = EFI_VOLUME_CORRUPTED;
    goto Out_Free;
  }

  *VolumeSize    = 0;
  *FreeSpaceSize = 0;

  Length = LogicalVolInt->NumberOfPartitions;
  for (Index = 0; Index < Length; Index += sizeof (UINT32)) {
    LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
    //
    // Check if size is not specified
    //
    if (LsnsNo == 0xFFFFFFFFUL) {
      continue;
    }

    //
    // Accumulate free space size
    //
    *FreeSpaceSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
  }

  Length = LogicalVolInt->NumberOfPartitions * sizeof (UINT32) * 2;
  for ( ; Index < Length; Index += sizeof (UINT32)) {
    LsnsNo = *(UINT32 *)((UINT8 *)LogicalVolInt->Data + Index);
    //
    // Check if size is not specified
    //
    if (LsnsNo == 0xFFFFFFFFUL) {
      continue;
    }

    //
    // Accumulate used volume space
    //
    *VolumeSize += MultU64x32 ((UINT64)LsnsNo, LogicalBlockSize);
  }

  Status = EFI_SUCCESS;

Out_Free:
  //
  // Free Logical Volume Integrity Descriptor
  //
  FreePool (LogicalVolInt);

  return Status;
}

/**
  Seek a file and read its data into memory on an UDF volume.

  @param[in]      BlockIo       BlockIo interface.
  @param[in]      DiskIo        DiskIo interface.
  @param[in]      Volume        UDF volume information structure.
  @param[in]      File          File information structure.
  @param[in]      FileSize      Size of the file.
  @param[in, out] FilePosition  File position.
  @param[in, out] Buffer        File data.
  @param[in, out] BufferSize    Read size.

  @retval EFI_SUCCESS          File seeked and read.
  @retval EFI_UNSUPPORTED      Extended Allocation Descriptors not supported.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_OUT_OF_RESOURCES The file's recorded data was not read due to lack
                               of resources.

**/
EFI_STATUS
ReadFileData (
  IN      EFI_BLOCK_IO_PROTOCOL  *BlockIo,
  IN      EFI_DISK_IO_PROTOCOL   *DiskIo,
  IN      UDF_VOLUME_INFO        *Volume,
  IN      UDF_FILE_INFO          *File,
  IN      UINT64                 FileSize,
  IN OUT  UINT64                 *FilePosition,
  IN OUT  VOID                   *Buffer,
  IN OUT  UINT64                 *BufferSize
  )
{
  EFI_STATUS          Status;
  UDF_READ_FILE_INFO  ReadFileInfo;

  ReadFileInfo.Flags        = ReadFileSeekAndRead;
  ReadFileInfo.FilePosition = *FilePosition;
  ReadFileInfo.FileData     = Buffer;
  ReadFileInfo.FileDataSize = *BufferSize;
  ReadFileInfo.FileSize     = FileSize;

  Status = ReadFile (
             BlockIo,
             DiskIo,
             Volume,
             &File->FileIdentifierDesc->Icb,
             File->FileEntry,
             &ReadFileInfo
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  *BufferSize   = ReadFileInfo.FileDataSize;
  *FilePosition = ReadFileInfo.FilePosition;

  return EFI_SUCCESS;
}

/**
  Check if ControllerHandle supports an UDF file system.

  @param[in]  This                Protocol instance pointer.
  @param[in]  ControllerHandle    Handle of device to test.

  @retval EFI_SUCCESS             UDF file system found.
  @retval EFI_UNSUPPORTED         UDF file system not found.

**/
EFI_STATUS
SupportUdfFileSystem (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL  *LastDevicePathNode;
  EFI_GUID                  *VendorDefinedGuid;

  //
  // Open Device Path protocol on ControllerHandle
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&DevicePath,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  Status = EFI_UNSUPPORTED;

  //
  // Get last Device Path node
  //
  LastDevicePathNode = NULL;
  DevicePathNode     = DevicePath;
  while (!IsDevicePathEnd (DevicePathNode)) {
    LastDevicePathNode = DevicePathNode;
    DevicePathNode     = NextDevicePathNode (DevicePathNode);
  }

  //
  // Check if last Device Path node contains a Vendor-Defined Media Device Path
  // of an UDF file system.
  //
  if ((LastDevicePathNode != NULL) &&
      (DevicePathType (LastDevicePathNode) == MEDIA_DEVICE_PATH) &&
      (DevicePathSubType (LastDevicePathNode) == MEDIA_VENDOR_DP))
  {
    VendorDefinedGuid = (EFI_GUID *)((UINTN)LastDevicePathNode +
                                     OFFSET_OF (VENDOR_DEVICE_PATH, Guid));
    if (CompareGuid (VendorDefinedGuid, &gUdfDevPathGuid)) {
      Status = EFI_SUCCESS;
    }
  }

  //
  // Close Device Path protocol on ControllerHandle
  //
  gBS->CloseProtocol (
         ControllerHandle,
         &gEfiDevicePathProtocolGuid,
         This->DriverBindingHandle,
         ControllerHandle
         );

  return Status;
}
