/** @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>

  This program and the accompanying materials are licensed and made available
  under the terms and conditions of the BSD License which accompanies this
  distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/

#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;
}
