187 IN EFI_DRIVER_BINDING_PROTOCOL *This,
189 IN EFI_DISK_IO_PROTOCOL *DiskIo,
190 IN EFI_DISK_IO2_PROTOCOL *DiskIo2,
191 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
192 IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2,
193 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
199 MASTER_BOOT_RECORD *ProtectiveMbr;
200 EFI_PARTITION_TABLE_HEADER *PrimaryHeader;
201 EFI_PARTITION_TABLE_HEADER *BackupHeader;
202 EFI_PARTITION_ENTRY *PartEntry;
203 EFI_PARTITION_ENTRY *Entry;
206 EFI_STATUS GptValidStatus;
207 HARDDRIVE_DEVICE_PATH HdDev;
209 EFI_PARTITION_INFO_PROTOCOL PartitionInfo;
212 ProtectiveMbr = NULL;
213 PrimaryHeader = NULL;
219 LastBlock = BlockIo->Media->LastBlock;
220 MediaId = BlockIo->Media->MediaId;
222 DEBUG ((EFI_D_INFO,
" BlockSize : %d \n",
BlockSize));
223 DEBUG ((EFI_D_INFO,
" LastBlock : %lx \n", LastBlock));
225 GptValidStatus = EFI_NOT_FOUND;
230 if (
BlockSize <
sizeof (MASTER_BOOT_RECORD)) {
231 return EFI_NOT_FOUND;
237 ProtectiveMbr = AllocatePool (
BlockSize);
238 if (ProtectiveMbr == NULL) {
239 return EFI_NOT_FOUND;
245 Status = DiskIo->ReadDisk (
252 if (EFI_ERROR (Status)) {
253 GptValidStatus = Status;
260 for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {
261 if ((ProtectiveMbr->Partition[Index].BootIndicator == 0x00) &&
262 (ProtectiveMbr->Partition[Index].OSIndicator == PMBR_GPT_PARTITION) &&
263 (
UNPACK_UINT32 (ProtectiveMbr->Partition[Index].StartingLBA) == 1)
270 if (Index == MAX_MBR_PARTITIONS) {
277 PrimaryHeader = AllocateZeroPool (
sizeof (EFI_PARTITION_TABLE_HEADER));
278 if (PrimaryHeader == NULL) {
282 BackupHeader = AllocateZeroPool (
sizeof (EFI_PARTITION_TABLE_HEADER));
283 if (BackupHeader == NULL) {
291 DEBUG ((EFI_D_INFO,
" Not Valid primary partition table\n"));
294 DEBUG ((EFI_D_INFO,
" Not Valid backup partition table\n"));
297 DEBUG ((EFI_D_INFO,
" Valid backup partition table\n"));
298 DEBUG ((EFI_D_INFO,
" Restore primary partition table by the backup\n"));
300 DEBUG ((EFI_D_INFO,
" Restore primary partition table error\n"));
304 DEBUG ((EFI_D_INFO,
" Restore backup partition table success\n"));
308 DEBUG ((EFI_D_INFO,
" Valid primary and !Valid backup partition table\n"));
309 DEBUG ((EFI_D_INFO,
" Restore backup partition table by the primary\n"));
311 DEBUG ((EFI_D_INFO,
" Restore backup partition table error\n"));
315 DEBUG ((EFI_D_INFO,
" Restore backup partition table success\n"));
319 DEBUG ((EFI_D_INFO,
" Valid primary and Valid backup partition table\n"));
324 PartEntry = AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry);
325 if (PartEntry == NULL) {
326 DEBUG ((EFI_D_ERROR,
"Allocate pool error\n"));
330 Status = DiskIo->ReadDisk (
334 PrimaryHeader->NumberOfPartitionEntries * (PrimaryHeader->SizeOfPartitionEntry),
337 if (EFI_ERROR (Status)) {
338 GptValidStatus = Status;
339 DEBUG ((EFI_D_ERROR,
" Partition Entry ReadDisk error\n"));
343 DEBUG ((EFI_D_INFO,
" Partition entries read block success\n"));
345 DEBUG ((EFI_D_INFO,
" Number of partition entries: %d\n", PrimaryHeader->NumberOfPartitionEntries));
348 if (PEntryStatus == NULL) {
349 DEBUG ((EFI_D_ERROR,
"Allocate pool error\n"));
361 GptValidStatus = EFI_SUCCESS;
366 for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
367 Entry = (EFI_PARTITION_ENTRY *)((UINT8 *)PartEntry + Index * PrimaryHeader->SizeOfPartitionEntry);
368 if (
CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid) ||
381 ZeroMem (&HdDev,
sizeof (HdDev));
382 HdDev.Header.Type = MEDIA_DEVICE_PATH;
383 HdDev.Header.SubType = MEDIA_HARDDRIVE_DP;
384 SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev));
386 HdDev.PartitionNumber = (UINT32)Index + 1;
387 HdDev.MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
388 HdDev.SignatureType = SIGNATURE_TYPE_GUID;
389 HdDev.PartitionStart = Entry->StartingLBA;
390 HdDev.PartitionSize = Entry->EndingLBA - Entry->StartingLBA + 1;
391 CopyMem (HdDev.Signature, &Entry->UniquePartitionGUID, sizeof (EFI_GUID));
393 ZeroMem (&PartitionInfo,
sizeof (EFI_PARTITION_INFO_PROTOCOL));
394 PartitionInfo.Revision = EFI_PARTITION_INFO_PROTOCOL_REVISION;
395 PartitionInfo.Type = PARTITION_TYPE_GPT;
396 if (
CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeSystemPartGuid)) {
397 PartitionInfo.System = 1;
400 CopyMem (&PartitionInfo.Info.Gpt, Entry, sizeof (EFI_PARTITION_ENTRY));
405 ApplePartitionInfo.
MBRType = HdDev.MBRType;
409 ApplePartitionInfo.
Attributes = PartEntry[Index].Attributes;
410 CopyMem (&ApplePartitionInfo.
Signature, HdDev.Signature, sizeof (EFI_GUID));
411 CopyMem (ApplePartitionInfo.
PartitionName, PartEntry[Index].PartitionName, 36 * sizeof (UINT16));
412 CopyMem (&ApplePartitionInfo.
PartitionType, &PartEntry[Index].PartitionTypeGUID, sizeof (EFI_GUID));
414 DEBUG ((EFI_D_INFO,
" Index : %d\n", (UINT32)Index));
415 DEBUG ((EFI_D_INFO,
" Start LBA : %lx\n", (UINT64)HdDev.PartitionStart));
416 DEBUG ((EFI_D_INFO,
" End LBA : %lx\n", (UINT64)Entry->EndingLBA));
417 DEBUG ((EFI_D_INFO,
" Partition size: %lx\n", (UINT64)HdDev.PartitionSize));
429 (EFI_DEVICE_PATH_PROTOCOL *)&HdDev,
435 &Entry->PartitionTypeGUID
439 DEBUG ((EFI_D_INFO,
"Prepare to Free Pool\n"));
442 if (ProtectiveMbr != NULL) {
443 FreePool (ProtectiveMbr);
446 if (PrimaryHeader != NULL) {
447 FreePool (PrimaryHeader);
450 if (BackupHeader != NULL) {
451 FreePool (BackupHeader);
454 if (PartEntry != NULL) {
455 FreePool (PartEntry);
458 if (PEntryStatus != NULL) {
459 FreePool (PEntryStatus);
462 return GptValidStatus;
483 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
484 IN EFI_DISK_IO_PROTOCOL *DiskIo,
486 OUT EFI_PARTITION_TABLE_HEADER *PartHeader
491 EFI_PARTITION_TABLE_HEADER *PartHdr;
495 MediaId = BlockIo->Media->MediaId;
498 if (PartHdr == NULL) {
499 DEBUG ((EFI_D_ERROR,
"Allocate pool error\n"));
506 Status = DiskIo->ReadDisk (
513 if (EFI_ERROR (Status)) {
518 if ((PartHdr->Header.Signature != EFI_PTAB_HEADER_ID) ||
520 (PartHdr->MyLBA != Lba) ||
521 (PartHdr->SizeOfPartitionEntry < sizeof (EFI_PARTITION_ENTRY))
524 DEBUG ((EFI_D_INFO,
"Invalid efi partition table header\n"));
532 if (PartHdr->NumberOfPartitionEntries >
DivU64x32 (MAX_UINTN, PartHdr->SizeOfPartitionEntry)) {
537 CopyMem (PartHeader, PartHdr,
sizeof (EFI_PARTITION_TABLE_HEADER));
543 DEBUG ((EFI_D_INFO,
" Valid efi partition table header\n"));
621 IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
622 IN EFI_DISK_IO_PROTOCOL *DiskIo,
623 IN EFI_PARTITION_TABLE_HEADER *PartHeader
628 EFI_PARTITION_TABLE_HEADER *PartHdr;
637 MediaId = BlockIo->Media->MediaId;
641 if (PartHdr == NULL) {
642 DEBUG ((EFI_D_ERROR,
"Allocate pool error\n"));
646 PEntryLBA = (PartHeader->MyLBA == PRIMARY_PART_HEADER_LBA) ? \
647 (PartHeader->LastUsableLBA + 1) : \
648 (PRIMARY_PART_HEADER_LBA + 1);
650 CopyMem (PartHdr, PartHeader,
sizeof (EFI_PARTITION_TABLE_HEADER));
652 PartHdr->MyLBA = PartHeader->AlternateLBA;
653 PartHdr->AlternateLBA = PartHeader->MyLBA;
654 PartHdr->PartitionEntryLBA = PEntryLBA;
657 Status = DiskIo->WriteDisk (
664 if (EFI_ERROR (Status)) {
668 Ptr = AllocatePool (PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry);
670 DEBUG ((EFI_D_ERROR,
" Allocate pool error\n"));
671 Status = EFI_OUT_OF_RESOURCES;
675 Status = DiskIo->ReadDisk (
679 PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
682 if (EFI_ERROR (Status)) {
686 Status = DiskIo->WriteDisk (
690 PartHeader->NumberOfPartitionEntries * PartHeader->SizeOfPartitionEntry,
701 if (EFI_ERROR (Status)) {
723 IN EFI_PARTITION_TABLE_HEADER *PartHeader,
724 IN EFI_PARTITION_ENTRY *PartEntry,
730 EFI_PARTITION_ENTRY *Entry;
734 DEBUG ((EFI_D_INFO,
" start check partition entries\n"));
735 for (Index1 = 0; Index1 < PartHeader->NumberOfPartitionEntries; Index1++) {
736 Entry = (EFI_PARTITION_ENTRY *)((UINT8 *)PartEntry + Index1 * PartHeader->SizeOfPartitionEntry);
737 if (
CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
741 StartingLBA = Entry->StartingLBA;
742 EndingLBA = Entry->EndingLBA;
743 if ((StartingLBA > EndingLBA) ||
744 (StartingLBA < PartHeader->FirstUsableLBA) ||
745 (StartingLBA > PartHeader->LastUsableLBA) ||
746 (EndingLBA < PartHeader->FirstUsableLBA) ||
747 (EndingLBA > PartHeader->LastUsableLBA)
750 PEntryStatus[Index1].OutOfRange = TRUE;
754 if ((Entry->Attributes & BIT1) != 0) {
758 PEntryStatus[Index1].OsSpecific = TRUE;
761 for (Index2 = Index1 + 1; Index2 < PartHeader->NumberOfPartitionEntries; Index2++) {
762 Entry = (EFI_PARTITION_ENTRY *)((UINT8 *)PartEntry + Index2 * PartHeader->SizeOfPartitionEntry);
763 if (
CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
767 if ((Entry->EndingLBA >= StartingLBA) && (Entry->StartingLBA <= EndingLBA)) {
771 PEntryStatus[Index1].Overlap = TRUE;
772 PEntryStatus[Index2].Overlap = TRUE;
778 DEBUG ((EFI_D_INFO,
" End check partition entries\n"));