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