/** @file
  Scan for an UDF file system on a formatted media.

  Caution: This file requires additional review when modified.
  This driver will have external input - CD/DVD media.
  This external input must be validated carefully to avoid security issue like
  buffer overflow, integer overflow.

  FindUdfFileSystem() routine will consume the media properties and do basic
  validation.

  Copyright (c) 2018 Qualcomm Datacenter Technologies, Inc.
  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 "Partition.h"

#define MAX_CORRECTION_BLOCKS_NUM  512u

//
// C5BD4D42-1A76-4996-8956-73CDA326CD0A
//
#define EFI_UDF_DEVICE_PATH_GUID                        \
  { 0xC5BD4D42, 0x1A76, 0x4996,                         \
    { 0x89, 0x56, 0x73, 0xCD, 0xA3, 0x26, 0xCD, 0x0A }  \
  }

typedef struct {
  VENDOR_DEVICE_PATH          DevicePath;
  EFI_DEVICE_PATH_PROTOCOL    End;
} UDF_DEVICE_PATH;

//
// Vendor-Defined Device Path GUID for UDF file system
//
EFI_GUID  gUdfDevPathGuid = EFI_UDF_DEVICE_PATH_GUID;

//
// Vendor-Defined Media Device Path for UDF file system
//
UDF_DEVICE_PATH  gUdfDevicePath = {
  {
    { MEDIA_DEVICE_PATH,                 MEDIA_VENDOR_DP,
        { sizeof (VENDOR_DEVICE_PATH),       0 }
    },
    EFI_UDF_DEVICE_PATH_GUID
  },
  { END_DEVICE_PATH_TYPE,              END_ENTIRE_DEVICE_PATH_SUBTYPE,
        { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
  }
};

/**
  Find the anchor volume descriptor pointer.

  @param[in]  BlockIo               BlockIo interface.
  @param[in]  DiskIo                DiskIo interface.
  @param[out] AnchorPoint           Anchor volume descriptor pointer.
  @param[out] LastRecordedBlock     Last recorded block.

  @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,
  OUT  EFI_LBA                               *LastRecordedBlock
  )
{
  EFI_STATUS                            Status;
  UINT32                                BlockSize;
  EFI_LBA                               EndLBA;
  UDF_DESCRIPTOR_TAG                    *DescriptorTag;
  UINTN                                 AvdpsCount;
  UINTN                                 Size;
  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoints;
  INTN                                  Index;
  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPointPtr;
  EFI_LBA                               LastAvdpBlockNum;

  //
  // UDF 2.60, 2.2.3 Anchor Volume Descriptor Pointer
  //
  // An Anchor Volume Descriptor Pointer structure shall be recorded in at
  // least 2 of the following 3 locations on the media: Logical Sector 256,
  // N - 256 or N, where N is the last *addressable* sector of a volume.
  //
  // To figure out what logical sector N is, the SCSI commands READ CAPACITY and
  // READ TRACK INFORMATION are used, however many drives or medias report their
  // "last recorded block" wrongly. Although, READ CAPACITY returns the last
  // readable data block but there might be unwritten blocks, which are located
  // outside any track and therefore AVDP will not be found at block N.
  //
  // That said, we define a magic number of 512 blocks to be used as correction
  // when attempting to find AVDP and define last block number.
  //
  BlockSize          = BlockIo->Media->BlockSize;
  EndLBA             = BlockIo->Media->LastBlock;
  *LastRecordedBlock = EndLBA;
  AvdpsCount         = 0;

  //
  // Check if the block size of the underlying media can hold the data of an
  // Anchor Volume Descriptor Pointer
  //
  if (BlockSize < sizeof (UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: Media block size 0x%x unable to hold an AVDP.\n",
      __func__,
      BlockSize
      ));
    return EFI_UNSUPPORTED;
  }

  //
  // Find AVDP at block 256
  //
  Status = DiskIo->ReadDisk (
                     DiskIo,
                     BlockIo->Media->MediaId,
                     MultU64x32 (256, BlockSize),
                     sizeof (*AnchorPoint),
                     AnchorPoint
                     );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  DescriptorTag = &AnchorPoint->DescriptorTag;

  //
  // Check if read block is a valid AVDP descriptor
  //
  if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
    DEBUG ((DEBUG_INFO, "%a: found AVDP at block %d\n", __func__, 256));
    AvdpsCount++;
  }

  //
  // Find AVDP at block N - 256
  //
  Status = DiskIo->ReadDisk (
                     DiskIo,
                     BlockIo->Media->MediaId,
                     MultU64x32 ((UINT64)EndLBA - 256, BlockSize),
                     sizeof (*AnchorPoint),
                     AnchorPoint
                     );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Check if read block is a valid AVDP descriptor
  //
  if ((DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) &&
      (++AvdpsCount == 2))
  {
    DEBUG ((
      DEBUG_INFO,
      "%a: found AVDP at block %Ld\n",
      __func__,
      EndLBA - 256
      ));
    return EFI_SUCCESS;
  }

  //
  // Check if at least one AVDP was found in previous locations
  //
  if (AvdpsCount == 0) {
    return EFI_VOLUME_CORRUPTED;
  }

  //
  // Find AVDP at block N
  //
  Status = DiskIo->ReadDisk (
                     DiskIo,
                     BlockIo->Media->MediaId,
                     MultU64x32 ((UINT64)EndLBA, BlockSize),
                     sizeof (*AnchorPoint),
                     AnchorPoint
                     );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Check if read block is a valid AVDP descriptor
  //
  if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
    return EFI_SUCCESS;
  }

  //
  // No AVDP found at block N. Possibly drive/media returned bad last recorded
  // block, or it is part of unwritten data blocks and outside any track.
  //
  // Search backwards for an AVDP from block N-1 through
  // N-MAX_CORRECTION_BLOCKS_NUM. If any AVDP is found, then correct last block
  // number for the new UDF partition child handle.
  //
  Size = MAX_CORRECTION_BLOCKS_NUM * BlockSize;

  AnchorPoints = AllocateZeroPool (Size);
  if (AnchorPoints == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Read consecutive MAX_CORRECTION_BLOCKS_NUM disk blocks
  //
  Status = DiskIo->ReadDisk (
                     DiskIo,
                     BlockIo->Media->MediaId,
                     MultU64x32 ((UINT64)EndLBA - MAX_CORRECTION_BLOCKS_NUM, BlockSize),
                     Size,
                     AnchorPoints
                     );
  if (EFI_ERROR (Status)) {
    goto Out_Free;
  }

  Status = EFI_VOLUME_CORRUPTED;

  //
  // Search for AVDP from blocks N-1 through N-MAX_CORRECTION_BLOCKS_NUM
  //
  for (Index = MAX_CORRECTION_BLOCKS_NUM - 2; Index >= 0; Index--) {
    AnchorPointPtr = (VOID *)((UINTN)AnchorPoints + Index * BlockSize);

    DescriptorTag = &AnchorPointPtr->DescriptorTag;

    //
    // Check if read block is a valid AVDP descriptor
    //
    if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
      //
      // Calculate last recorded block number
      //
      LastAvdpBlockNum = EndLBA - (MAX_CORRECTION_BLOCKS_NUM - Index);
      DEBUG ((
        DEBUG_WARN,
        "%a: found AVDP at block %Ld\n",
        __func__,
        LastAvdpBlockNum
        ));
      DEBUG ((
        DEBUG_WARN,
        "%a: correcting last block from %Ld to %Ld\n",
        __func__,
        EndLBA,
        LastAvdpBlockNum
        ));
      //
      // Save read AVDP from last block
      //
      CopyMem (AnchorPoint, AnchorPointPtr, sizeof (*AnchorPointPtr));
      //
      // Set last recorded block number
      //
      *LastRecordedBlock = LastAvdpBlockNum;
      Status             = EFI_SUCCESS;
      break;
    }
  }

Out_Free:
  FreePool (AnchorPoints);
  return Status;
}

/**
  Find UDF volume identifiers in a Volume Recognition Sequence.

  @param[in]  BlockIo             BlockIo interface.
  @param[in]  DiskIo              DiskIo interface.

  @retval EFI_SUCCESS             UDF volume identifiers were found.
  @retval EFI_NOT_FOUND           UDF volume identifiers were not found.
  @retval other                   Failed to perform disk I/O.

**/
EFI_STATUS
FindUdfVolumeIdentifiers (
  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
  IN EFI_DISK_IO_PROTOCOL   *DiskIo
  )
{
  EFI_STATUS               Status;
  UINT64                   Offset;
  UINT64                   EndDiskOffset;
  CDROM_VOLUME_DESCRIPTOR  VolDescriptor;
  CDROM_VOLUME_DESCRIPTOR  TerminatingVolDescriptor;

  ZeroMem ((VOID *)&TerminatingVolDescriptor, sizeof (CDROM_VOLUME_DESCRIPTOR));

  //
  // Start Volume Recognition Sequence
  //
  EndDiskOffset = MultU64x32 (
                    BlockIo->Media->LastBlock,
                    BlockIo->Media->BlockSize
                    );

  for (Offset = UDF_VRS_START_OFFSET; Offset < EndDiskOffset;
       Offset += UDF_LOGICAL_SECTOR_SIZE)
  {
    //
    // Check if block device has a Volume Structure Descriptor and an Extended
    // Area.
    //
    Status = DiskIo->ReadDisk (
                       DiskIo,
                       BlockIo->Media->MediaId,
                       Offset,
                       sizeof (CDROM_VOLUME_DESCRIPTOR),
                       (VOID *)&VolDescriptor
                       );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if (CompareMem (
          (VOID *)VolDescriptor.Unknown.Id,
          (VOID *)UDF_BEA_IDENTIFIER,
          sizeof (VolDescriptor.Unknown.Id)
          ) == 0)
    {
      break;
    }

    if ((CompareMem (
           (VOID *)VolDescriptor.Unknown.Id,
           (VOID *)CDVOL_ID,
           sizeof (VolDescriptor.Unknown.Id)
           ) != 0) ||
        (CompareMem (
           (VOID *)&VolDescriptor,
           (VOID *)&TerminatingVolDescriptor,
           sizeof (CDROM_VOLUME_DESCRIPTOR)
           ) == 0))
    {
      return EFI_NOT_FOUND;
    }
  }

  //
  // Look for "NSR0{2,3}" identifiers in the Extended Area.
  //
  Offset += UDF_LOGICAL_SECTOR_SIZE;
  if (Offset >= EndDiskOffset) {
    return EFI_NOT_FOUND;
  }

  Status = DiskIo->ReadDisk (
                     DiskIo,
                     BlockIo->Media->MediaId,
                     Offset,
                     sizeof (CDROM_VOLUME_DESCRIPTOR),
                     (VOID *)&VolDescriptor
                     );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if ((CompareMem (
         (VOID *)VolDescriptor.Unknown.Id,
         (VOID *)UDF_NSR2_IDENTIFIER,
         sizeof (VolDescriptor.Unknown.Id)
         ) != 0) &&
      (CompareMem (
         (VOID *)VolDescriptor.Unknown.Id,
         (VOID *)UDF_NSR3_IDENTIFIER,
         sizeof (VolDescriptor.Unknown.Id)
         ) != 0))
  {
    return EFI_NOT_FOUND;
  }

  //
  // Look for "TEA01" identifier in the Extended Area
  //
  Offset += UDF_LOGICAL_SECTOR_SIZE;
  if (Offset >= EndDiskOffset) {
    return EFI_NOT_FOUND;
  }

  Status = DiskIo->ReadDisk (
                     DiskIo,
                     BlockIo->Media->MediaId,
                     Offset,
                     sizeof (CDROM_VOLUME_DESCRIPTOR),
                     (VOID *)&VolDescriptor
                     );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (CompareMem (
        (VOID *)VolDescriptor.Unknown.Id,
        (VOID *)UDF_TEA_IDENTIFIER,
        sizeof (VolDescriptor.Unknown.Id)
        ) != 0)
  {
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}

/**
  Check if Logical Volume Descriptor is supported by current EDK2 UDF file
  system implementation.

  @param[in]  LogicalVolDesc  Logical Volume Descriptor pointer.

  @retval TRUE                Logical Volume Descriptor is supported.
  @retval FALSE               Logical Volume Descriptor is not supported.

**/
BOOLEAN
IsLogicalVolumeDescriptorSupported (
  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc
  )
{
  //
  // Check for a valid UDF revision range
  //
  switch (LogicalVolDesc->DomainIdentifier.Suffix.Domain.UdfRevision) {
    case 0x0102:
    case 0x0150:
    case 0x0200:
    case 0x0201:
    case 0x0250:
    case 0x0260:
      break;
    default:
      return FALSE;
  }

  //
  // Check for a single Partition Map
  //
  if (LogicalVolDesc->NumberOfPartitionMaps > 1) {
    return FALSE;
  }

  //
  // UDF 1.02 revision supports only Type 1 (Physical) partitions, but
  // let's check it any way.
  //
  // PartitionMap[0] -> type
  // PartitionMap[1] -> length (in bytes)
  //
  if ((LogicalVolDesc->PartitionMaps[0] != 1) ||
      (LogicalVolDesc->PartitionMaps[1] != 6))
  {
    return FALSE;
  }

  return TRUE;
}

/**
  Find UDF logical volume location and whether it is supported by current EDK2
  UDF file system implementation.

  @param[in]  BlockIo               BlockIo interface.
  @param[in]  DiskIo                DiskIo interface.
  @param[in]  AnchorPoint           Anchor volume descriptor pointer.
  @param[in]  LastRecordedBlock     Last recorded block in media.
  @param[out] MainVdsStartBlock     Main VDS starting block number.
  @param[out] MainVdsEndBlock       Main VDS ending block number.

  @retval EFI_SUCCESS               UDF logical volume was found.
  @retval EFI_VOLUME_CORRUPTED      UDF file system structures are corrupted.
  @retval EFI_UNSUPPORTED           UDF logical volume is not supported.
  @retval other                     Failed to perform disk I/O.

**/
EFI_STATUS
FindLogicalVolumeLocation (
  IN   EFI_BLOCK_IO_PROTOCOL                 *BlockIo,
  IN   EFI_DISK_IO_PROTOCOL                  *DiskIo,
  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
  IN   EFI_LBA                               LastRecordedBlock,
  OUT  UINT64                                *MainVdsStartBlock,
  OUT  UINT64                                *MainVdsEndBlock
  )
{
  EFI_STATUS                     Status;
  UINT32                         BlockSize;
  UDF_EXTENT_AD                  *ExtentAd;
  UINT64                         SeqBlocksNum;
  UINT64                         SeqStartBlock;
  UINT64                         GuardMainVdsStartBlock;
  VOID                           *Buffer;
  UINT64                         SeqEndBlock;
  BOOLEAN                        StopSequence;
  UINTN                          LvdsCount;
  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
  UDF_DESCRIPTOR_TAG             *DescriptorTag;

  BlockSize = BlockIo->Media->BlockSize;
  ExtentAd  = &AnchorPoint->MainVolumeDescriptorSequenceExtent;

  //
  // UDF 2.60, 2.2.3.1 struct MainVolumeDescriptorSequenceExtent
  //
  // The Main Volume Descriptor Sequence Extent shall have a minimum length of
  // 16 logical sectors.
  //
  // Also make sure it does not exceed maximum number of blocks in the disk.
  //
  SeqBlocksNum = DivU64x32 ((UINT64)ExtentAd->ExtentLength, BlockSize);
  if ((SeqBlocksNum < 16) || ((EFI_LBA)SeqBlocksNum > LastRecordedBlock + 1)) {
    return EFI_VOLUME_CORRUPTED;
  }

  //
  // Check for valid Volume Descriptor Sequence starting block number
  //
  SeqStartBlock = (UINT64)ExtentAd->ExtentLocation;
  if ((SeqStartBlock > LastRecordedBlock) ||
      (SeqStartBlock + SeqBlocksNum - 1 > LastRecordedBlock))
  {
    return EFI_VOLUME_CORRUPTED;
  }

  GuardMainVdsStartBlock = SeqStartBlock;

  //
  // Allocate buffer for reading disk blocks
  //
  Buffer = AllocateZeroPool ((UINTN)BlockSize);
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  SeqEndBlock  = SeqStartBlock + SeqBlocksNum;
  StopSequence = FALSE;
  LvdsCount    = 0;
  Status       = EFI_VOLUME_CORRUPTED;
  //
  // Start Main Volume Descriptor Sequence
  //
  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;

    //
    // ECMA 167, 8.4.1 Contents of a Volume Descriptor Sequence
    //
    // - A Volume Descriptor Sequence shall contain one or more Primary Volume
    //   Descriptors.
    // - A Volume Descriptor Sequence shall contain zero or more Implementation
    //   Use Volume Descriptors.
    // - A Volume Descriptor Sequence shall contain zero or more Partition
    //   Descriptors.
    // - A Volume Descriptor Sequence shall contain zero or more Logical Volume
    //   Descriptors.
    // - A Volume Descriptor Sequence shall contain zero or more Unallocated
    //   Space Descriptors.
    //
    switch (DescriptorTag->TagIdentifier) {
      case UdfPrimaryVolumeDescriptor:
      case UdfImplemenationUseVolumeDescriptor:
      case UdfPartitionDescriptor:
      case UdfUnallocatedSpaceDescriptor:
        break;

      case UdfLogicalVolumeDescriptor:
        LogicalVolDesc = Buffer;

        //
        // Check for existence of a single LVD and whether it is supported by
        // current EDK2 UDF file system implementation.
        //
        if ((++LvdsCount > 1) ||
            !IsLogicalVolumeDescriptorSupported (LogicalVolDesc))
        {
          Status       = EFI_UNSUPPORTED;
          StopSequence = TRUE;
        }

        break;

      case UdfTerminatingDescriptor:
        //
        // Stop the sequence when we find a Terminating Descriptor
        // (aka Unallocated Sector), se we don't have to walk all the unallocated
        // area unnecessarily.
        //
        StopSequence = TRUE;
        break;

      default:
        //
        // An invalid Volume Descriptor has been found in the sequece. Volume is
        // corrupted.
        //
        Status = EFI_VOLUME_CORRUPTED;
        goto Out_Free;
    }
  }

  //
  // Check if LVD was found
  //
  if (!EFI_ERROR (Status) && (LvdsCount == 1)) {
    *MainVdsStartBlock = GuardMainVdsStartBlock;
    //
    // We do not need to read either LVD or PD descriptors to know the last
    // valid block in the found UDF file system. It's already
    // LastRecordedBlock.
    //
    *MainVdsEndBlock = LastRecordedBlock;

    Status = EFI_SUCCESS;
  }

Out_Free:
  //
  // Free block read buffer
  //
  FreePool (Buffer);

  return Status;
}

