2 Decode a hard disk partitioned with the GPT scheme in the UEFI 2.0
5 Caution: This file requires additional review when modified.
6 This driver will have external input - disk partition.
7 This external input must be validated carefully to avoid security issue like
8 buffer overflow, integer overflow.
10 PartitionInstallGptChildHandles() routine will read disk partition content and
11 do basic validation before PartitionInstallChildHandle().
13 PartitionValidGptTable(), PartitionCheckGptEntry() routine will accept disk
14 partition content and validate the GPT table and GPT entry.
16 Copyright (c) 2018 Qualcomm Datacenter Technologies, Inc.
17 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
18 This program and the accompanying materials
19 are licensed and made available under the terms and conditions of the BSD License
20 which accompanies this distribution. The full text of the license may be found at
21 http://opensource.org/licenses/bsd-license.php
23 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
24 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
29 #include "Partition.h"
32 Install child handles if the Handle supports GPT partition structure.
34 Caution: This function may receive untrusted input.
35 The GPT partition table header is external input, so this routine
36 will do basic validation for GPT partition table header before return.
38 @param[in] BlockIo Parent BlockIo interface.
39 @param[in] DiskIo Disk Io protocol.
40 @param[in] Lba The starting Lba of the Partition Table
41 @param[out] PartHeader Stores the partition table that is read
43 @retval TRUE The partition table is valid
44 @retval FALSE The partition table is not valid
48 PartitionValidGptTable (
49 IN EFI_BLOCK_IO_PROTOCOL
*BlockIo
,
50 IN EFI_DISK_IO_PROTOCOL
*DiskIo
,
52 OUT EFI_PARTITION_TABLE_HEADER
*PartHeader
56 Check if the CRC field in the Partition table header is valid
57 for Partition entry array.
59 @param[in] BlockIo Parent BlockIo interface
60 @param[in] DiskIo Disk Io Protocol.
61 @param[in] PartHeader Partition table header structure
63 @retval TRUE the CRC is valid
64 @retval FALSE the CRC is invalid
68 PartitionCheckGptEntryArrayCRC (
69 IN EFI_BLOCK_IO_PROTOCOL
*BlockIo
,
70 IN EFI_DISK_IO_PROTOCOL
*DiskIo
,
71 IN EFI_PARTITION_TABLE_HEADER
*PartHeader
76 Restore Partition Table to its alternate place
77 (Primary -> Backup or Backup -> Primary).
79 @param[in] BlockIo Parent BlockIo interface.
80 @param[in] DiskIo Disk Io Protocol.
81 @param[in] PartHeader Partition table header structure.
83 @retval TRUE Restoring succeeds
84 @retval FALSE Restoring failed
88 PartitionRestoreGptTable (
89 IN EFI_BLOCK_IO_PROTOCOL
*BlockIo
,
90 IN EFI_DISK_IO_PROTOCOL
*DiskIo
,
91 IN EFI_PARTITION_TABLE_HEADER
*PartHeader
96 This routine will check GPT partition entry and return entry status.
98 Caution: This function may receive untrusted input.
99 The GPT partition entry is external input, so this routine
100 will do basic validation for GPT partition entry and report status.
102 @param[in] PartHeader Partition table header structure
103 @param[in] PartEntry The partition entry array
104 @param[out] PEntryStatus the partition entry status array
105 recording the status of each partition
109 PartitionCheckGptEntry (
110 IN EFI_PARTITION_TABLE_HEADER
*PartHeader
,
111 IN EFI_PARTITION_ENTRY
*PartEntry
,
112 OUT EFI_PARTITION_ENTRY_STATUS
*PEntryStatus
117 Checks the CRC32 value in the table header.
119 @param MaxSize Max Size limit
120 @param Size The size of the table
121 @param Hdr Table to check
123 @return TRUE CRC Valid
124 @return FALSE CRC Invalid
128 PartitionCheckCrcAltSize (
131 IN OUT EFI_TABLE_HEADER
*Hdr
136 Checks the CRC32 value in the table header.
138 @param MaxSize Max Size limit
139 @param Hdr Table to check
141 @return TRUE CRC Valid
142 @return FALSE CRC Invalid
148 IN OUT EFI_TABLE_HEADER
*Hdr
153 Updates the CRC32 value in the table header.
155 @param Size The size of the table
156 @param Hdr Table to update
160 PartitionSetCrcAltSize (
162 IN OUT EFI_TABLE_HEADER
*Hdr
167 Updates the CRC32 value in the table header.
169 @param Hdr Table to update
174 IN OUT EFI_TABLE_HEADER
*Hdr
178 Install child handles if the Handle supports GPT partition structure.
180 Caution: This function may receive untrusted input.
181 The GPT partition table is external input, so this routine
182 will do basic validation for GPT partition table before install
183 child handle for each GPT partition.
185 @param[in] This Calling context.
186 @param[in] Handle Parent Handle.
187 @param[in] DiskIo Parent DiskIo interface.
188 @param[in] DiskIo2 Parent DiskIo2 interface.
189 @param[in] BlockIo Parent BlockIo interface.
190 @param[in] BlockIo2 Parent BlockIo2 interface.
191 @param[in] DevicePath Parent Device Path.
193 @retval EFI_SUCCESS Valid GPT disk.
194 @retval EFI_MEDIA_CHANGED Media changed Detected.
195 @retval other Not a valid GPT disk.
199 PartitionInstallGptChildHandles (
200 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
201 IN EFI_HANDLE Handle
,
202 IN EFI_DISK_IO_PROTOCOL
*DiskIo
,
203 IN EFI_DISK_IO2_PROTOCOL
*DiskIo2
,
204 IN EFI_BLOCK_IO_PROTOCOL
*BlockIo
,
205 IN EFI_BLOCK_IO2_PROTOCOL
*BlockIo2
,
206 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
212 MASTER_BOOT_RECORD
*ProtectiveMbr
;
213 EFI_PARTITION_TABLE_HEADER
*PrimaryHeader
;
214 EFI_PARTITION_TABLE_HEADER
*BackupHeader
;
215 EFI_PARTITION_ENTRY
*PartEntry
;
216 EFI_PARTITION_ENTRY
*Entry
;
217 EFI_PARTITION_ENTRY_STATUS
*PEntryStatus
;
219 EFI_STATUS GptValidStatus
;
220 HARDDRIVE_DEVICE_PATH HdDev
;
222 EFI_PARTITION_INFO_PROTOCOL PartitionInfo
;
224 ProtectiveMbr
= NULL
;
225 PrimaryHeader
= NULL
;
230 BlockSize
= BlockIo
->Media
->BlockSize
;
231 LastBlock
= BlockIo
->Media
->LastBlock
;
232 MediaId
= BlockIo
->Media
->MediaId
;
234 DEBUG ((EFI_D_INFO
, " BlockSize : %d \n", BlockSize
));
235 DEBUG ((EFI_D_INFO
, " LastBlock : %lx \n", LastBlock
));
237 GptValidStatus
= EFI_NOT_FOUND
;
240 // Ensure the block size can hold the MBR
242 if (BlockSize
< sizeof (MASTER_BOOT_RECORD
)) {
243 return EFI_NOT_FOUND
;
247 // Allocate a buffer for the Protective MBR
249 ProtectiveMbr
= AllocatePool (BlockSize
);
250 if (ProtectiveMbr
== NULL
) {
251 return EFI_NOT_FOUND
;
255 // Read the Protective MBR from LBA #0
257 Status
= DiskIo
->ReadDisk (
264 if (EFI_ERROR (Status
)) {
265 GptValidStatus
= Status
;
270 // Verify that the Protective MBR is valid
272 for (Index
= 0; Index
< MAX_MBR_PARTITIONS
; Index
++) {
273 if (ProtectiveMbr
->Partition
[Index
].BootIndicator
== 0x00 &&
274 ProtectiveMbr
->Partition
[Index
].OSIndicator
== PMBR_GPT_PARTITION
&&
275 UNPACK_UINT32 (ProtectiveMbr
->Partition
[Index
].StartingLBA
) == 1
280 if (Index
== MAX_MBR_PARTITIONS
) {
285 // Allocate the GPT structures
287 PrimaryHeader
= AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER
));
288 if (PrimaryHeader
== NULL
) {
292 BackupHeader
= AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER
));
293 if (BackupHeader
== NULL
) {
298 // Check primary and backup partition tables
300 if (!PartitionValidGptTable (BlockIo
, DiskIo
, PRIMARY_PART_HEADER_LBA
, PrimaryHeader
)) {
301 DEBUG ((EFI_D_INFO
, " Not Valid primary partition table\n"));
303 if (!PartitionValidGptTable (BlockIo
, DiskIo
, LastBlock
, BackupHeader
)) {
304 DEBUG ((EFI_D_INFO
, " Not Valid backup partition table\n"));
307 DEBUG ((EFI_D_INFO
, " Valid backup partition table\n"));
308 DEBUG ((EFI_D_INFO
, " Restore primary partition table by the backup\n"));
309 if (!PartitionRestoreGptTable (BlockIo
, DiskIo
, BackupHeader
)) {
310 DEBUG ((EFI_D_INFO
, " Restore primary partition table error\n"));
313 if (PartitionValidGptTable (BlockIo
, DiskIo
, BackupHeader
->AlternateLBA
, PrimaryHeader
)) {
314 DEBUG ((EFI_D_INFO
, " Restore backup partition table success\n"));
317 } else if (!PartitionValidGptTable (BlockIo
, DiskIo
, PrimaryHeader
->AlternateLBA
, BackupHeader
)) {
318 DEBUG ((EFI_D_INFO
, " Valid primary and !Valid backup partition table\n"));
319 DEBUG ((EFI_D_INFO
, " Restore backup partition table by the primary\n"));
320 if (!PartitionRestoreGptTable (BlockIo
, DiskIo
, PrimaryHeader
)) {
321 DEBUG ((EFI_D_INFO
, " Restore backup partition table error\n"));
324 if (PartitionValidGptTable (BlockIo
, DiskIo
, PrimaryHeader
->AlternateLBA
, BackupHeader
)) {
325 DEBUG ((EFI_D_INFO
, " Restore backup partition table success\n"));
330 DEBUG ((EFI_D_INFO
, " Valid primary and Valid backup partition table\n"));
333 // Read the EFI Partition Entries
335 PartEntry
= AllocatePool (PrimaryHeader
->NumberOfPartitionEntries
* PrimaryHeader
->SizeOfPartitionEntry
);
336 if (PartEntry
== NULL
) {
337 DEBUG ((EFI_D_ERROR
, "Allocate pool error\n"));
341 Status
= DiskIo
->ReadDisk (
344 MultU64x32(PrimaryHeader
->PartitionEntryLBA
, BlockSize
),
345 PrimaryHeader
->NumberOfPartitionEntries
* (PrimaryHeader
->SizeOfPartitionEntry
),
348 if (EFI_ERROR (Status
)) {
349 GptValidStatus
= Status
;
350 DEBUG ((EFI_D_ERROR
, " Partition Entry ReadDisk error\n"));
354 DEBUG ((EFI_D_INFO
, " Partition entries read block success\n"));
356 DEBUG ((EFI_D_INFO
, " Number of partition entries: %d\n", PrimaryHeader
->NumberOfPartitionEntries
));
358 PEntryStatus
= AllocateZeroPool (PrimaryHeader
->NumberOfPartitionEntries
* sizeof (EFI_PARTITION_ENTRY_STATUS
));
359 if (PEntryStatus
== NULL
) {
360 DEBUG ((EFI_D_ERROR
, "Allocate pool error\n"));
365 // Check the integrity of partition entries
367 PartitionCheckGptEntry (PrimaryHeader
, PartEntry
, PEntryStatus
);
370 // If we got this far the GPT layout of the disk is valid and we should return true
372 GptValidStatus
= EFI_SUCCESS
;
375 // Create child device handles
377 for (Index
= 0; Index
< PrimaryHeader
->NumberOfPartitionEntries
; Index
++) {
378 Entry
= (EFI_PARTITION_ENTRY
*) ((UINT8
*) PartEntry
+ Index
* PrimaryHeader
->SizeOfPartitionEntry
);
379 if (CompareGuid (&Entry
->PartitionTypeGUID
, &gEfiPartTypeUnusedGuid
) ||
380 PEntryStatus
[Index
].OutOfRange
||
381 PEntryStatus
[Index
].Overlap
||
382 PEntryStatus
[Index
].OsSpecific
385 // Don't use null EFI Partition Entries, Invalid Partition Entries or OS specific
391 ZeroMem (&HdDev
, sizeof (HdDev
));
392 HdDev
.Header
.Type
= MEDIA_DEVICE_PATH
;
393 HdDev
.Header
.SubType
= MEDIA_HARDDRIVE_DP
;
394 SetDevicePathNodeLength (&HdDev
.Header
, sizeof (HdDev
));
396 HdDev
.PartitionNumber
= (UINT32
) Index
+ 1;
397 HdDev
.MBRType
= MBR_TYPE_EFI_PARTITION_TABLE_HEADER
;
398 HdDev
.SignatureType
= SIGNATURE_TYPE_GUID
;
399 HdDev
.PartitionStart
= Entry
->StartingLBA
;
400 HdDev
.PartitionSize
= Entry
->EndingLBA
- Entry
->StartingLBA
+ 1;
401 CopyMem (HdDev
.Signature
, &Entry
->UniquePartitionGUID
, sizeof (EFI_GUID
));
403 ZeroMem (&PartitionInfo
, sizeof (EFI_PARTITION_INFO_PROTOCOL
));
404 PartitionInfo
.Revision
= EFI_PARTITION_INFO_PROTOCOL_REVISION
;
405 PartitionInfo
.Type
= PARTITION_TYPE_GPT
;
406 if (CompareGuid (&Entry
->PartitionTypeGUID
, &gEfiPartTypeSystemPartGuid
)) {
407 PartitionInfo
.System
= 1;
409 CopyMem (&PartitionInfo
.Info
.Gpt
, Entry
, sizeof (EFI_PARTITION_ENTRY
));
411 DEBUG ((EFI_D_INFO
, " Index : %d\n", (UINT32
) Index
));
412 DEBUG ((EFI_D_INFO
, " Start LBA : %lx\n", (UINT64
) HdDev
.PartitionStart
));
413 DEBUG ((EFI_D_INFO
, " End LBA : %lx\n", (UINT64
) Entry
->EndingLBA
));
414 DEBUG ((EFI_D_INFO
, " Partition size: %lx\n", (UINT64
) HdDev
.PartitionSize
));
415 DEBUG ((EFI_D_INFO
, " Start : %lx", MultU64x32 (Entry
->StartingLBA
, BlockSize
)));
416 DEBUG ((EFI_D_INFO
, " End : %lx\n", MultU64x32 (Entry
->EndingLBA
, BlockSize
)));
418 Status
= PartitionInstallChildHandle (
426 (EFI_DEVICE_PATH_PROTOCOL
*) &HdDev
,
431 &Entry
->PartitionTypeGUID
435 DEBUG ((EFI_D_INFO
, "Prepare to Free Pool\n"));
438 if (ProtectiveMbr
!= NULL
) {
439 FreePool (ProtectiveMbr
);
441 if (PrimaryHeader
!= NULL
) {
442 FreePool (PrimaryHeader
);
444 if (BackupHeader
!= NULL
) {
445 FreePool (BackupHeader
);
447 if (PartEntry
!= NULL
) {
448 FreePool (PartEntry
);
450 if (PEntryStatus
!= NULL
) {
451 FreePool (PEntryStatus
);
454 return GptValidStatus
;
458 This routine will read GPT partition table header and return it.
460 Caution: This function may receive untrusted input.
461 The GPT partition table header is external input, so this routine
462 will do basic validation for GPT partition table header before return.
464 @param[in] BlockIo Parent BlockIo interface.
465 @param[in] DiskIo Disk Io protocol.
466 @param[in] Lba The starting Lba of the Partition Table
467 @param[out] PartHeader Stores the partition table that is read
469 @retval TRUE The partition table is valid
470 @retval FALSE The partition table is not valid
474 PartitionValidGptTable (
475 IN EFI_BLOCK_IO_PROTOCOL
*BlockIo
,
476 IN EFI_DISK_IO_PROTOCOL
*DiskIo
,
478 OUT EFI_PARTITION_TABLE_HEADER
*PartHeader
483 EFI_PARTITION_TABLE_HEADER
*PartHdr
;
486 BlockSize
= BlockIo
->Media
->BlockSize
;
487 MediaId
= BlockIo
->Media
->MediaId
;
488 PartHdr
= AllocateZeroPool (BlockSize
);
490 if (PartHdr
== NULL
) {
491 DEBUG ((EFI_D_ERROR
, "Allocate pool error\n"));
495 // Read the EFI Partition Table Header
497 Status
= DiskIo
->ReadDisk (
500 MultU64x32 (Lba
, BlockSize
),
504 if (EFI_ERROR (Status
)) {
509 if ((PartHdr
->Header
.Signature
!= EFI_PTAB_HEADER_ID
) ||
510 !PartitionCheckCrc (BlockSize
, &PartHdr
->Header
) ||
511 PartHdr
->MyLBA
!= Lba
||
512 (PartHdr
->SizeOfPartitionEntry
< sizeof (EFI_PARTITION_ENTRY
))
514 DEBUG ((EFI_D_INFO
, "Invalid efi partition table header\n"));
520 // Ensure the NumberOfPartitionEntries * SizeOfPartitionEntry doesn't overflow.
522 if (PartHdr
->NumberOfPartitionEntries
> DivU64x32 (MAX_UINTN
, PartHdr
->SizeOfPartitionEntry
)) {
527 CopyMem (PartHeader
, PartHdr
, sizeof (EFI_PARTITION_TABLE_HEADER
));
528 if (!PartitionCheckGptEntryArrayCRC (BlockIo
, DiskIo
, PartHeader
)) {
533 DEBUG ((EFI_D_INFO
, " Valid efi partition table header\n"));
539 Check if the CRC field in the Partition table header is valid
540 for Partition entry array.
542 @param[in] BlockIo Parent BlockIo interface
543 @param[in] DiskIo Disk Io Protocol.
544 @param[in] PartHeader Partition table header structure
546 @retval TRUE the CRC is valid
547 @retval FALSE the CRC is invalid
551 PartitionCheckGptEntryArrayCRC (
552 IN EFI_BLOCK_IO_PROTOCOL
*BlockIo
,
553 IN EFI_DISK_IO_PROTOCOL
*DiskIo
,
554 IN EFI_PARTITION_TABLE_HEADER
*PartHeader
563 // Read the EFI Partition Entries
565 Ptr
= AllocatePool (PartHeader
->NumberOfPartitionEntries
* PartHeader
->SizeOfPartitionEntry
);
567 DEBUG ((EFI_D_ERROR
, " Allocate pool error\n"));
571 Status
= DiskIo
->ReadDisk (
573 BlockIo
->Media
->MediaId
,
574 MultU64x32(PartHeader
->PartitionEntryLBA
, BlockIo
->Media
->BlockSize
),
575 PartHeader
->NumberOfPartitionEntries
* PartHeader
->SizeOfPartitionEntry
,
578 if (EFI_ERROR (Status
)) {
583 Size
= PartHeader
->NumberOfPartitionEntries
* PartHeader
->SizeOfPartitionEntry
;
585 Status
= gBS
->CalculateCrc32 (Ptr
, Size
, &Crc
);
586 if (EFI_ERROR (Status
)) {
587 DEBUG ((EFI_D_ERROR
, "CheckPEntryArrayCRC: Crc calculation failed\n"));
594 return (BOOLEAN
) (PartHeader
->PartitionEntryArrayCRC32
== Crc
);
599 Restore Partition Table to its alternate place
600 (Primary -> Backup or Backup -> Primary).
602 @param[in] BlockIo Parent BlockIo interface.
603 @param[in] DiskIo Disk Io Protocol.
604 @param[in] PartHeader Partition table header structure.
606 @retval TRUE Restoring succeeds
607 @retval FALSE Restoring failed
611 PartitionRestoreGptTable (
612 IN EFI_BLOCK_IO_PROTOCOL
*BlockIo
,
613 IN EFI_DISK_IO_PROTOCOL
*DiskIo
,
614 IN EFI_PARTITION_TABLE_HEADER
*PartHeader
619 EFI_PARTITION_TABLE_HEADER
*PartHdr
;
627 BlockSize
= BlockIo
->Media
->BlockSize
;
628 MediaId
= BlockIo
->Media
->MediaId
;
630 PartHdr
= AllocateZeroPool (BlockSize
);
632 if (PartHdr
== NULL
) {
633 DEBUG ((EFI_D_ERROR
, "Allocate pool error\n"));
637 PEntryLBA
= (PartHeader
->MyLBA
== PRIMARY_PART_HEADER_LBA
) ? \
638 (PartHeader
->LastUsableLBA
+ 1) : \
639 (PRIMARY_PART_HEADER_LBA
+ 1);
641 CopyMem (PartHdr
, PartHeader
, sizeof (EFI_PARTITION_TABLE_HEADER
));
643 PartHdr
->MyLBA
= PartHeader
->AlternateLBA
;
644 PartHdr
->AlternateLBA
= PartHeader
->MyLBA
;
645 PartHdr
->PartitionEntryLBA
= PEntryLBA
;
646 PartitionSetCrc ((EFI_TABLE_HEADER
*) PartHdr
);
648 Status
= DiskIo
->WriteDisk (
651 MultU64x32 (PartHdr
->MyLBA
, (UINT32
) BlockSize
),
655 if (EFI_ERROR (Status
)) {
659 Ptr
= AllocatePool (PartHeader
->NumberOfPartitionEntries
* PartHeader
->SizeOfPartitionEntry
);
661 DEBUG ((EFI_D_ERROR
, " Allocate pool error\n"));
662 Status
= EFI_OUT_OF_RESOURCES
;
666 Status
= DiskIo
->ReadDisk (
669 MultU64x32(PartHeader
->PartitionEntryLBA
, (UINT32
) BlockSize
),
670 PartHeader
->NumberOfPartitionEntries
* PartHeader
->SizeOfPartitionEntry
,
673 if (EFI_ERROR (Status
)) {
677 Status
= DiskIo
->WriteDisk (
680 MultU64x32(PEntryLBA
, (UINT32
) BlockSize
),
681 PartHeader
->NumberOfPartitionEntries
* PartHeader
->SizeOfPartitionEntry
,
692 if (EFI_ERROR (Status
)) {
700 This routine will check GPT partition entry and return entry status.
702 Caution: This function may receive untrusted input.
703 The GPT partition entry is external input, so this routine
704 will do basic validation for GPT partition entry and report status.
706 @param[in] PartHeader Partition table header structure
707 @param[in] PartEntry The partition entry array
708 @param[out] PEntryStatus the partition entry status array
709 recording the status of each partition
713 PartitionCheckGptEntry (
714 IN EFI_PARTITION_TABLE_HEADER
*PartHeader
,
715 IN EFI_PARTITION_ENTRY
*PartEntry
,
716 OUT EFI_PARTITION_ENTRY_STATUS
*PEntryStatus
721 EFI_PARTITION_ENTRY
*Entry
;
725 DEBUG ((EFI_D_INFO
, " start check partition entries\n"));
726 for (Index1
= 0; Index1
< PartHeader
->NumberOfPartitionEntries
; Index1
++) {
727 Entry
= (EFI_PARTITION_ENTRY
*) ((UINT8
*) PartEntry
+ Index1
* PartHeader
->SizeOfPartitionEntry
);
728 if (CompareGuid (&Entry
->PartitionTypeGUID
, &gEfiPartTypeUnusedGuid
)) {
732 StartingLBA
= Entry
->StartingLBA
;
733 EndingLBA
= Entry
->EndingLBA
;
734 if (StartingLBA
> EndingLBA
||
735 StartingLBA
< PartHeader
->FirstUsableLBA
||
736 StartingLBA
> PartHeader
->LastUsableLBA
||
737 EndingLBA
< PartHeader
->FirstUsableLBA
||
738 EndingLBA
> PartHeader
->LastUsableLBA
740 PEntryStatus
[Index1
].OutOfRange
= TRUE
;
744 if ((Entry
->Attributes
& BIT1
) != 0) {
746 // If Bit 1 is set, this indicate that this is an OS specific GUID partition.
748 PEntryStatus
[Index1
].OsSpecific
= TRUE
;
751 for (Index2
= Index1
+ 1; Index2
< PartHeader
->NumberOfPartitionEntries
; Index2
++) {
752 Entry
= (EFI_PARTITION_ENTRY
*) ((UINT8
*) PartEntry
+ Index2
* PartHeader
->SizeOfPartitionEntry
);
753 if (CompareGuid (&Entry
->PartitionTypeGUID
, &gEfiPartTypeUnusedGuid
)) {
757 if (Entry
->EndingLBA
>= StartingLBA
&& Entry
->StartingLBA
<= EndingLBA
) {
759 // This region overlaps with the Index1'th region
761 PEntryStatus
[Index1
].Overlap
= TRUE
;
762 PEntryStatus
[Index2
].Overlap
= TRUE
;
768 DEBUG ((EFI_D_INFO
, " End check partition entries\n"));
773 Updates the CRC32 value in the table header.
775 @param Hdr Table to update
780 IN OUT EFI_TABLE_HEADER
*Hdr
783 PartitionSetCrcAltSize (Hdr
->HeaderSize
, Hdr
);
788 Updates the CRC32 value in the table header.
790 @param Size The size of the table
791 @param Hdr Table to update
795 PartitionSetCrcAltSize (
797 IN OUT EFI_TABLE_HEADER
*Hdr
803 gBS
->CalculateCrc32 ((UINT8
*) Hdr
, Size
, &Crc
);
809 Checks the CRC32 value in the table header.
811 @param MaxSize Max Size limit
812 @param Hdr Table to check
814 @return TRUE CRC Valid
815 @return FALSE CRC Invalid
821 IN OUT EFI_TABLE_HEADER
*Hdr
824 return PartitionCheckCrcAltSize (MaxSize
, Hdr
->HeaderSize
, Hdr
);
829 Checks the CRC32 value in the table header.
831 @param MaxSize Max Size limit
832 @param Size The size of the table
833 @param Hdr Table to check
835 @return TRUE CRC Valid
836 @return FALSE CRC Invalid
840 PartitionCheckCrcAltSize (
843 IN OUT EFI_TABLE_HEADER
*Hdr
854 // If header size is 0 CRC will pass so return FALSE here
859 if ((MaxSize
!= 0) && (Size
> MaxSize
)) {
860 DEBUG ((EFI_D_ERROR
, "CheckCrc32: Size > MaxSize\n"));
864 // clear old crc from header
869 Status
= gBS
->CalculateCrc32 ((UINT8
*) Hdr
, Size
, &Crc
);
870 if (EFI_ERROR (Status
)) {
871 DEBUG ((EFI_D_ERROR
, "CheckCrc32: Crc calculation failed\n"));
884 DEBUG ((EFI_D_ERROR
, "CheckCrc32: Crc check failed\n"));
888 return (BOOLEAN
) (OrgCrc
== Crc
);