]> git.proxmox.com Git - mirror_edk2.git/commitdiff
FatPkg: Break down Part.c file.
authorChen A Chen <chen.a.chen@intel.com>
Wed, 16 Jan 2019 08:13:31 +0000 (16:13 +0800)
committerHao Wu <hao.a.wu@intel.com>
Thu, 31 Jan 2019 03:10:54 +0000 (11:10 +0800)
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1470
Break down partition parsing logic to 2 parts, Eltorito and MBR.

Cc: Ruiyu Ni <ray.ni@intel.com>
Cc: Zhang Chao B <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Chen A Chen <chen.a.chen@intel.com>
Reviewed-by: Hao Wu <hao.a.wu@intel.com>
FatPkg/FatPei/Eltorito.c [new file with mode: 0644]
FatPkg/FatPei/FatPei.inf
FatPkg/FatPei/Mbr.c [new file with mode: 0644]
FatPkg/FatPei/Part.c

diff --git a/FatPkg/FatPei/Eltorito.c b/FatPkg/FatPei/Eltorito.c
new file mode 100644 (file)
index 0000000..a350237
--- /dev/null
@@ -0,0 +1,239 @@
+/** @file\r
+  Routines supporting partition discovery and\r
+  logical device reading\r
+\r
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials are licensed and made available\r
+under the terms and conditions of the BSD License which accompanies this\r
+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
+\r
+**/\r
+\r
+#include <IndustryStandard/ElTorito.h>\r
+#include "FatLitePeim.h"\r
+\r
+/**\r
+  This function finds Eltorito partitions. Main algorithm\r
+  is ported from DXE partition driver.\r
+\r
+  @param[in]  PrivateData       The global memory map\r
+  @param[in]  ParentBlockDevNo  The parent block device\r
+\r
+  @retval TRUE              New partitions are detected and logical block devices\r
+                            are added to block device array\r
+  @retval FALSE             No new partitions are added\r
+\r
+**/\r
+BOOLEAN\r
+FatFindEltoritoPartitions (\r
+  IN  PEI_FAT_PRIVATE_DATA *PrivateData,\r
+  IN  UINTN                ParentBlockDevNo\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  BOOLEAN                 Found;\r
+  PEI_FAT_BLOCK_DEVICE    *BlockDev;\r
+  PEI_FAT_BLOCK_DEVICE    *ParentBlockDev;\r
+  UINT32                  VolDescriptorLba;\r
+  UINT32                  Lba;\r
+  CDROM_VOLUME_DESCRIPTOR *VolDescriptor;\r
+  ELTORITO_CATALOG        *Catalog;\r
+  UINTN                   Check;\r
+  UINTN                   Index;\r
+  UINTN                   MaxIndex;\r
+  UINT16                  *CheckBuffer;\r
+  UINT32                  SubBlockSize;\r
+  UINT32                  SectorCount;\r
+  UINT32                  VolSpaceSize;\r
+\r
+  if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {\r
+    return FALSE;\r
+  }\r
+\r
+  Found           = FALSE;\r
+  ParentBlockDev  = &(PrivateData->BlockDevice[ParentBlockDevNo]);\r
+  VolSpaceSize    = 0;\r
+\r
+  //\r
+  // CD_ROM has the fixed block size as 2048 bytes\r
+  //\r
+  if (ParentBlockDev->BlockSize != 2048) {\r
+    return FALSE;\r
+  }\r
+\r
+  VolDescriptor = (CDROM_VOLUME_DESCRIPTOR *) PrivateData->BlockData;\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
+  VolDescriptorLba = 15;\r
+  //\r
+  // ((16*2048) / Media->BlockSize) - 1;\r
+  //\r
+  // Loop: handle one volume descriptor per time\r
+  //\r
+  while (TRUE) {\r
+\r
+    VolDescriptorLba += 1;\r
+    if (VolDescriptorLba > ParentBlockDev->LastBlock) {\r
+      //\r
+      // We are pointing past the end of the device so exit\r
+      //\r
+      break;\r
+    }\r
+\r
+    Status = FatReadBlock (\r
+              PrivateData,\r
+              ParentBlockDevNo,\r
+              VolDescriptorLba,\r
+              ParentBlockDev->BlockSize,\r
+              VolDescriptor\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+    //\r
+    // Check for valid volume descriptor signature\r
+    //\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
+      //\r
+      break;\r
+    }\r
+    //\r
+    // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte\r
+    //\r
+    if (VolDescriptor->Unknown.Type == CDVOL_TYPE_CODED) {\r
+      VolSpaceSize = VolDescriptor->PrimaryVolume.VolSpaceSize[1];\r
+    }\r
+    //\r
+    // Is it an El Torito volume descriptor?\r
+    //\r
+    if (CompareMem (\r
+          VolDescriptor->BootRecordVolume.SystemId,\r
+          CDVOL_ELTORITO_ID,\r
+          sizeof (CDVOL_ELTORITO_ID) - 1\r
+          ) != 0) {\r
+      continue;\r
+    }\r
+    //\r
+    // Read in the boot El Torito boot catalog\r
+    //\r
+    Lba = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog);\r
+    if (Lba > ParentBlockDev->LastBlock) {\r
+      continue;\r
+    }\r
+\r
+    Status = FatReadBlock (\r
+              PrivateData,\r
+              ParentBlockDevNo,\r
+              Lba,\r
+              ParentBlockDev->BlockSize,\r
+              Catalog\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+    //\r
+    // We don't care too much about the Catalog header's contents, but we do want\r
+    // to make sure it looks like a Catalog header\r
+    //\r
+    if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) {\r
+      continue;\r
+    }\r
+\r
+    Check       = 0;\r
+    CheckBuffer = (UINT16 *) Catalog;\r
+    for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) {\r
+      Check += CheckBuffer[Index];\r
+    }\r
+\r
+    if ((Check & 0xFFFF) != 0) {\r
+      continue;\r
+    }\r
+\r
+    MaxIndex = ParentBlockDev->BlockSize / sizeof (ELTORITO_CATALOG);\r
+    for (Index = 1; Index < MaxIndex; Index += 1) {\r
+      //\r
+      // Next entry\r
+      //\r
+      Catalog += 1;\r
+\r
+      //\r
+      // Check this entry\r
+      //\r
+      if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) {\r
+        continue;\r
+      }\r
+\r
+      SubBlockSize  = 512;\r
+      SectorCount   = Catalog->Boot.SectorCount;\r
+\r
+      switch (Catalog->Boot.MediaType) {\r
+\r
+      case ELTORITO_NO_EMULATION:\r
+        SubBlockSize  = ParentBlockDev->BlockSize;\r
+        SectorCount   = Catalog->Boot.SectorCount;\r
+        break;\r
+\r
+      case ELTORITO_HARD_DISK:\r
+        break;\r
+\r
+      case ELTORITO_12_DISKETTE:\r
+        SectorCount = 0x50 * 0x02 * 0x0F;\r
+        break;\r
+\r
+      case ELTORITO_14_DISKETTE:\r
+        SectorCount = 0x50 * 0x02 * 0x12;\r
+        break;\r
+\r
+      case ELTORITO_28_DISKETTE:\r
+        SectorCount = 0x50 * 0x02 * 0x24;\r
+        break;\r
+\r
+      default:\r
+        SectorCount   = 0;\r
+        SubBlockSize  = ParentBlockDev->BlockSize;\r
+        break;\r
+      }\r
+\r
+      if (SectorCount < 2) {\r
+        SectorCount = (VolSpaceSize > ParentBlockDev->LastBlock + 1) ? (UINT32) (ParentBlockDev->LastBlock - Catalog->Boot.Lba + 1) : (UINT32) (VolSpaceSize - Catalog->Boot.Lba);\r
+      }\r
+      //\r
+      // Register this partition\r
+      //\r
+      if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {\r
+\r
+        Found                       = TRUE;\r
+\r
+        BlockDev                    = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);\r
+\r
+        BlockDev->BlockSize         = SubBlockSize;\r
+        BlockDev->LastBlock         = SectorCount - 1;\r
+        BlockDev->IoAlign           = ParentBlockDev->IoAlign;\r
+        BlockDev->Logical           = TRUE;\r
+        BlockDev->PartitionChecked  = FALSE;\r
+        BlockDev->StartingPos       = MultU64x32 (Catalog->Boot.Lba, ParentBlockDev->BlockSize);\r
+        BlockDev->ParentDevNo       = ParentBlockDevNo;\r
+\r
+        PrivateData->BlockDeviceCount++;\r
+      }\r
+    }\r
+  }\r
+\r
+  ParentBlockDev->PartitionChecked = TRUE;\r
+\r
+  return Found;\r
+\r
+}\r
index fc8d612283e5cfc345f915f2d178eaf25c9621d5..57312a90471d310737780ec6bdc9cf3a87b8b071 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 #    Lite Fat driver only used in Pei Phase.\r
 #\r
