-/*++\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
- \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
-Module Name:\r
-\r
- Mbr.c\r
- \r
-Abstract:\r
-\r
+/** @file\r
Decode a hard disk partitioned with the legacy MBR found on most PC's\r
\r
MBR - Master Boot Record is in the first sector of a partitioned hard disk.\r
The MBR supports four partitions per disk. The MBR also contains legacy\r
- code that is not run on an EFI system. The legacy code reads the \r
- first sector of the active partition into memory and \r
+ code that is not run on an EFI system. The legacy code reads the\r
+ first sector of the active partition into memory and\r
\r
- BPB - Boot(?) Parameter Block is in the first sector of a FAT file system. \r
- The BPB contains information about the FAT file system. The BPB is \r
+ BPB - BIOS Parameter Block is in the first sector of a FAT file system.\r
+ The BPB contains information about the FAT file system. The BPB is\r
always on the first sector of a media. The first sector also contains\r
the legacy boot strap code.\r
\r
---*/\r
+Copyright (c) 2018 Qualcomm Datacenter Technologies, Inc.\r
+Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>\r
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
\r
#include "Partition.h"\r
\r
-STATIC\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_LBA LastLba\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Test to see if the Mbr buffer is a valid MBR\r
-\r
-Arguments: \r
- Mbr - Parent Handle \r
- LastLba - Last Lba address on the device.\r
-\r
-Returns:\r
- TRUE - Mbr is a Valid MBR\r
- FALSE - Mbr is not a Valid MBR\r
-\r
---*/\r
{\r
UINT32 StartingLBA;\r
UINT32 EndingLBA;\r
// return FALSE since no block devices on a system are implemented\r
// with INT 13h\r
//\r
+\r
+ DEBUG((EFI_D_INFO, "PartitionValidMbr: Bad MBR partition size EndingLBA(%1x) > LastLBA(%1x)\n", EndingLBA, LastLba));\r
+\r
return FALSE;\r
}\r
\r
}\r
}\r
//\r
- // Non of the regions overlapped so MBR is O.K.\r
+ // None of the regions overlapped so MBR is O.K.\r
//\r
return MbrValid;\r
}\r
\r
+\r
+/**\r
+ Install child handles if the Handle supports MBR format.\r
+\r
+ @param[in] This Calling context.\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
+ @retval EFI_SUCCESS A child handle was added.\r
+ @retval EFI_MEDIA_CHANGED Media change was detected.\r
+ @retval Others MBR partition was not found.\r
+\r
+**/\r
EFI_STATUS\r
PartitionInstallMbrChildHandles (\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
-\r
-Routine Description:\r
- Install child handles if the Handle supports MBR format.\r
+{\r
+ EFI_STATUS Status;\r
+ MASTER_BOOT_RECORD *Mbr;\r
+ UINT32 ExtMbrStartingLba;\r
+ UINT32 Index;\r
+ HARDDRIVE_DEVICE_PATH HdDev;\r
+ HARDDRIVE_DEVICE_PATH ParentHdDev;\r
+ EFI_STATUS Found;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;\r
+ EFI_DEVICE_PATH_PROTOCOL *LastDevicePathNode;\r
+ UINT32 BlockSize;\r
+ UINT32 MediaId;\r
+ EFI_LBA LastSector;\r
+ EFI_PARTITION_INFO_PROTOCOL PartitionInfo;\r
\r
-Arguments: \r
- This - Calling context.\r
- Handle - Parent Handle \r
- DiskIo - Parent DiskIo interface\r
- BlockIo - Parent BlockIo interface\r
- DevicePath - Parent Device Path\r
+ Found = EFI_NOT_FOUND;\r
\r
-Returns:\r
- EFI_SUCCESS - If a child handle was added\r
- EFI_MEDIA_CHANGED - Media changed Detected\r
- !EFI_SUCCESS - Not found MBR partition.\r
+ BlockSize = BlockIo->Media->BlockSize;\r
+ MediaId = BlockIo->Media->MediaId;\r
+ LastSector = DivU64x32 (\r
+ MultU64x32 (BlockIo->Media->LastBlock + 1, BlockSize),\r
+ MBR_SIZE\r
+ ) - 1;\r
\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- MASTER_BOOT_RECORD *Mbr;\r
- UINT32 ExtMbrStartingLba;\r
- UINTN Index;\r
- HARDDRIVE_DEVICE_PATH HdDev;\r
- HARDDRIVE_DEVICE_PATH ParentHdDev;\r
- EFI_STATUS Found;\r
- UINT32 PartitionNumber;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;\r
- EFI_DEVICE_PATH_PROTOCOL *LastDevicePathNode;\r
-\r
- Mbr = NULL;\r
- Found = EFI_NOT_FOUND;\r
+ //\r
+ // Ensure the block size can hold the MBR\r
+ //\r
+ if (BlockSize < sizeof (MASTER_BOOT_RECORD)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
\r
- Mbr = AllocatePool (BlockIo->Media->BlockSize);\r
+ Mbr = AllocatePool (BlockSize);\r
if (Mbr == NULL) {\r
- goto Done;\r
+ return Found;\r
}\r
\r
- Status = BlockIo->ReadBlocks (\r
- BlockIo,\r
- BlockIo->Media->MediaId,\r
- 0,\r
- BlockIo->Media->BlockSize,\r
- Mbr\r
- );\r
+ Status = DiskIo->ReadDisk (\r
+ DiskIo,\r
+ MediaId,\r
+ 0,\r
+ BlockSize,\r
+ Mbr\r
+ );\r
if (EFI_ERROR (Status)) {\r
Found = Status;\r
goto Done;\r
}\r
- if (!PartitionValidMbr (Mbr, BlockIo->Media->LastBlock)) {\r
+ if (!PartitionValidMbr (Mbr, LastSector)) {\r
goto Done;\r
}\r
//\r
LastDevicePathNode = NULL;\r
ZeroMem (&ParentHdDev, sizeof (ParentHdDev));\r
DevicePathNode = DevicePath;\r
- while (!EfiIsDevicePathEnd (DevicePathNode)) {\r
+ while (!IsDevicePathEnd (DevicePathNode)) {\r
LastDevicePathNode = DevicePathNode;\r
- DevicePathNode = EfiNextDevicePathNode (DevicePathNode);\r
+ DevicePathNode = NextDevicePathNode (DevicePathNode);\r
}\r
\r
if (LastDevicePathNode != NULL) {\r
}\r
}\r
\r
- PartitionNumber = 1;\r
-\r
ZeroMem (&HdDev, sizeof (HdDev));\r
HdDev.Header.Type = MEDIA_DEVICE_PATH;\r
HdDev.Header.SubType = MEDIA_HARDDRIVE_DP;\r
if (Mbr->Partition[Index].OSIndicator == PMBR_GPT_PARTITION) {\r
//\r
// This is the guard MBR for the GPT. If you ever see a GPT disk with zero partitions you can get here.\r
- // We can not produce an MBR BlockIo for this device as the MBR spans the GPT headers. So formating \r
+ // We can not produce an MBR BlockIo for this device as the MBR spans the GPT headers. So formating\r
// this BlockIo would corrupt the GPT structures and require a recovery that would corrupt the format\r
- // that corrupted the GPT partition. \r
+ // that corrupted the GPT partition.\r
//\r
continue;\r
}\r
\r
- HdDev.PartitionNumber = PartitionNumber ++;\r
+ HdDev.PartitionNumber = Index + 1;\r
HdDev.PartitionStart = UNPACK_UINT32 (Mbr->Partition[Index].StartingLBA);\r
HdDev.PartitionSize = UNPACK_UINT32 (Mbr->Partition[Index].SizeInLBA);\r
- CopyMem (HdDev.Signature, &(Mbr->UniqueMbrSignature[0]), sizeof (UINT32));\r
+ CopyMem (HdDev.Signature, &(Mbr->UniqueMbrSignature[0]), sizeof (Mbr->UniqueMbrSignature));\r
+\r
+ ZeroMem (&PartitionInfo, sizeof (EFI_PARTITION_INFO_PROTOCOL));\r
+ PartitionInfo.Revision = EFI_PARTITION_INFO_PROTOCOL_REVISION;\r
+ PartitionInfo.Type = PARTITION_TYPE_MBR;\r
+ if (Mbr->Partition[Index].OSIndicator == EFI_PARTITION) {\r
+ PartitionInfo.System = 1;\r
+ }\r
+ CopyMem (&PartitionInfo.Info.Mbr, &Mbr->Partition[Index], sizeof (MBR_PARTITION_RECORD));\r
\r
Status = PartitionInstallChildHandle (\r
This,\r
Handle,\r
DiskIo,\r
+ DiskIo2,\r
BlockIo,\r
+ BlockIo2,\r
DevicePath,\r
(EFI_DEVICE_PATH_PROTOCOL *) &HdDev,\r
+ &PartitionInfo,\r
HdDev.PartitionStart,\r
HdDev.PartitionStart + HdDev.PartitionSize - 1,\r
MBR_SIZE,\r
- (BOOLEAN) (Mbr->Partition[Index].OSIndicator == EFI_PARTITION)\r
+ ((Mbr->Partition[Index].OSIndicator == EFI_PARTITION) ? &gEfiPartTypeSystemPartGuid: NULL)\r
);\r
\r
if (!EFI_ERROR (Status)) {\r
// It's an extended partition. Follow the extended partition\r
// chain to get all the logical drives\r
//\r
+ Index = 0;\r
ExtMbrStartingLba = 0;\r
\r
do {\r
\r
- Status = BlockIo->ReadBlocks (\r
- BlockIo,\r
- BlockIo->Media->MediaId,\r
- ExtMbrStartingLba,\r
- BlockIo->Media->BlockSize,\r
- Mbr\r
- );\r
+ Status = DiskIo->ReadDisk (\r
+ DiskIo,\r
+ MediaId,\r
+ MultU64x32 (ExtMbrStartingLba, BlockSize),\r
+ BlockSize,\r
+ Mbr\r
+ );\r
if (EFI_ERROR (Status)) {\r
Found = Status;\r
goto Done;\r
ExtMbrStartingLba = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA);\r
continue;\r
}\r
- HdDev.PartitionNumber = PartitionNumber ++;\r
+ HdDev.PartitionNumber = ++Index;\r
HdDev.PartitionStart = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA) + ExtMbrStartingLba + ParentHdDev.PartitionStart;\r
HdDev.PartitionSize = UNPACK_UINT32 (Mbr->Partition[0].SizeInLBA);\r
if ((HdDev.PartitionStart + HdDev.PartitionSize - 1 >= ParentHdDev.PartitionStart + ParentHdDev.PartitionSize) ||\r
//\r
*((UINT32 *) &HdDev.Signature[0]) = 0;\r
\r
+ ZeroMem (&PartitionInfo, sizeof (EFI_PARTITION_INFO_PROTOCOL));\r
+ PartitionInfo.Revision = EFI_PARTITION_INFO_PROTOCOL_REVISION;\r
+ PartitionInfo.Type = PARTITION_TYPE_MBR;\r
+ if (Mbr->Partition[0].OSIndicator == EFI_PARTITION) {\r
+ PartitionInfo.System = 1;\r
+ }\r
+ CopyMem (&PartitionInfo.Info.Mbr, &Mbr->Partition[0], sizeof (MBR_PARTITION_RECORD));\r
+\r
Status = PartitionInstallChildHandle (\r
- This,\r
- Handle,\r
- DiskIo,\r
- BlockIo,\r
- DevicePath,\r
- (EFI_DEVICE_PATH_PROTOCOL *) &HdDev,\r
- HdDev.PartitionStart - ParentHdDev.PartitionStart,\r
- HdDev.PartitionStart - ParentHdDev.PartitionStart + HdDev.PartitionSize - 1,\r
- MBR_SIZE,\r
- (BOOLEAN) (Mbr->Partition[0].OSIndicator == EFI_PARTITION)\r
- );\r
+ This,\r
+ Handle,\r
+ DiskIo,\r
+ DiskIo2,\r
+ BlockIo,\r
+ BlockIo2,\r
+ DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *) &HdDev,\r
+ &PartitionInfo,\r
+ HdDev.PartitionStart - ParentHdDev.PartitionStart,\r
+ HdDev.PartitionStart - ParentHdDev.PartitionStart + HdDev.PartitionSize - 1,\r
+ MBR_SIZE,\r
+ ((Mbr->Partition[0].OSIndicator == EFI_PARTITION) ? &gEfiPartTypeSystemPartGuid: NULL)\r
+ );\r
if (!EFI_ERROR (Status)) {\r
Found = EFI_SUCCESS;\r
}\r