]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Disk/PartitionDxe/ElTorito.c
MdeModulePkg/PartitionDxe: Add partition type guid to installed handle
[mirror_edk2.git] / MdeModulePkg / Universal / Disk / PartitionDxe / ElTorito.c
index 37ac710ff0104d46963a38dcc5f897337f2b8616..a7b5434a08e7cf844b05e8d197f5d9e795c2fc39 100644 (file)
@@ -1,14 +1,15 @@
 /** @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
@@ -36,39 +39,47 @@ PartitionInstallElToritoChildHandles (
   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
@@ -76,34 +87,20 @@ PartitionInstallElToritoChildHandles (
 \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
@@ -111,8 +108,8 @@ PartitionInstallElToritoChildHandles (
     //\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
@@ -123,30 +120,32 @@ PartitionInstallElToritoChildHandles (
     // 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
@@ -166,7 +165,7 @@ PartitionInstallElToritoChildHandles (
       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
@@ -231,37 +230,44 @@ PartitionInstallElToritoChildHandles (
 \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