-#  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  This program and the accompanying materials are licensed and made available\r
 #  under the terms and conditions of the BSD License which accompanies this\r
@@ -30,6 +30,8 @@
 #\r
 \r
 [Sources]\r
+  Mbr.c\r
+  Eltorito.c\r
   Part.c\r
   FatLiteApi.c\r
   FatLiteLib.c\r
diff --git a/FatPkg/FatPei/Mbr.c b/FatPkg/FatPei/Mbr.c
new file mode 100644 (file)
index 0000000..acad6e7
--- /dev/null
@@ -0,0 +1,181 @@
+/** @file\r
+  Routines supporting partition discovery and\r
+  logical device reading\r
+\r
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials are licensed and made available\r
+under the terms and conditions of the BSD License which accompanies this\r
+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
+\r
+**/\r
+\r
+#include <IndustryStandard/Mbr.h>\r
+#include "FatLitePeim.h"\r
+\r
+/**\r
+  Test to see if the Mbr buffer is a valid MBR\r
+\r
+  @param[in]  Mbr               Parent Handle\r
+  @param[in]  LastLba           Last Lba address on the device.\r
+\r
+  @retval     TRUE              Mbr is a Valid MBR\r
+  @retval     FALSE             Mbr is not a Valid MBR\r
+\r
+**/\r
+BOOLEAN\r
+PartitionValidMbr (\r
+  IN  MASTER_BOOT_RECORD      *Mbr,\r
+  IN  EFI_PEI_LBA             LastLba\r
+  )\r
+{\r
+  UINT32  StartingLBA;\r
+  UINT32  EndingLBA;\r
+  UINT32  NewEndingLBA;\r
+  INTN    Index1;\r
+  INTN    Index2;\r
+  BOOLEAN MbrValid;\r
+\r
+  if (Mbr->Signature != MBR_SIGNATURE) {\r
+    return FALSE;\r
+  }\r
+  //\r
+  // The BPB also has this signature, so it can not be used alone.\r
+  //\r
+  MbrValid = FALSE;\r
+  for (Index1 = 0; Index1 < MAX_MBR_PARTITIONS; Index1++) {\r
+    if (Mbr->Partition[Index1].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) == 0) {\r
+      continue;\r
+    }\r
+\r
+    MbrValid    = TRUE;\r
+    StartingLBA = UNPACK_UINT32 (Mbr->Partition[Index1].StartingLBA);\r
+    EndingLBA   = StartingLBA + UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) - 1;\r
+    if (EndingLBA > LastLba) {\r
+      //\r
+      // Compatability Errata:\r
+      //  Some systems try to hide drive space with thier INT 13h driver\r
+      //  This does not hide space from the OS driver. This means the MBR\r
+      //  that gets created from DOS is smaller than the MBR created from\r
+      //  a real OS (NT & Win98). This leads to BlockIo->LastBlock being\r
+      //  wrong on some systems FDISKed by the OS.\r
+      //\r
+      //  return FALSE Because no block devices on a system are implemented\r
+      //  with INT 13h\r
+      //\r
+      return FALSE;\r
+    }\r
+\r
+    for (Index2 = Index1 + 1; Index2 < MAX_MBR_PARTITIONS; Index2++) {\r
+      if (Mbr->Partition[Index2].OSIndicator == 0x00 || UNPACK_INT32 (Mbr->Partition[Index2].SizeInLBA) == 0) {\r
+        continue;\r
+      }\r
+\r
+      NewEndingLBA = UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) + UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) - 1;\r
+      if (NewEndingLBA >= StartingLBA && UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) <= EndingLBA) {\r
+        //\r
+        // This region overlaps with the Index1'th region\r
+        //\r
+        return FALSE;\r
+      }\r
+    }\r
+  }\r
+  //\r
+  // Non of the regions overlapped so MBR is O.K.\r
+  //\r
+  return MbrValid;\r
+}\r
+\r
+/**\r
+  This function finds Mbr partitions. Main algorithm\r
+  is ported from DXE partition driver.\r
+\r
+  @param[in]  PrivateData       The global memory map\r
+  @param[in]  ParentBlockDevNo  The parent block device\r
+\r
+  @retval TRUE              New partitions are detected and logical block devices\r
+                            are added to block device array\r
+  @retval FALSE             No new partitions are added\r
+\r
+**/\r
+BOOLEAN\r
+FatFindMbrPartitions (\r
+  IN  PEI_FAT_PRIVATE_DATA *PrivateData,\r
+  IN  UINTN                ParentBlockDevNo\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  MASTER_BOOT_RECORD    *Mbr;\r
+  UINTN                 Index;\r
+  BOOLEAN               Found;\r
+  PEI_FAT_BLOCK_DEVICE  *ParentBlockDev;\r
+  PEI_FAT_BLOCK_DEVICE  *BlockDev;\r
+\r
+  if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {\r
+    return FALSE;\r
+  }\r
+\r
+  ParentBlockDev  = &(PrivateData->BlockDevice[ParentBlockDevNo]);\r
+\r
+  if (ParentBlockDev->BlockSize > PEI_FAT_MAX_BLOCK_SIZE) {\r
+    DEBUG((DEBUG_ERROR, "Device BlockSize %x exceeds FAT_MAX_BLOCK_SIZE\n", ParentBlockDev->BlockSize));\r
+    return FALSE;\r
+  }\r
+\r
+  Found           = FALSE;\r
+  Mbr             = (MASTER_BOOT_RECORD *) PrivateData->BlockData;\r
+\r
+  Status = FatReadBlock (\r
+            PrivateData,\r
+            ParentBlockDevNo,\r
+            0,\r
+            ParentBlockDev->BlockSize,\r
+            Mbr\r
+            );\r
+\r
+  if (EFI_ERROR (Status) || !PartitionValidMbr (Mbr, ParentBlockDev->LastBlock)) {\r
+    goto Done;\r
+  }\r
+  //\r
+  // We have a valid mbr - add each partition\r
+  //\r
+  for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {\r
+    if (Mbr->Partition[Index].OSIndicator == 0x00 || UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) == 0) {\r
+      //\r
+      // Don't use null MBR entries\r
+      //\r
+      continue;\r
+    }\r
+    //\r
+    // Register this partition\r
+    //\r
+    if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {\r
+\r
+      Found                       = TRUE;\r
+\r
+      BlockDev                    = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);\r
+\r
+      BlockDev->BlockSize         = MBR_SIZE;\r
+      BlockDev->LastBlock         = UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) - 1;\r
+      BlockDev->IoAlign           = ParentBlockDev->IoAlign;\r
+      BlockDev->Logical           = TRUE;\r
+      BlockDev->PartitionChecked  = FALSE;\r
+      BlockDev->StartingPos = MultU64x32 (\r
+                                UNPACK_INT32 (Mbr->Partition[Index].StartingLBA),\r
+                                ParentBlockDev->BlockSize\r
+                                );\r
+      BlockDev->ParentDevNo = ParentBlockDevNo;\r
+\r
+      PrivateData->BlockDeviceCount++;\r
+    }\r
+  }\r
+\r
+Done:\r
+\r
+  ParentBlockDev->PartitionChecked = TRUE;\r
+  return Found;\r
+}\r
index be185460f310914b35e4342bb672af0aed7d58ee..8a54e56f5ae6c452003fea6e6de9f0cc741a44a8 100644 (file)
@@ -2,7 +2,7 @@
   Routines supporting partition discovery and\r
   logical device reading\r
 \r
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
 \r
 This program and the accompanying materials are licensed and made available\r
 under the terms and conditions of the BSD License which accompanies this\r
