/** @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",
      __func__
      ));
    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'\\')) {
      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;
}
