X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FDisk%2FPartitionDxe%2FElTorito.c;h=a7b5434a08e7cf844b05e8d197f5d9e795c2fc39;hp=37ac710ff0104d46963a38dcc5f897337f2b8616;hb=709c9fd56b2a3303e679858a4927e382f255d8e4;hpb=adbcbf8ffcaedab483d23b52e8283aaad74cc807 diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/ElTorito.c b/MdeModulePkg/Universal/Disk/PartitionDxe/ElTorito.c index 37ac710ff0..a7b5434a08 100644 --- a/MdeModulePkg/Universal/Disk/PartitionDxe/ElTorito.c +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/ElTorito.c @@ -1,14 +1,15 @@ /** @file Decode an El Torito formatted CD-ROM - Copyright (c) 2006 - 2007, Intel Corporation - All rights reserved. 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 +Copyright (c) 2018 Qualcomm Datacenter Technologies, Inc. +Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
+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. +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ @@ -20,15 +21,17 @@ Install child handles if the Handle supports El Torito format. @param[in] This Calling context. - @param[in] Handle Parent Handle - @param[in] DiskIo Parent DiskIo interface - @param[in] BlockIo Parent BlockIo interface + @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 + @retval EFI_SUCCESS Child handle(s) was added. + @retval EFI_MEDIA_CHANGED Media changed Detected. + @retval other no child handle was added. **/ EFI_STATUS @@ -36,39 +39,47 @@ PartitionInstallElToritoChildHandles ( 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 ) { - EFI_STATUS Status; - UINT32 VolDescriptorLba; - UINT32 Lba; - EFI_BLOCK_IO_MEDIA *Media; - CDROM_VOLUME_DESCRIPTOR *VolDescriptor; - ELTORITO_CATALOG *Catalog; - UINTN Check; - UINTN Index; - UINTN BootEntry; - UINTN MaxIndex; - UINT16 *CheckBuffer; - CDROM_DEVICE_PATH CdDev; - UINT32 SubBlockSize; - UINT32 SectorCount; - EFI_STATUS Found; - UINT32 VolSpaceSize; + EFI_STATUS Status; + UINT64 VolDescriptorOffset; + UINT32 Lba2KB; + EFI_BLOCK_IO_MEDIA *Media; + CDROM_VOLUME_DESCRIPTOR *VolDescriptor; + ELTORITO_CATALOG *Catalog; + UINTN Check; + UINTN Index; + UINTN BootEntry; + UINTN MaxIndex; + UINT16 *CheckBuffer; + CDROM_DEVICE_PATH CdDev; + UINT32 SubBlockSize; + UINT32 SectorCount; + EFI_STATUS Found; + UINT32 VolSpaceSize; + EFI_PARTITION_INFO_PROTOCOL PartitionInfo; Found = EFI_NOT_FOUND; Media = BlockIo->Media; + VolSpaceSize = 0; // - // CD_ROM has the fixed block size as 2048 bytes + // CD_ROM has the fixed block size as 2048 bytes (SIZE_2KB) // - if (Media->BlockSize != 2048) { + + // If the ISO image has been copied onto a different storage media + // then the block size might be different (eg: USB). + // Ensure 2048 (SIZE_2KB) is a multiple of block size + if (((SIZE_2KB % Media->BlockSize) != 0) || (Media->BlockSize > SIZE_2KB)) { return EFI_NOT_FOUND; } - VolDescriptor = AllocatePool ((UINTN) Media->BlockSize); + VolDescriptor = AllocatePool ((UINTN)SIZE_2KB); if (VolDescriptor == NULL) { return EFI_NOT_FOUND; @@ -76,34 +87,20 @@ PartitionInstallElToritoChildHandles ( Catalog = (ELTORITO_CATALOG *) VolDescriptor; - // - // the ISO-9660 volume descriptor starts at 32k on the media - // and CD_ROM has the fixed block size as 2048 bytes, so... - // - // - // ((16*2048) / Media->BlockSize) - 1; - // - VolDescriptorLba = 15; // // Loop: handle one volume descriptor per time + // The ISO-9660 volume descriptor starts at 32k on the media // - while (TRUE) { - - VolDescriptorLba += 1; - if (VolDescriptorLba > Media->LastBlock) { - // - // We are pointing past the end of the device so exit - // - break; - } - - Status = BlockIo->ReadBlocks ( - BlockIo, - Media->MediaId, - VolDescriptorLba, - Media->BlockSize, - VolDescriptor - ); + for (VolDescriptorOffset = SIZE_32KB; + VolDescriptorOffset <= MultU64x32 (Media->LastBlock, Media->BlockSize); + VolDescriptorOffset += SIZE_2KB) { + Status = DiskIo->ReadDisk ( + DiskIo, + Media->MediaId, + VolDescriptorOffset, + SIZE_2KB, + VolDescriptor + ); if (EFI_ERROR (Status)) { Found = Status; break; @@ -111,8 +108,8 @@ PartitionInstallElToritoChildHandles ( // // Check for valid volume descriptor signature // - if (VolDescriptor->Type == CDVOL_TYPE_END || - CompareMem (VolDescriptor->Id, CDVOL_ID, sizeof (VolDescriptor->Id)) != 0 + if (VolDescriptor->Unknown.Type == CDVOL_TYPE_END || + CompareMem (VolDescriptor->Unknown.Id, CDVOL_ID, sizeof (VolDescriptor->Unknown.Id)) != 0 ) { // // end of Volume descriptor list @@ -123,30 +120,32 @@ PartitionInstallElToritoChildHandles ( // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte, // the 32-bit numerical values is stored in Both-byte orders // - if (VolDescriptor->Type == CDVOL_TYPE_CODED) { - VolSpaceSize = VolDescriptor->VolSpaceSize[0]; + if (VolDescriptor->PrimaryVolume.Type == CDVOL_TYPE_CODED) { + VolSpaceSize = VolDescriptor->PrimaryVolume.VolSpaceSize[0]; } // // Is it an El Torito volume descriptor? // - if (CompareMem (VolDescriptor->SystemId, CDVOL_ELTORITO_ID, sizeof (CDVOL_ELTORITO_ID) - 1) != 0) { + if (CompareMem (VolDescriptor->BootRecordVolume.SystemId, CDVOL_ELTORITO_ID, sizeof (CDVOL_ELTORITO_ID) - 1) != 0) { continue; } // // Read in the boot El Torito boot catalog + // The LBA unit used by El Torito boot catalog is 2KB unit // - Lba = UNPACK_INT32 (VolDescriptor->EltCatalog); - if (Lba > Media->LastBlock) { + Lba2KB = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog); + // Ensure the LBA (in 2KB unit) fits into our media + if (Lba2KB * (SIZE_2KB / Media->BlockSize) > Media->LastBlock) { continue; } - Status = BlockIo->ReadBlocks ( - BlockIo, - Media->MediaId, - Lba, - Media->BlockSize, - Catalog - ); + Status = DiskIo->ReadDisk ( + DiskIo, + Media->MediaId, + MultU64x32 (Lba2KB, SIZE_2KB), + SIZE_2KB, + Catalog + ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "EltCheckDevice: error reading catalog %r\n", Status)); continue; @@ -166,7 +165,7 @@ PartitionInstallElToritoChildHandles ( Check += CheckBuffer[Index]; } - if (Check & 0xFFFF) { + if ((Check & 0xFFFF) != 0) { DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header checksum failed\n")); continue; } @@ -231,37 +230,44 @@ PartitionInstallElToritoChildHandles ( CdDev.BootEntry = (UINT32) BootEntry; BootEntry++; - CdDev.PartitionStart = Catalog->Boot.Lba; + CdDev.PartitionStart = Catalog->Boot.Lba * (SIZE_2KB / Media->BlockSize); if (SectorCount < 2) { // // When the SectorCount < 2, set the Partition as the whole CD. // - if (VolSpaceSize > (Media->LastBlock + 1)) { - CdDev.PartitionSize = (UINT32)(Media->LastBlock - Catalog->Boot.Lba + 1); + if (VolSpaceSize * (SIZE_2KB / Media->BlockSize) > (Media->LastBlock + 1)) { + CdDev.PartitionSize = (UINT32)(Media->LastBlock - Catalog->Boot.Lba * (SIZE_2KB / Media->BlockSize) + 1); } else { - CdDev.PartitionSize = (UINT32)(VolSpaceSize - Catalog->Boot.Lba); + CdDev.PartitionSize = (UINT32)(VolSpaceSize - Catalog->Boot.Lba) * (SIZE_2KB / Media->BlockSize); } } else { CdDev.PartitionSize = DivU64x32 ( MultU64x32 ( - SectorCount, + SectorCount * (SIZE_2KB / Media->BlockSize), SubBlockSize ) + Media->BlockSize - 1, Media->BlockSize ); } + ZeroMem (&PartitionInfo, sizeof (EFI_PARTITION_INFO_PROTOCOL)); + PartitionInfo.Revision = EFI_PARTITION_INFO_PROTOCOL_REVISION; + PartitionInfo.Type = PARTITION_TYPE_OTHER; + Status = PartitionInstallChildHandle ( This, Handle, DiskIo, + DiskIo2, BlockIo, + BlockIo2, DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &CdDev, - Catalog->Boot.Lba, - Catalog->Boot.Lba + CdDev.PartitionSize - 1, + &PartitionInfo, + Catalog->Boot.Lba * (SIZE_2KB / Media->BlockSize), + Catalog->Boot.Lba * (SIZE_2KB / Media->BlockSize) + CdDev.PartitionSize - 1, SubBlockSize, - FALSE + NULL ); if (!EFI_ERROR (Status)) { Found = EFI_SUCCESS;