@@ -14,20 +14,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include <IndustryStandard/Mbr.h>\r
-#include <IndustryStandard/ElTorito.h>\r
 #include "FatLitePeim.h"\r
 \r
 /**\r
   This function finds Eltorito partitions. Main algorithm\r
   is ported from DXE partition driver.\r
 \r
-  @param  PrivateData       The global memory map\r
-  @param  ParentBlockDevNo  The parent block device\r
+  @param[in]  PrivateData       The global memory map\r
+  @param[in]  ParentBlockDevNo  The parent block device\r
 \r
   @retval TRUE              New partitions are detected and logical block devices\r
-                            are  added to block device array\r
-  @retval FALSE             No New partitions are added;\r
+                            are added to block device array\r
+  @retval FALSE             No new partitions are added\r
 \r
 **/\r
 BOOLEAN\r
@@ -40,12 +38,12 @@ FatFindEltoritoPartitions (
   This function finds Mbr partitions. Main algorithm\r
   is ported from DXE partition driver.\r
 \r
-  @param  PrivateData       The global memory map\r
-  @param  ParentBlockDevNo  The parent block device\r
+  @param[in]  PrivateData       The global memory map\r
+  @param[in]  ParentBlockDevNo  The parent block device\r
 \r
   @retval TRUE              New partitions are detected and logical block devices\r
-                            are  added to block device array\r
-  @retval FALSE             No New partitions are added;\r
+                            are added to block device array\r
+  @retval FALSE             No new partitions are added\r
 \r
 **/\r
 BOOLEAN\r
@@ -54,7 +52,6 @@ FatFindMbrPartitions (
   IN  UINTN                ParentBlockDevNo\r
   );\r
 \r
-\r
 /**\r
   This function finds partitions (logical devices) in physical block devices.\r
 \r
@@ -83,384 +80,3 @@ FatFindPartitions (
   } while (Found && PrivateData->BlockDeviceCount <= PEI_FAT_MAX_BLOCK_DEVICE);\r
 }\r
 \r
-\r
-/**\r
-  This function finds Eltorito partitions. Main algorithm\r
-  is ported from DXE partition driver.\r
-\r
-  @param  PrivateData       The global memory map\r
-  @param  ParentBlockDevNo  The parent block device\r
-\r
-  @retval TRUE              New partitions are detected and logical block devices\r
-                            are  added to block device array\r
-  @retval FALSE             No New partitions are added;\r
-\r
-**/\r
-BOOLEAN\r
-FatFindEltoritoPartitions (\r
-  IN  PEI_FAT_PRIVATE_DATA *PrivateData,\r
-  IN  UINTN                ParentBlockDevNo\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  BOOLEAN                 Found;\r
-  PEI_FAT_BLOCK_DEVICE    *BlockDev;\r
-  PEI_FAT_BLOCK_DEVICE    *ParentBlockDev;\r
-  UINT32                  VolDescriptorLba;\r
-  UINT32                  Lba;\r
-  CDROM_VOLUME_DESCRIPTOR *VolDescriptor;\r
-  ELTORITO_CATALOG        *Catalog;\r
-  UINTN                   Check;\r
-  UINTN                   Index;\r
-  UINTN                   MaxIndex;\r
-  UINT16                  *CheckBuffer;\r
-  UINT32                  SubBlockSize;\r
-  UINT32                  SectorCount;\r
-  UINT32                  VolSpaceSize;\r
-\r
-  if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {\r
-    return FALSE;\r
-  }\r
-\r
-  Found           = FALSE;\r
-  ParentBlockDev  = &(PrivateData->BlockDevice[ParentBlockDevNo]);\r
-  VolSpaceSize    = 0;\r
-\r
-  //\r
-  // CD_ROM has the fixed block size as 2048 bytes\r
-  //\r
-  if (ParentBlockDev->BlockSize != 2048) {\r
-    return FALSE;\r
-  }\r
-\r
-  VolDescriptor = (CDROM_VOLUME_DESCRIPTOR *) PrivateData->BlockData;\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
-  VolDescriptorLba = 15;\r
-  //\r
-  // ((16*2048) / Media->BlockSize) - 1;\r
-  //\r
-  // Loop: handle one volume descriptor per time\r
-  //\r
-  while (TRUE) {\r
-\r
-    VolDescriptorLba += 1;\r
-    if (VolDescriptorLba > ParentBlockDev->LastBlock) {\r
-      //\r
-      // We are pointing past the end of the device so exit\r
-      //\r
-      break;\r
-    }\r
-\r
-    Status = FatReadBlock (\r
-              PrivateData,\r
-              ParentBlockDevNo,\r
-              VolDescriptorLba,\r
-              ParentBlockDev->BlockSize,\r
-              VolDescriptor\r
-              );\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-    //\r
-    // Check for valid volume descriptor signature\r
-    //\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
-      //\r
-      break;\r
-    }\r
-    //\r
-    // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte\r
-    //\r
-    if (VolDescriptor->Unknown.Type == CDVOL_TYPE_CODED) {\r
-      VolSpaceSize = VolDescriptor->PrimaryVolume.VolSpaceSize[1];\r
-    }\r
-    //\r
-    // Is it an El Torito volume descriptor?\r
-    //\r
-    if (CompareMem (\r
-          VolDescriptor->BootRecordVolume.SystemId,\r
-          CDVOL_ELTORITO_ID,\r
-          sizeof (CDVOL_ELTORITO_ID) - 1\r
-          ) != 0) {\r
-      continue;\r
-    }\r
-    //\r
-    // Read in the boot El Torito boot catalog\r
-    //\r
-    Lba = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog);\r
-    if (Lba > ParentBlockDev->LastBlock) {\r
-      continue;\r
-    }\r
-\r
-    Status = FatReadBlock (\r
-              PrivateData,\r
-              ParentBlockDevNo,\r
-              Lba,\r
-              ParentBlockDev->BlockSize,\r
-              Catalog\r
-              );\r
-    if (EFI_ERROR (Status)) {\r
-      continue;\r
-    }\r
-    //\r
-    // We don't care too much about the Catalog header's contents, but we do want\r
-    // to make sure it looks like a Catalog header\r
-    //\r
-    if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) {\r
-      continue;\r
-    }\r
-\r
-    Check       = 0;\r
-    CheckBuffer = (UINT16 *) Catalog;\r
-    for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) {\r
-      Check += CheckBuffer[Index];\r
-    }\r
-\r
-    if ((Check & 0xFFFF) != 0) {\r
-      continue;\r
-    }\r
-\r
-    MaxIndex = ParentBlockDev->BlockSize / sizeof (ELTORITO_CATALOG);\r
-    for (Index = 1; Index < MaxIndex; Index += 1) {\r
-      //\r
-      // Next entry\r
-      //\r
-      Catalog += 1;\r
-\r
-      //\r
-      // Check this entry\r
-      //\r
-      if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) {\r
-        continue;\r
-      }\r
-\r
-      SubBlockSize  = 512;\r
-      SectorCount   = Catalog->Boot.SectorCount;\r
-\r
-      switch (Catalog->Boot.MediaType) {\r
-\r
-      case ELTORITO_NO_EMULATION:\r
-        SubBlockSize  = ParentBlockDev->BlockSize;\r
-        SectorCount   = Catalog->Boot.SectorCount;\r
-        break;\r
-\r
-      case ELTORITO_HARD_DISK:\r
-        break;\r
-\r
-      case ELTORITO_12_DISKETTE:\r
-        SectorCount = 0x50 * 0x02 * 0x0F;\r
-        break;\r
-\r
-      case ELTORITO_14_DISKETTE:\r
-        SectorCount = 0x50 * 0x02 * 0x12;\r
-        break;\r
-\r
-      case ELTORITO_28_DISKETTE:\r
-        SectorCount = 0x50 * 0x02 * 0x24;\r
-        break;\r
-\r
-      default:\r
-        SectorCount   = 0;\r
-        SubBlockSize  = ParentBlockDev->BlockSize;\r
-        break;\r
-      }\r
-\r
-      if (SectorCount < 2) {\r
-        SectorCount = (VolSpaceSize > ParentBlockDev->LastBlock + 1) ? (UINT32) (ParentBlockDev->LastBlock - Catalog->Boot.Lba + 1) : (UINT32) (VolSpaceSize - Catalog->Boot.Lba);\r
-      }\r
-      //\r
-      // Register this partition\r
-      //\r
-      if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {\r
-\r
-        Found                       = TRUE;\r
-\r
-        BlockDev                    = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);\r
-\r
-        BlockDev->BlockSize         = SubBlockSize;\r
-        BlockDev->LastBlock         = SectorCount - 1;\r
-        BlockDev->IoAlign           = ParentBlockDev->IoAlign;\r
-        BlockDev->Logical           = TRUE;\r
-        BlockDev->PartitionChecked  = FALSE;\r
-        BlockDev->StartingPos       = MultU64x32 (Catalog->Boot.Lba, ParentBlockDev->BlockSize);\r
-        BlockDev->ParentDevNo       = ParentBlockDevNo;\r
-\r
-        PrivateData->BlockDeviceCount++;\r
-      }\r
-    }\r
-  }\r
-\r
-  ParentBlockDev->PartitionChecked = TRUE;\r
-\r
-  return Found;\r
-\r
-}\r
-\r
-\r
-/**\r
-  Test to see if the Mbr buffer is a valid MBR\r
-\r
-  @param  Mbr               Parent Handle\r
-  @param  LastLba           Last Lba address on the device.\r
-\r
-  @retval TRUE              Mbr is a Valid MBR\r
-  @retval FALSE             Mbr is not a Valid MBR\r
-\r
-**/\r
-BOOLEAN\r
-PartitionValidMbr (\r
-  IN  MASTER_BOOT_RECORD      *Mbr,\r
-  IN  EFI_PEI_LBA             LastLba\r
-  )\r
-{\r
-  UINT32  StartingLBA;\r
-  UINT32  EndingLBA;\r
-  UINT32  NewEndingLBA;\r
-  INTN    Index1;\r
-  INTN    Index2;\r
-  BOOLEAN MbrValid;\r
-\r
-  if (Mbr->Signature != MBR_SIGNATURE) {\r
-    return FALSE;\r
-  }\r
-  //\r
-  // The BPB also has this signature, so it can not be used alone.\r
-  //\r
-  MbrValid = FALSE;\r
-  for (Index1 = 0; Index1 < MAX_MBR_PARTITIONS; Index1++) {\r
-    if (Mbr->Partition[Index1].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) == 0) {\r
-      continue;\r
-    }\r
-\r
-    MbrValid    = TRUE;\r
-    StartingLBA = UNPACK_UINT32 (Mbr->Partition[Index1].StartingLBA);\r
-    EndingLBA   = StartingLBA + UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) - 1;\r
-    if (EndingLBA > LastLba) {\r
-      //\r
-      // Compatability Errata:\r
-      //  Some systems try to hide drive space with thier INT 13h driver\r
-      //  This does not hide space from the OS driver. This means the MBR\r
-      //  that gets created from DOS is smaller than the MBR created from\r
-      //  a real OS (NT & Win98). This leads to BlockIo->LastBlock being\r
-      //  wrong on some systems FDISKed by the OS.\r
-      //\r
-      //  return FALSE Because no block devices on a system are implemented\r
-      //  with INT 13h\r
-      //\r
-      return FALSE;\r
-    }\r
-\r
-    for (Index2 = Index1 + 1; Index2 < MAX_MBR_PARTITIONS; Index2++) {\r
-      if (Mbr->Partition[Index2].OSIndicator == 0x00 || UNPACK_INT32 (Mbr->Partition[Index2].SizeInLBA) == 0) {\r
-        continue;\r
-      }\r
-\r
-      NewEndingLBA = UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) + UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) - 1;\r
-      if (NewEndingLBA >= StartingLBA && UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) <= EndingLBA) {\r
-        //\r
-        // This region overlaps with the Index1'th region\r
-        //\r
-        return FALSE;\r
-      }\r
-    }\r
-  }\r
-  //\r
-  // Non of the regions overlapped so MBR is O.K.\r
-  //\r
-  return MbrValid;\r
-}\r
-\r
-\r
-/**\r
-  This function finds Mbr partitions. Main algorithm\r
-  is ported from DXE partition driver.\r
-\r
-  @param  PrivateData       The global memory map\r
-  @param  ParentBlockDevNo  The parent block device\r
-\r
-  @retval TRUE              New partitions are detected and logical block devices\r
-                            are  added to block device array\r
-  @retval FALSE             No New partitions are added;\r
-\r
-**/\r
-BOOLEAN\r
-FatFindMbrPartitions (\r
-  IN  PEI_FAT_PRIVATE_DATA *PrivateData,\r
-  IN  UINTN                ParentBlockDevNo\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  MASTER_BOOT_RECORD    *Mbr;\r
-  UINTN                 Index;\r
-  BOOLEAN               Found;\r
-  PEI_FAT_BLOCK_DEVICE  *ParentBlockDev;\r
-  PEI_FAT_BLOCK_DEVICE  *BlockDev;\r
-\r
-  if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {\r
-    return FALSE;\r
-  }\r
-\r
-  ParentBlockDev  = &(PrivateData->BlockDevice[ParentBlockDevNo]);\r
-\r
-  Found           = FALSE;\r
-  Mbr             = (MASTER_BOOT_RECORD *) PrivateData->BlockData;\r
-\r
-  Status = FatReadBlock (\r
-            PrivateData,\r
-            ParentBlockDevNo,\r
-            0,\r
-            ParentBlockDev->BlockSize,\r
-            Mbr\r
-            );\r
-\r
-  if (EFI_ERROR (Status) || !PartitionValidMbr (Mbr, ParentBlockDev->LastBlock)) {\r
-    goto Done;\r
-  }\r
-  //\r
-  // We have a valid mbr - add each partition\r
-  //\r
-  for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {\r
-    if (Mbr->Partition[Index].OSIndicator == 0x00 || UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) == 0) {\r
-      //\r
-      // Don't use null MBR entries\r
-      //\r
-      continue;\r
-    }\r
-    //\r
-    // Register this partition\r
-    //\r
-    if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {\r
-\r
-      Found                       = TRUE;\r
-\r
-      BlockDev                    = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);\r
-\r
-      BlockDev->BlockSize         = MBR_SIZE;\r
-      BlockDev->LastBlock         = UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) - 1;\r
-      BlockDev->IoAlign           = ParentBlockDev->IoAlign;\r
-      BlockDev->Logical           = TRUE;\r
-      BlockDev->PartitionChecked  = FALSE;\r
-      BlockDev->StartingPos = MultU64x32 (\r
-                                UNPACK_INT32 (Mbr->Partition[Index].StartingLBA),\r
-                                ParentBlockDev->BlockSize\r
-                                );\r
-      BlockDev->ParentDevNo = ParentBlockDevNo;\r
-\r
-      PrivateData->BlockDeviceCount++;\r
-    }\r
-  }\r
-\r
-Done:\r
-\r
-  ParentBlockDev->PartitionChecked = TRUE;\r
-  return Found;\r
-}\r