/** @file\r
Decode an El Torito formatted CD-ROM\r
\r
- Copyright (c) 2006 - 2007, Intel Corporation \r
- All rights reserved. This program and the accompanying materials \r
- are licensed and made available under the terms and conditions of the BSD License \r
- which accompanies this distribution. The full text of the license may be found at \r
- http://opensource.org/licenses/bsd-license.php \r
+Copyright (c) 2018 Qualcomm Datacenter Technologies, Inc.\r
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
\r
**/\r
\r
Install child handles if the Handle supports El Torito format.\r
\r
@param[in] This Calling context.\r
- @param[in] Handle Parent Handle\r
- @param[in] DiskIo Parent DiskIo interface\r
- @param[in] BlockIo Parent BlockIo interface\r
+ @param[in] Handle Parent Handle.\r
+ @param[in] DiskIo Parent DiskIo interface.\r
+ @param[in] DiskIo2 Parent DiskIo2 interface.\r
+ @param[in] BlockIo Parent BlockIo interface.\r
+ @param[in] BlockIo2 Parent BlockIo2 interface.\r
@param[in] DevicePath Parent Device Path\r
\r
\r
- @retval EFI_SUCCESS Child handle(s) was added\r
- @retval EFI_MEDIA_CHANGED Media changed Detected\r
- @retval other no child handle was added\r
+ @retval EFI_SUCCESS Child handle(s) was added.\r
+ @retval EFI_MEDIA_CHANGED Media changed Detected.\r
+ @retval other no child handle was added.\r
\r
**/\r
EFI_STATUS\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE Handle,\r
IN EFI_DISK_IO_PROTOCOL *DiskIo,\r
+ IN EFI_DISK_IO2_PROTOCOL *DiskIo2,\r
IN EFI_BLOCK_IO_PROTOCOL *BlockIo,\r
+ IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,\r
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT32 VolDescriptorLba;\r
- UINT32 Lba;\r
- EFI_BLOCK_IO_MEDIA *Media;\r
- CDROM_VOLUME_DESCRIPTOR *VolDescriptor;\r
- ELTORITO_CATALOG *Catalog;\r
- UINTN Check;\r
- UINTN Index;\r
- UINTN BootEntry;\r
- UINTN MaxIndex;\r
- UINT16 *CheckBuffer;\r
- CDROM_DEVICE_PATH CdDev;\r
- UINT32 SubBlockSize;\r
- UINT32 SectorCount;\r
- EFI_STATUS Found;\r
- UINT32 VolSpaceSize;\r
+ EFI_STATUS Status;\r
+ UINT64 VolDescriptorOffset;\r
+ UINT32 Lba2KB;\r
+ EFI_BLOCK_IO_MEDIA *Media;\r
+ CDROM_VOLUME_DESCRIPTOR *VolDescriptor;\r
+ ELTORITO_CATALOG *Catalog;\r
+ UINTN Check;\r
+ UINTN Index;\r
+ UINTN BootEntry;\r
+ UINTN MaxIndex;\r
+ UINT16 *CheckBuffer;\r
+ CDROM_DEVICE_PATH CdDev;\r
+ UINT32 SubBlockSize;\r
+ UINT32 SectorCount;\r
+ EFI_STATUS Found;\r
+ UINT32 VolSpaceSize;\r
+ EFI_PARTITION_INFO_PROTOCOL PartitionInfo;\r
\r
Found = EFI_NOT_FOUND;\r
Media = BlockIo->Media;\r
+\r
VolSpaceSize = 0;\r
\r
//\r
- // CD_ROM has the fixed block size as 2048 bytes\r
+ // CD_ROM has the fixed block size as 2048 bytes (SIZE_2KB)\r
//\r
- if (Media->BlockSize != 2048) {\r
+\r
+ // If the ISO image has been copied onto a different storage media\r
+ // then the block size might be different (eg: USB).\r
+ // Ensure 2048 (SIZE_2KB) is a multiple of block size\r
+ if (((SIZE_2KB % Media->BlockSize) != 0) || (Media->BlockSize > SIZE_2KB)) {\r
return EFI_NOT_FOUND;\r
}\r
\r
- VolDescriptor = AllocatePool ((UINTN) Media->BlockSize);\r
+ VolDescriptor = AllocatePool ((UINTN)SIZE_2KB);\r
\r
if (VolDescriptor == NULL) {\r
return EFI_NOT_FOUND;\r
\r
Catalog = (ELTORITO_CATALOG *) VolDescriptor;\r
\r
- //\r
- // the ISO-9660 volume descriptor starts at 32k on the media\r
- // and CD_ROM has the fixed block size as 2048 bytes, so...\r
- //\r
- //\r
- // ((16*2048) / Media->BlockSize) - 1;\r
- //\r
- VolDescriptorLba = 15;\r
//\r
// Loop: handle one volume descriptor per time\r
+ // The ISO-9660 volume descriptor starts at 32k on the media\r
//\r
- while (TRUE) {\r
-\r
- VolDescriptorLba += 1;\r
- if (VolDescriptorLba > Media->LastBlock) {\r
- //\r
- // We are pointing past the end of the device so exit\r
- //\r
- break;\r
- }\r
-\r
- Status = BlockIo->ReadBlocks (\r
- BlockIo,\r
- Media->MediaId,\r
- VolDescriptorLba,\r
- Media->BlockSize,\r
- VolDescriptor\r
- );\r
+ for (VolDescriptorOffset = SIZE_32KB;\r
+ VolDescriptorOffset <= MultU64x32 (Media->LastBlock, Media->BlockSize);\r
+ VolDescriptorOffset += SIZE_2KB) {\r
+ Status = DiskIo->ReadDisk (\r
+ DiskIo,\r
+ Media->MediaId,\r
+ VolDescriptorOffset,\r
+ SIZE_2KB,\r
+ VolDescriptor\r
+ );\r
if (EFI_ERROR (Status)) {\r
Found = Status;\r
break;\r
//\r
// Check for valid volume descriptor signature\r
//\r
- if (VolDescriptor->Type == CDVOL_TYPE_END ||\r
- CompareMem (VolDescriptor->Id, CDVOL_ID, sizeof (VolDescriptor->Id)) != 0\r
+ if (VolDescriptor->Unknown.Type == CDVOL_TYPE_END ||\r
+ CompareMem (VolDescriptor->Unknown.Id, CDVOL_ID, sizeof (VolDescriptor->Unknown.Id)) != 0\r
) {\r
//\r
// end of Volume descriptor list\r
// Read the Volume Space Size from Primary Volume Descriptor 81-88 byte,\r
// the 32-bit numerical values is stored in Both-byte orders\r
//\r
- if (VolDescriptor->Type == CDVOL_TYPE_CODED) {\r
- VolSpaceSize = VolDescriptor->VolSpaceSize[0];\r
+ if (VolDescriptor->PrimaryVolume.Type == CDVOL_TYPE_CODED) {\r
+ VolSpaceSize = VolDescriptor->PrimaryVolume.VolSpaceSize[0];\r
}\r
//\r
// Is it an El Torito volume descriptor?\r
//\r
- if (CompareMem (VolDescriptor->SystemId, CDVOL_ELTORITO_ID, sizeof (CDVOL_ELTORITO_ID) - 1) != 0) {\r
+ if (CompareMem (VolDescriptor->BootRecordVolume.SystemId, CDVOL_ELTORITO_ID, sizeof (CDVOL_ELTORITO_ID) - 1) != 0) {\r
continue;\r
}\r
//\r
// Read in the boot El Torito boot catalog\r
+ // The LBA unit used by El Torito boot catalog is 2KB unit\r
//\r
- Lba = UNPACK_INT32 (VolDescriptor->EltCatalog);\r
- if (Lba > Media->LastBlock) {\r
+ Lba2KB = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog);\r
+ // Ensure the LBA (in 2KB unit) fits into our media\r
+ if (Lba2KB * (SIZE_2KB / Media->BlockSize) > Media->LastBlock) {\r
continue;\r
}\r
\r
- Status = BlockIo->ReadBlocks (\r
- BlockIo,\r
- Media->MediaId,\r
- Lba,\r
- Media->BlockSize,\r
- Catalog\r
- );\r
+ Status = DiskIo->ReadDisk (\r
+ DiskIo,\r
+ Media->MediaId,\r
+ MultU64x32 (Lba2KB, SIZE_2KB),\r
+ SIZE_2KB,\r
+ Catalog\r
+ );\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "EltCheckDevice: error reading catalog %r\n", Status));\r
continue;\r
Check += CheckBuffer[Index];\r
}\r
\r
- if (Check & 0xFFFF) {\r
+ if ((Check & 0xFFFF) != 0) {\r
DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header checksum failed\n"));\r
continue;\r
}\r
\r
CdDev.BootEntry = (UINT32) BootEntry;\r
BootEntry++;\r
- CdDev.PartitionStart = Catalog->Boot.Lba;\r
+ CdDev.PartitionStart = Catalog->Boot.Lba * (SIZE_2KB / Media->BlockSize);\r
if (SectorCount < 2) {\r
//\r
// When the SectorCount < 2, set the Partition as the whole CD.\r
//\r
- if (VolSpaceSize > (Media->LastBlock + 1)) {\r
- CdDev.PartitionSize = (UINT32)(Media->LastBlock - Catalog->Boot.Lba + 1);\r
+ if (VolSpaceSize * (SIZE_2KB / Media->BlockSize) > (Media->LastBlock + 1)) {\r
+ CdDev.PartitionSize = (UINT32)(Media->LastBlock - Catalog->Boot.Lba * (SIZE_2KB / Media->BlockSize) + 1);\r
} else {\r
- CdDev.PartitionSize = (UINT32)(VolSpaceSize - Catalog->Boot.Lba);\r
+ CdDev.PartitionSize = (UINT32)(VolSpaceSize - Catalog->Boot.Lba) * (SIZE_2KB / Media->BlockSize);\r
}\r
} else {\r
CdDev.PartitionSize = DivU64x32 (\r
MultU64x32 (\r
- SectorCount,\r
+ SectorCount * (SIZE_2KB / Media->BlockSize),\r
SubBlockSize\r
) + Media->BlockSize - 1,\r
Media->BlockSize\r
);\r
}\r
\r
+ ZeroMem (&PartitionInfo, sizeof (EFI_PARTITION_INFO_PROTOCOL));\r
+ PartitionInfo.Revision = EFI_PARTITION_INFO_PROTOCOL_REVISION;\r
+ PartitionInfo.Type = PARTITION_TYPE_OTHER;\r
+\r
Status = PartitionInstallChildHandle (\r
This,\r
Handle,\r
DiskIo,\r
+ DiskIo2,\r
BlockIo,\r
+ BlockIo2,\r
DevicePath,\r
(EFI_DEVICE_PATH_PROTOCOL *) &CdDev,\r
- Catalog->Boot.Lba,\r
- Catalog->Boot.Lba + CdDev.PartitionSize - 1,\r
+ &PartitionInfo,\r
+ Catalog->Boot.Lba * (SIZE_2KB / Media->BlockSize),\r
+ Catalog->Boot.Lba * (SIZE_2KB / Media->BlockSize) + CdDev.PartitionSize - 1,\r
SubBlockSize,\r
- FALSE\r
+ NULL\r
);\r
if (!EFI_ERROR (Status)) {\r
Found = EFI_SUCCESS;\r