VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/FatPkg/FatPei/Mbr.c

Last change on this file was 99404, checked in by vboxsync, 19 months ago

Devices/EFI/FirmwareNew: Update to edk2-stable202302 and make it build, bugref:4643

  • Property svn:eol-style set to native
File size: 5.0 KB
Line 
1/** @file
2 Routines supporting partition discovery and
3 logical device reading
4
5Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
6
7SPDX-License-Identifier: BSD-2-Clause-Patent
8
9**/
10
11#include <IndustryStandard/Mbr.h>
12#include "FatLitePeim.h"
13
14/**
15 Test to see if the Mbr buffer is a valid MBR
16
17 @param[in] Mbr Parent Handle
18 @param[in] LastLba Last Lba address on the device.
19
20 @retval TRUE Mbr is a Valid MBR
21 @retval FALSE Mbr is not a Valid MBR
22
23**/
24BOOLEAN
25PartitionValidMbr (
26 IN MASTER_BOOT_RECORD *Mbr,
27 IN EFI_PEI_LBA LastLba
28 )
29{
30 UINT32 StartingLBA;
31 UINT32 EndingLBA;
32 UINT32 NewEndingLBA;
33 INTN Index1;
34 INTN Index2;
35 BOOLEAN MbrValid;
36
37 if (Mbr->Signature != MBR_SIGNATURE) {
38 return FALSE;
39 }
40
41 //
42 // The BPB also has this signature, so it can not be used alone.
43 //
44 MbrValid = FALSE;
45 for (Index1 = 0; Index1 < MAX_MBR_PARTITIONS; Index1++) {
46 if ((Mbr->Partition[Index1].OSIndicator == 0x00) || (UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) == 0)) {
47 continue;
48 }
49
50 MbrValid = TRUE;
51 StartingLBA = UNPACK_UINT32 (Mbr->Partition[Index1].StartingLBA);
52 EndingLBA = StartingLBA + UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) - 1;
53 if (EndingLBA > LastLba) {
54 //
55 // Compatibility Errata:
56 // Some systems try to hide drive space with their INT 13h driver
57 // This does not hide space from the OS driver. This means the MBR
58 // that gets created from DOS is smaller than the MBR created from
59 // a real OS (NT & Win98). This leads to BlockIo->LastBlock being
60 // wrong on some systems FDISKed by the OS.
61 //
62 // return FALSE Because no block devices on a system are implemented
63 // with INT 13h
64 //
65 return FALSE;
66 }
67
68 for (Index2 = Index1 + 1; Index2 < MAX_MBR_PARTITIONS; Index2++) {
69 if ((Mbr->Partition[Index2].OSIndicator == 0x00) || (UNPACK_INT32 (Mbr->Partition[Index2].SizeInLBA) == 0)) {
70 continue;
71 }
72
73 NewEndingLBA = UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) + UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) - 1;
74 if ((NewEndingLBA >= StartingLBA) && (UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) <= EndingLBA)) {
75 //
76 // This region overlaps with the Index1'th region
77 //
78 return FALSE;
79 }
80 }
81 }
82
83 //
84 // Non of the regions overlapped so MBR is O.K.
85 //
86 return MbrValid;
87}
88
89/**
90 This function finds Mbr partitions. Main algorithm
91 is ported from DXE partition driver.
92
93 @param[in] PrivateData The global memory map
94 @param[in] ParentBlockDevNo The parent block device
95
96 @retval TRUE New partitions are detected and logical block devices
97 are added to block device array
98 @retval FALSE No new partitions are added
99
100**/
101BOOLEAN
102FatFindMbrPartitions (
103 IN PEI_FAT_PRIVATE_DATA *PrivateData,
104 IN UINTN ParentBlockDevNo
105 )
106{
107 EFI_STATUS Status;
108 MASTER_BOOT_RECORD *Mbr;
109 UINTN Index;
110 BOOLEAN Found;
111 PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
112 PEI_FAT_BLOCK_DEVICE *BlockDev;
113
114 if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {
115 return FALSE;
116 }
117
118 ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
119
120 if (ParentBlockDev->BlockSize > PEI_FAT_MAX_BLOCK_SIZE) {
121 DEBUG ((DEBUG_ERROR, "Device BlockSize %x exceeds FAT_MAX_BLOCK_SIZE\n", ParentBlockDev->BlockSize));
122 return FALSE;
123 }
124
125 Found = FALSE;
126 Mbr = (MASTER_BOOT_RECORD *)PrivateData->BlockData;
127
128 Status = FatReadBlock (
129 PrivateData,
130 ParentBlockDevNo,
131 0,
132 ParentBlockDev->BlockSize,
133 Mbr
134 );
135
136 if (EFI_ERROR (Status) || !PartitionValidMbr (Mbr, ParentBlockDev->LastBlock)) {
137 goto Done;
138 }
139
140 //
141 // We have a valid mbr - add each partition
142 //
143 for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {
144 if ((Mbr->Partition[Index].OSIndicator == 0x00) || (UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) == 0)) {
145 //
146 // Don't use null MBR entries
147 //
148 continue;
149 }
150
151 //
152 // Register this partition
153 //
154 if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {
155 Found = TRUE;
156
157 BlockDev = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);
158
159 BlockDev->BlockSize = MBR_SIZE;
160 BlockDev->LastBlock = UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) - 1;
161 BlockDev->IoAlign = ParentBlockDev->IoAlign;
162 BlockDev->Logical = TRUE;
163 BlockDev->PartitionChecked = FALSE;
164 BlockDev->StartingPos = MultU64x32 (
165 UNPACK_INT32 (Mbr->Partition[Index].StartingLBA),
166 ParentBlockDev->BlockSize
167 );
168 BlockDev->ParentDevNo = ParentBlockDevNo;
169
170 PrivateData->BlockDeviceCount++;
171 }
172 }
173
174Done:
175
176 ParentBlockDev->PartitionChecked = TRUE;
177 return Found;
178}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette