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;
}

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;
  }

   
   
   
  Status = DiskIo->ReadDisk (
    DiskIo,
    BlockIo->Media->MediaId,
    MultU64x32 (Lsn, LogicalBlockSize),
    Volume->FileEntrySize,
    ReadBuffer
    );
  if (EFI_ERROR (Status)) {
    goto Error_Read_Disk_Blk;
  }

  DescriptorTag = ReadBuffer;

   
   
   
   
  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;
}