/**
  Find a supported UDF file system in block device.

  @attention This is boundary function that may receive untrusted input.
  @attention The input is from Partition.

  The CD/DVD media is the external input, so this routine will do basic
  validation for the media.

  @param[in]  BlockIo             BlockIo interface.
  @param[in]  DiskIo              DiskIo interface.
  @param[out] StartingLBA         UDF file system starting LBA.
  @param[out] EndingLBA           UDF file system starting LBA.

  @retval EFI_SUCCESS             UDF file system was found.
  @retval other                   UDF file system was not found.

**/
EFI_STATUS
FindUdfFileSystem (
  IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
  IN EFI_DISK_IO_PROTOCOL   *DiskIo,
  OUT EFI_LBA               *StartingLBA,
  OUT EFI_LBA               *EndingLBA
  )
{
  EFI_STATUS                            Status;
  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
  EFI_LBA                               LastRecordedBlock;

  //
  // Find UDF volume identifiers
  //
  Status = FindUdfVolumeIdentifiers (BlockIo, DiskIo);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Find Anchor Volume Descriptor Pointer
  //
  Status = FindAnchorVolumeDescriptorPointer (
             BlockIo,
             DiskIo,
             &AnchorPoint,
             &LastRecordedBlock
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Find Logical Volume location
  //
  Status = FindLogicalVolumeLocation (
             BlockIo,
             DiskIo,
             &AnchorPoint,
             LastRecordedBlock,
             (UINT64 *)StartingLBA,
             (UINT64 *)EndingLBA
             );

  return Status;
}

/**
  Install child handles if the Handle supports UDF/ECMA-167 volume format.

  @param[in]  This        Calling context.
  @param[in]  Handle      Parent Handle.
  @param[in]  DiskIo      Parent DiskIo interface.
  @param[in]  DiskIo2     Parent DiskIo2 interface.
  @param[in]  BlockIo     Parent BlockIo interface.
  @param[in]  BlockIo2    Parent BlockIo2 interface.
  @param[in]  DevicePath  Parent Device Path


  @retval EFI_SUCCESS         Child handle(s) was added.
  @retval EFI_MEDIA_CHANGED   Media changed Detected.
  @retval other               no child handle was added.

**/
EFI_STATUS
PartitionInstallUdfChildHandles (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   Handle,
  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,
  IN  EFI_DISK_IO2_PROTOCOL        *DiskIo2,
  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,
  IN  EFI_BLOCK_IO2_PROTOCOL       *BlockIo2,
  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  UINT32                       RemainderByMediaBlockSize;
  EFI_STATUS                   Status;
  EFI_BLOCK_IO_MEDIA           *Media;
  EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;
  EFI_LBA                      StartingLBA;
  EFI_LBA                      EndingLBA;
  BOOLEAN                      ChildCreated;

  Media        = BlockIo->Media;
  ChildCreated = FALSE;

  //
  // Check if UDF logical block size is multiple of underlying device block size
  //
  DivU64x32Remainder (
    UDF_LOGICAL_SECTOR_SIZE,   // Dividend
    Media->BlockSize,          // Divisor
    &RemainderByMediaBlockSize // Remainder
    );
  if (RemainderByMediaBlockSize != 0) {
    return EFI_NOT_FOUND;
  }

  //
  // Detect El Torito feature first.
  // And always continue to search for UDF.
  //
  Status = PartitionInstallElToritoChildHandles (
             This,
             Handle,
             DiskIo,
             DiskIo2,
             BlockIo,
             BlockIo2,
             DevicePath
             );
  if (!EFI_ERROR (Status)) {
    DEBUG ((DEBUG_INFO, "PartitionDxe: El Torito standard found on handle 0x%p.\n", Handle));
    ChildCreated = TRUE;
  }

  //
  // Search for an UDF file system on block device
  //
  Status = FindUdfFileSystem (BlockIo, DiskIo, &StartingLBA, &EndingLBA);
  if (EFI_ERROR (Status)) {
    return (ChildCreated ? EFI_SUCCESS : EFI_NOT_FOUND);
  }

  //
  // Create Partition Info protocol for UDF file system
  //
  ZeroMem (&PartitionInfo, sizeof (EFI_PARTITION_INFO_PROTOCOL));
  PartitionInfo.Revision = EFI_PARTITION_INFO_PROTOCOL_REVISION;
  PartitionInfo.Type     = PARTITION_TYPE_OTHER;

  //
  // Install partition child handle for UDF file system
  //
  Status = PartitionInstallChildHandle (
             This,
             Handle,
             DiskIo,
             DiskIo2,
             BlockIo,
             BlockIo2,
             DevicePath,
             (EFI_DEVICE_PATH_PROTOCOL *)&gUdfDevicePath,
             &PartitionInfo,
             StartingLBA,
             EndingLBA,
             Media->BlockSize,
             NULL
             );
  if (EFI_ERROR (Status)) {
    return (ChildCreated ? EFI_SUCCESS : Status);
  }

  return EFI_SUCCESS;
}
