/** 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_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) { // // Compatibility Errata: // Some systems try to hide drive space with their 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 since 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_UINT32 (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; } } } // // None of the regions overlapped so MBR is O.K. // return MbrValid; }
/** Install child handles if the Handle supports GPT partition structure. @param[in] This Calling context. @param[in] Handle Parent Handle. @param[in] DiskIo Parent DiskIo interface. @param[in] BlockIo Parent BlockIo interface. @param[in] BlockIo2 Parent BlockIo2 interface. @param[in] DevicePath Parent Device Path. @retval EFI_SUCCESS Valid GPT disk. @retval EFI_MEDIA_CHANGED Media changed Detected. @retval other Not a valid GPT disk. **/ EFI_STATUS PartitionInstallGptChildHandles ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, IN EFI_DISK_IO_PROTOCOL *DiskIo, IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { EFI_STATUS Status; UINT32 BlockSize; EFI_LBA LastBlock; MASTER_BOOT_RECORD *ProtectiveMbr; EFI_PARTITION_TABLE_HEADER *PrimaryHeader; EFI_PARTITION_TABLE_HEADER *BackupHeader; EFI_PARTITION_ENTRY *PartEntry; EFI_PARTITION_ENTRY *Entry; EFI_PARTITION_ENTRY_STATUS *PEntryStatus; UINTN Index; EFI_STATUS GptValidStatus; HARDDRIVE_DEVICE_PATH HdDev; UINT32 MediaId; VBoxLogFlowFuncMarkDP(DevicePath); ProtectiveMbr = NULL; PrimaryHeader = NULL; BackupHeader = NULL; PartEntry = NULL; PEntryStatus = NULL; BlockSize = BlockIo->Media->BlockSize; LastBlock = BlockIo->Media->LastBlock; MediaId = BlockIo->Media->MediaId; DEBUG ((EFI_D_INFO, " BlockSize : %d \n", BlockSize)); DEBUG ((EFI_D_INFO, " LastBlock : %lx \n", LastBlock)); GptValidStatus = EFI_NOT_FOUND; // // Allocate a buffer for the Protective MBR // ProtectiveMbr = AllocatePool (BlockSize); if (ProtectiveMbr == NULL) { return EFI_NOT_FOUND; } // // Read the Protective MBR from LBA #0 // Status = DiskIo->ReadDisk ( DiskIo, MediaId, 0, BlockSize, ProtectiveMbr ); if (EFI_ERROR (Status)) { GptValidStatus = Status; goto Done; } // // Verify that the Protective MBR is valid // for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) { if (ProtectiveMbr->Partition[Index].BootIndicator == 0x00 && ProtectiveMbr->Partition[Index].OSIndicator == PMBR_GPT_PARTITION && UNPACK_UINT32 (ProtectiveMbr->Partition[Index].StartingLBA) == 1 ) { break; } } if (Index == MAX_MBR_PARTITIONS) { goto Done; } // // Allocate the GPT structures // PrimaryHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER)); if (PrimaryHeader == NULL) { goto Done; } BackupHeader = AllocateZeroPool (sizeof (EFI_PARTITION_TABLE_HEADER)); if (BackupHeader == NULL) { goto Done; } // // Check primary and backup partition tables // if (!PartitionValidGptTable (BlockIo, DiskIo, PRIMARY_PART_HEADER_LBA, PrimaryHeader)) { DEBUG ((EFI_D_INFO, " Not Valid primary partition table\n")); if (!PartitionValidGptTable (BlockIo, DiskIo, LastBlock, BackupHeader)) { DEBUG ((EFI_D_INFO, " Not Valid backup partition table\n")); goto Done; } else { DEBUG ((EFI_D_INFO, " Valid backup partition table\n")); DEBUG ((EFI_D_INFO, " Restore primary partition table by the backup\n")); if (!PartitionRestoreGptTable (BlockIo, DiskIo, BackupHeader)) { DEBUG ((EFI_D_INFO, " Restore primary partition table error\n")); } if (PartitionValidGptTable (BlockIo, DiskIo, BackupHeader->AlternateLBA, PrimaryHeader)) { DEBUG ((EFI_D_INFO, " Restore backup partition table success\n")); } } } else if (!PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) { DEBUG ((EFI_D_INFO, " Valid primary and !Valid backup partition table\n")); DEBUG ((EFI_D_INFO, " Restore backup partition table by the primary\n")); if (!PartitionRestoreGptTable (BlockIo, DiskIo, PrimaryHeader)) { DEBUG ((EFI_D_INFO, " Restore backup partition table error\n")); } if (PartitionValidGptTable (BlockIo, DiskIo, PrimaryHeader->AlternateLBA, BackupHeader)) { DEBUG ((EFI_D_INFO, " Restore backup partition table success\n")); } } DEBUG ((EFI_D_INFO, " Valid primary and Valid backup partition table\n")); // // Read the EFI Partition Entries // PartEntry = AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry); if (PartEntry == NULL) { DEBUG ((EFI_D_ERROR, "Allocate pool error\n")); goto Done; } Status = DiskIo->ReadDisk ( DiskIo, MediaId, MultU64x32(PrimaryHeader->PartitionEntryLBA, BlockSize), PrimaryHeader->NumberOfPartitionEntries * (PrimaryHeader->SizeOfPartitionEntry), PartEntry ); if (EFI_ERROR (Status)) { GptValidStatus = Status; DEBUG ((EFI_D_ERROR, " Partition Entry ReadDisk error\n")); goto Done; } DEBUG ((EFI_D_INFO, " Partition entries read block success\n")); DEBUG ((EFI_D_INFO, " Number of partition entries: %d\n", PrimaryHeader->NumberOfPartitionEntries)); PEntryStatus = AllocateZeroPool (PrimaryHeader->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY_STATUS)); if (PEntryStatus == NULL) { DEBUG ((EFI_D_ERROR, "Allocate pool error\n")); goto Done; } // // Check the integrity of partition entries // PartitionCheckGptEntry (PrimaryHeader, PartEntry, PEntryStatus); // // If we got this far the GPT layout of the disk is valid and we should return true // GptValidStatus = EFI_SUCCESS; // // Create child device handles // for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) { Entry = (EFI_PARTITION_ENTRY *) ((UINT8 *) PartEntry + Index * PrimaryHeader->SizeOfPartitionEntry); if (CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid) || PEntryStatus[Index].OutOfRange || PEntryStatus[Index].Overlap || PEntryStatus[Index].OsSpecific ) { // // Don't use null EFI Partition Entries, Invalid Partition Entries or OS specific // partition Entries // continue; } ZeroMem (&HdDev, sizeof (HdDev)); HdDev.Header.Type = MEDIA_DEVICE_PATH; HdDev.Header.SubType = MEDIA_HARDDRIVE_DP; SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev)); HdDev.PartitionNumber = (UINT32) Index + 1; HdDev.MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER; HdDev.SignatureType = SIGNATURE_TYPE_GUID; HdDev.PartitionStart = Entry->StartingLBA; HdDev.PartitionSize = Entry->EndingLBA - Entry->StartingLBA + 1; CopyMem (HdDev.Signature, &Entry->UniquePartitionGUID, sizeof (EFI_GUID)); DEBUG ((EFI_D_INFO, " Index : %d\n", (UINT32) Index)); DEBUG ((EFI_D_INFO, " Start LBA : %lx\n", (UINT64) HdDev.PartitionStart)); DEBUG ((EFI_D_INFO, " End LBA : %lx\n", (UINT64) Entry->EndingLBA)); DEBUG ((EFI_D_INFO, " Partition size: %lx\n", (UINT64) HdDev.PartitionSize)); DEBUG ((EFI_D_INFO, " Start : %lx", MultU64x32 (Entry->StartingLBA, BlockSize))); DEBUG ((EFI_D_INFO, " End : %lx\n", MultU64x32 (Entry->EndingLBA, BlockSize))); Status = PartitionInstallChildHandle ( This, Handle, DiskIo, BlockIo, BlockIo2, DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &HdDev, Entry->StartingLBA, Entry->EndingLBA, BlockSize, CompareGuid(&Entry->PartitionTypeGUID, &gEfiPartTypeSystemPartGuid) ); } DEBUG ((EFI_D_INFO, "Prepare to Free Pool\n")); Done: if (ProtectiveMbr != NULL) { FreePool (ProtectiveMbr); } if (PrimaryHeader != NULL) { FreePool (PrimaryHeader); } if (BackupHeader != NULL) { FreePool (BackupHeader); } if (PartEntry != NULL) { FreePool (PartEntry); } if (PEntryStatus != NULL) { FreePool (PEntryStatus); } return GptValidStatus; }
/** Install child handles if the Handle supports MBR format. @param This Calling context. @param Handle Parent Handle. @param DiskIo Parent DiskIo interface. @param BlockIo Parent BlockIo interface. @param DevicePath Parent Device Path. @retval EFI_SUCCESS A child handle was added. @retval EFI_MEDIA_CHANGED Media change was detected. @retval Others MBR partition was not found. **/ EFI_STATUS PartitionInstallMbrChildHandles ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, IN EFI_DISK_IO_PROTOCOL *DiskIo, IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { EFI_STATUS Status; MASTER_BOOT_RECORD *Mbr; UINT32 ExtMbrStartingLba; UINTN Index; HARDDRIVE_DEVICE_PATH HdDev; HARDDRIVE_DEVICE_PATH ParentHdDev; EFI_STATUS Found; UINT32 PartitionNumber; EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; EFI_DEVICE_PATH_PROTOCOL *LastDevicePathNode; Found = EFI_NOT_FOUND; Mbr = AllocatePool (BlockIo->Media->BlockSize); if (Mbr == NULL) { return Found; } Status = DiskIo->ReadDisk ( DiskIo, BlockIo->Media->MediaId, 0, BlockIo->Media->BlockSize, Mbr ); if (EFI_ERROR (Status)) { Found = Status; goto Done; } if (!PartitionValidMbr (Mbr, BlockIo->Media->LastBlock)) { goto Done; } // // We have a valid mbr - add each partition // // // Get starting and ending LBA of the parent block device. // LastDevicePathNode = NULL; ZeroMem (&ParentHdDev, sizeof (ParentHdDev)); DevicePathNode = DevicePath; while (!IsDevicePathEnd (DevicePathNode)) { LastDevicePathNode = DevicePathNode; DevicePathNode = NextDevicePathNode (DevicePathNode); } if (LastDevicePathNode != NULL) { if (DevicePathType (LastDevicePathNode) == MEDIA_DEVICE_PATH && DevicePathSubType (LastDevicePathNode) == MEDIA_HARDDRIVE_DP ) { CopyMem (&ParentHdDev, LastDevicePathNode, sizeof (ParentHdDev)); } else { LastDevicePathNode = NULL; } } PartitionNumber = 1; ZeroMem (&HdDev, sizeof (HdDev)); HdDev.Header.Type = MEDIA_DEVICE_PATH; HdDev.Header.SubType = MEDIA_HARDDRIVE_DP; SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev)); HdDev.MBRType = MBR_TYPE_PCAT; HdDev.SignatureType = SIGNATURE_TYPE_MBR; if (LastDevicePathNode == NULL) { // // This is a MBR, add each partition // for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) { if (Mbr->Partition[Index].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index].SizeInLBA) == 0) { // // Don't use null MBR entries // continue; } if (Mbr->Partition[Index].OSIndicator == PMBR_GPT_PARTITION) { // // This is the guard MBR for the GPT. If you ever see a GPT disk with zero partitions you can get here. // We can not produce an MBR BlockIo for this device as the MBR spans the GPT headers. So formating // this BlockIo would corrupt the GPT structures and require a recovery that would corrupt the format // that corrupted the GPT partition. // continue; } HdDev.PartitionNumber = PartitionNumber ++; HdDev.PartitionStart = UNPACK_UINT32 (Mbr->Partition[Index].StartingLBA); HdDev.PartitionSize = UNPACK_UINT32 (Mbr->Partition[Index].SizeInLBA); CopyMem (HdDev.Signature, &(Mbr->UniqueMbrSignature[0]), sizeof (Mbr->UniqueMbrSignature)); Status = PartitionInstallChildHandle ( This, Handle, DiskIo, BlockIo, DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &HdDev, HdDev.PartitionStart, HdDev.PartitionStart + HdDev.PartitionSize - 1, MBR_SIZE, (BOOLEAN) (Mbr->Partition[Index].OSIndicator == EFI_PARTITION) ); if (!EFI_ERROR (Status)) { Found = EFI_SUCCESS; } } } else { // // It's an extended partition. Follow the extended partition // chain to get all the logical drives // ExtMbrStartingLba = 0; do { Status = DiskIo->ReadDisk ( DiskIo, BlockIo->Media->MediaId, MultU64x32 (ExtMbrStartingLba, BlockIo->Media->BlockSize), BlockIo->Media->BlockSize, Mbr ); if (EFI_ERROR (Status)) { Found = Status; goto Done; } if (UNPACK_UINT32 (Mbr->Partition[0].SizeInLBA) == 0) { break; } if ((Mbr->Partition[0].OSIndicator == EXTENDED_DOS_PARTITION) || (Mbr->Partition[0].OSIndicator == EXTENDED_WINDOWS_PARTITION)) { ExtMbrStartingLba = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA); continue; } HdDev.PartitionNumber = PartitionNumber ++; HdDev.PartitionStart = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA) + ExtMbrStartingLba + ParentHdDev.PartitionStart; HdDev.PartitionSize = UNPACK_UINT32 (Mbr->Partition[0].SizeInLBA); if ((HdDev.PartitionStart + HdDev.PartitionSize - 1 >= ParentHdDev.PartitionStart + ParentHdDev.PartitionSize) || (HdDev.PartitionStart <= ParentHdDev.PartitionStart)) { break; } // // The signature in EBR(Extended Boot Record) should always be 0. // *((UINT32 *) &HdDev.Signature[0]) = 0; Status = PartitionInstallChildHandle ( This, Handle, DiskIo, BlockIo, DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &HdDev, HdDev.PartitionStart - ParentHdDev.PartitionStart, HdDev.PartitionStart - ParentHdDev.PartitionStart + HdDev.PartitionSize - 1, MBR_SIZE, (BOOLEAN) (Mbr->Partition[0].OSIndicator == EFI_PARTITION) ); if (!EFI_ERROR (Status)) { Found = EFI_SUCCESS; } if ((Mbr->Partition[1].OSIndicator != EXTENDED_DOS_PARTITION) && (Mbr->Partition[1].OSIndicator != EXTENDED_WINDOWS_PARTITION) ) { break; } ExtMbrStartingLba = UNPACK_UINT32 (Mbr->Partition[1].StartingLBA); // // Don't allow partition to be self referencing // if (ExtMbrStartingLba == 0) { break; } } while (ExtMbrStartingLba < ParentHdDev.PartitionSize); } Done: FreePool (Mbr); return Found; }
/** Install child handles if the Handle supports AddLbaOfs format. @param[in] This Calling context. @param[in] Handle Parent Handle. @param[in] DiskIo Parent DiskIo interface. @param[in] DiskIo2 Parent DiskIo2 interface. @param[in] BlockIo Parent BlockIo interface. @param[in] BlockIo2 Parent BlockIo2 interface. @param[in] DevicePath Parent Device Path. @retval EFI_SUCCESS A child handle was added. @retval EFI_MEDIA_CHANGED Media change was detected. @retval Others MBR partition was not found. **/ EFI_STATUS PartitionInstallAddLbaOfsChildHandles ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, IN EFI_DISK_IO_PROTOCOL *DiskIo, IN EFI_DISK_IO2_PROTOCOL *DiskIo2, IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN EFI_BLOCK_IO2_PROTOCOL *BlockIo2, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { #undef FN #define FN "PartitionInstallAddLbaOfsChildHandles" #define DBG_PartitionInstallAddLbaOfsChildHandles DL_80 /* DL_DISABLED DL_80 */ EFI_STATUS Status; MASTER_BOOT_RECORD *Mbr; //UINT32 ExtMbrStartingLba; UINTN Index; HARDDRIVE_DEVICE_PATH HdDev; HARDDRIVE_DEVICE_PATH ParentHdDev; EFI_STATUS Found; UINT32 PartitionNumber; EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; EFI_DEVICE_PATH_PROTOCOL *LastDevicePathNode; UINT32 BlockSize; UINT32 MediaId; EFI_LBA LastBlock; EFI_LBA AddLbaOfs; EFI_LBA Lba; DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "entered\n"); Found = EFI_NOT_FOUND; BlockSize = BlockIo->Media->BlockSize; MediaId = BlockIo->Media->MediaId; LastBlock = BlockIo->Media->LastBlock; DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "BlockSize=%"PRIx64" MediaId=%"PRIx64" LastBlock=%"PRIx64"\n", BlockSize, MediaId, LastBlock); Mbr = AllocatePool (BlockSize); if (Mbr == NULL) { return Found; } for (Lba = 0; Lba < 1; Lba++) { Status = DiskIo->ReadDisk( DiskIo, MediaId, Lba * BlockSize, BlockSize, Mbr ); DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "ReadDisk MediaId=%"PRIx32" Lba*BlockSize=%"PRIx64" %r\n", MediaId, Lba * BlockSize, Status); if (!EFI_ERROR(Status)) { DBG_X(DBG_PartitionInstallAddLbaOfsChildHandles, (PrBufxxdr(Mbr, BlockSize))); if (PartitionValidAddLbaOfs (Mbr, LastBlock)) { goto ValidMbr; } } #if 0 Status = DiskIo->ReadDisk( DiskIo, MediaId, (LastBlock - Lba) * BlockSize, BlockSize, Mbr ); DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "ReadDisk MediaId=%"PRIx32" (LastBlock-Lba)*BlockSize=%"PRIx64" %r\n", MediaId, (LastBlock - Lba) * BlockSize, Status); if (!EFI_ERROR(Status)) { DBG_X(DBG_PartitionInstallAddLbaOfsChildHandles, (PrBufxxdr(Mbr, BlockSize))); if (PartitionValidAddLbaOfs (Mbr, LastBlock)) { goto ValidMbr; } } #endif } /* for */ goto Done; ValidMbr: DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "ValidMbr\n"); // // We have a valid mbr - add each partition // // // Get starting and ending LBA of the parent block device. // LastDevicePathNode = NULL; ZeroMem (&ParentHdDev, sizeof (ParentHdDev)); DevicePathNode = DevicePath; while (!IsDevicePathEnd (DevicePathNode)) { LastDevicePathNode = DevicePathNode; DevicePathNode = NextDevicePathNode (DevicePathNode); } if (LastDevicePathNode != NULL) { if (DevicePathType (LastDevicePathNode) == MEDIA_DEVICE_PATH && DevicePathSubType (LastDevicePathNode) == MEDIA_HARDDRIVE_DP ) { CopyMem (&ParentHdDev, LastDevicePathNode, sizeof (ParentHdDev)); } else { LastDevicePathNode = NULL; } } PartitionNumber = 1; ZeroMem (&HdDev, sizeof (HdDev)); HdDev.Header.Type = MEDIA_DEVICE_PATH; HdDev.Header.SubType = MEDIA_HARDDRIVE_DP; //TBD MEDIA_VENDOR_DP SetDevicePathNodeLength (&HdDev.Header, sizeof (HdDev)); HdDev.MBRType = MBR_TYPE_PCAT; //TBD HdDev.SignatureType = SIGNATURE_TYPE_GUID + 1; //TBD if (LastDevicePathNode == NULL) { // // This is a MBR, add each partition // Index = 0; /* for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) { */ AddLbaOfs = SwapBytes64(*((UINT64 *)((UINT8 *)&Mbr->BootStrapCode[ADDLBAOFS_32_OFS]))); DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "AddLbaOfs=%"PRIx64"\n", AddLbaOfs); HdDev.PartitionNumber = PartitionNumber ++; HdDev.PartitionStart = AddLbaOfs; /* UNPACK_UINT32 (Mbr->Partition[Index].StartingLBA); */ HdDev.PartitionSize = LastBlock + 1 - AddLbaOfs; /* UNPACK_UINT32 (Mbr->Partition[Index].SizeInLBA); */ CopyMem (HdDev.Signature, &(Mbr->UniqueMbrSignature[0]), sizeof (Mbr->UniqueMbrSignature)); Status = PartitionInstallChildHandle ( This, Handle, DiskIo, DiskIo2, BlockIo, BlockIo2, DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &HdDev, HdDev.PartitionStart, HdDev.PartitionStart + HdDev.PartitionSize - 1, MBR_SIZE, (BOOLEAN) (Mbr->Partition[Index].OSIndicator == EFI_PARTITION) ); DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "PartitionInstallChildHandle %r\n", Status); if (!EFI_ERROR (Status)) { Found = EFI_SUCCESS; } /* } /* for */ } else { #if 1 //Found = EFI_NOT_FOUND; goto Done; #else // // It's an extended partition. Follow the extended partition // chain to get all the logical drives // ExtMbrStartingLba = 0; do { Status = DiskIo->ReadDisk ( DiskIo, MediaId, MultU64x32 (ExtMbrStartingLba, BlockSize), BlockSize, Mbr ); if (EFI_ERROR (Status)) { Found = Status; goto Done; } if (UNPACK_UINT32 (Mbr->Partition[0].SizeInLBA) == 0) { break; } if ((Mbr->Partition[0].OSIndicator == EXTENDED_DOS_PARTITION) || (Mbr->Partition[0].OSIndicator == EXTENDED_WINDOWS_PARTITION)) { ExtMbrStartingLba = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA); continue; } HdDev.PartitionNumber = PartitionNumber ++; HdDev.PartitionStart = UNPACK_UINT32 (Mbr->Partition[0].StartingLBA) + ExtMbrStartingLba + ParentHdDev.PartitionStart; HdDev.PartitionSize = UNPACK_UINT32 (Mbr->Partition[0].SizeInLBA); if ((HdDev.PartitionStart + HdDev.PartitionSize - 1 >= ParentHdDev.PartitionStart + ParentHdDev.PartitionSize) || (HdDev.PartitionStart <= ParentHdDev.PartitionStart)) { break; } // // The signature in EBR(Extended Boot Record) should always be 0. // *((UINT32 *) &HdDev.Signature[0]) = 0; Status = PartitionInstallChildHandle ( This, Handle, DiskIo, DiskIo2, BlockIo, BlockIo2, DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &HdDev, HdDev.PartitionStart - ParentHdDev.PartitionStart, HdDev.PartitionStart - ParentHdDev.PartitionStart + HdDev.PartitionSize - 1, MBR_SIZE, (BOOLEAN) (Mbr->Partition[0].OSIndicator == EFI_PARTITION) ); if (!EFI_ERROR (Status)) { Found = EFI_SUCCESS; } if ((Mbr->Partition[1].OSIndicator != EXTENDED_DOS_PARTITION) && (Mbr->Partition[1].OSIndicator != EXTENDED_WINDOWS_PARTITION) ) { break; } ExtMbrStartingLba = UNPACK_UINT32 (Mbr->Partition[1].StartingLBA); // // Don't allow partition to be self referencing // if (ExtMbrStartingLba == 0) { break; } } while (ExtMbrStartingLba < ParentHdDev.PartitionSize); #endif } Done: FreePool (Mbr); DBG_PR(DBG_PartitionInstallAddLbaOfsChildHandles, "Found=%d\n", Found); return Found; }