void PartitionHandle::CheckEBR(u8 PartNum, sec_t ebr_lba) { EXTENDED_BOOT_RECORD *ebr = (EXTENDED_BOOT_RECORD*)MEM2_alloc(MAX_BYTES_PER_SECTOR); if(ebr == NULL) return; sec_t next_erb_lba = 0; do { // Read and validate the extended boot record if(!interface->readSectors(ebr_lba + next_erb_lba, 1, ebr)) { MEM2_free(ebr); return; } if(ebr->signature != EBR_SIGNATURE && ebr->signature != EBR_SIGNATURE_MOD) { MEM2_free(ebr); return; } if(le32(ebr->partition.block_count) > 0 && !IsExisting(ebr_lba + next_erb_lba + le32(ebr->partition.lba_start))) { AddPartition(PartFromType(ebr->partition.type), ebr_lba + next_erb_lba + le32(ebr->partition.lba_start), le32(ebr->partition.block_count), (ebr->partition.status == PARTITION_BOOTABLE), ebr->partition.type, PartNum); } // Get the start sector of the current partition // and the next extended boot record in the chain next_erb_lba = le32(ebr->next_ebr.lba_start); } while(next_erb_lba > 0); MEM2_free(ebr); }
BranchSection::BranchSection(BranchPartition& p) { partitions.clear(); m_partitionNum = 0; AddPartition(p); }
void PartitionHandle::CheckEBR(int PartNum, sec_t ebr_lba) { EXTENDED_BOOT_RECORD *ebr = (EXTENDED_BOOT_RECORD *) malloc(MAX_SECTOR_SIZE); if(!ebr) return; sec_t next_erb_lba = 0; do { // Read and validate the extended boot record if (!interface->readSectors(ebr_lba + next_erb_lba, 1, ebr)) break; if (ebr->signature != EBR_SIGNATURE) break; PARTITION_RECORD * partition = (PARTITION_RECORD *) &ebr->partition; if(le32(partition->block_count) > 0) { AddPartition(PartFromType(partition->type), ebr_lba + next_erb_lba + le32(partition->lba_start), le32(partition->block_count), (partition->status == PARTITION_BOOTABLE), partition->type, PartNum, ebr_lba + next_erb_lba); } // Get the start sector of the current partition // and the next extended boot record in the chain next_erb_lba = le32(ebr->next_ebr.lba_start); } while(next_erb_lba > 0); free(ebr); }
int PartitionHandle::CheckGPT(int PartNum) { GPT_HEADER *gpt_header = (GPT_HEADER *) malloc(MAX_SECTOR_SIZE); if(!gpt_header) return -1; // Read and validate the extended boot record if (!interface->readSectors(1, 1, gpt_header)) { free(gpt_header); return -1; } if(strncmp(gpt_header->magic, "EFI PART", 8) != 0) { free(gpt_header); return -1; } gpt_header->part_table_lba = le64(gpt_header->part_table_lba); gpt_header->part_entries = le32(gpt_header->part_entries); gpt_header->part_entry_size = le32(gpt_header->part_entry_size); gpt_header->part_entry_checksum = le32(gpt_header->part_entry_checksum); u8 * sector_buf = (u8 *) malloc(MAX_SECTOR_SIZE); if(!sector_buf) { free(gpt_header); return -1; } u64 next_lba = gpt_header->part_table_lba; for(u32 i = 0; i < gpt_header->part_entries; ++i) { if (!interface->readSectors(next_lba, 1, sector_buf)) break; for(u32 n = 0; n < sectorSize/gpt_header->part_entry_size; ++n, ++i) { GUID_PART_ENTRY * part_entry = (GUID_PART_ENTRY *) (sector_buf+gpt_header->part_entry_size*n); if(memcmp(part_entry->part_type_guid, TYPE_UNUSED, 16) == 0) continue; bool bootable = (memcmp(part_entry->part_type_guid, TYPE_BIOS, 16) == 0); AddPartition("GUID-Entry", le64(part_entry->part_first_lba), le64(part_entry->part_last_lba), bootable, PARTITION_TYPE_GPT, PartNum); } next_lba++; } free(sector_buf); free(gpt_header); return 0; }
int PartitionHandle::FindPartitions() { MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD *) malloc(MAX_SECTOR_SIZE); if(!mbr) return -1; // Read the first sector on the device if (!interface->readSectors(0, 1, mbr)) { free(mbr); return -1; } // If this is the devices master boot record if (mbr->signature != MBR_SIGNATURE) { free(mbr); return -1; } for (int i = 0; i < 4; i++) { PARTITION_RECORD * partition = (PARTITION_RECORD *) &mbr->partitions[i]; if(partition->type == PARTITION_TYPE_GPT) { int ret = CheckGPT(i); if(ret == 0) break; } if(partition->type == PARTITION_TYPE_DOS33_EXTENDED || partition->type == PARTITION_TYPE_WIN95_EXTENDED) { CheckEBR(i, le32(partition->lba_start)); continue; } if(le32(partition->block_count) > 0) { AddPartition(PartFromType(partition->type), le32(partition->lba_start), le32(partition->block_count), (partition->status == PARTITION_BOOTABLE), partition->type, i); } } free(mbr); return 0; }
s8 PartitionHandle::FindPartitions() { MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD*)MEM2_alloc(MAX_BYTES_PER_SECTOR); if(mbr == NULL) return -1; // Read the first sector on the device if(!interface->readSectors(0, 1, mbr)) { MEM2_free(mbr); return -1; } // If this is the devices master boot record if(mbr->signature != MBR_SIGNATURE && mbr->signature != MBR_SIGNATURE_MOD) { MEM2_free(mbr); return -1; } for(u8 i = 0; i < 4; i++) { PARTITION_RECORD *partition = (PARTITION_RECORD *)&mbr->partitions[i]; if(partition->type == PARTITION_TYPE_GPT) { s8 ret = CheckGPT(i); if(ret == 0) // if it's a GPT we don't need to go on looking through the mbr anymore return ret; } if(partition->type == PARTITION_TYPE_DOS33_EXTENDED || partition->type == PARTITION_TYPE_WIN95_EXTENDED) { CheckEBR(i, le32(partition->lba_start)); continue; } if(le32(partition->block_count) > 0 && !IsExisting(le32(partition->lba_start))) { AddPartition(PartFromType(partition->type), le32(partition->lba_start), le32(partition->block_count), (partition->status == PARTITION_BOOTABLE), partition->type, i); } } MEM2_free(mbr); return 0; }
PartitionListRow* PartitionListView::AddPartition(BPartition* partition) { PartitionListRow* partitionrow = FindRow(partition->ID()); // forget about it if this partition is already in the listview if (partitionrow != NULL) return partitionrow; // create the row for this partition partitionrow = new PartitionListRow(partition); // see if this partition has a parent, or should have // a parent (add it in this case) PartitionListRow* parent = NULL; if (partition->Parent() != NULL) { // check if it is in the listview parent = FindRow(partition->Parent()->ID()); // If parent of this partition is not yet in the list if (parent == NULL) { // add it parent = AddPartition(partition->Parent()); } } // find a proper insertion index based on the on-disk offset int32 index = _InsertIndexForOffset(parent, partition->Offset()); // add the row, parent may be NULL (add at top level) AddRow(partitionrow, index, parent); // make sure the row is initially expanded ExpandOrCollapse(partitionrow, true); return partitionrow; }
static int FindPartitions(int device) { int i; int devnum = 0; // clear list for (i = 0; i < MAX_DEVICES; i++) { part[device][i].name[0] = 0; part[device][i].mount[0] = 0; part[device][i].sector = 0; part[device][i].interface = NULL; part[device][i].type = 0; } DISC_INTERFACE *interface; switch(device){ case DEVICE_ATAPI: interface = (DISC_INTERFACE *) & xenon_atapi_ops; break; case DEVICE_ATA: interface = (DISC_INTERFACE *) & xenon_ata_ops; break; case DEVICE_USB: interface = (DISC_INTERFACE *) & usb2mass_ops; break; } MASTER_BOOT_RECORD mbr; PARTITION_RECORD *partition = NULL; devnum = 0; sec_t part_lba = 0; union { u8 buffer[BYTES_PER_SECTOR]; MASTER_BOOT_RECORD mbr; EXTENDED_BOOT_RECORD ebr; NTFS_BOOT_SECTOR boot; } sector; if(device == DEVICE_ATAPI){ AddPartition(0, device, T_ISO9660, &devnum); return devnum; } // Read the first sector on the device if (!interface->readSectors(0, 1, §or.buffer)) { //errno = EIO; return -1; } // If this is the devices master boot record debug_printf("0x%x\n", sector.mbr.signature); if (sector.mbr.signature == MBR_SIGNATURE) { memcpy(&mbr, §or, sizeof (MASTER_BOOT_RECORD)); debug_printf("Valid Master Boot Record found\n"); // Search the partition table for all partitions (max. 4 primary partitions) for (i = 0; i < 4; i++) { partition = &mbr.partitions[i]; part_lba = le32_to_cpu(mbr.partitions[i].lba_start); debug_printf( "Partition %i: %s, sector %u, type 0x%x\n", i + 1, partition->status == PARTITION_STATUS_BOOTABLE ? "bootable (active)" : "non-bootable", part_lba, partition->type); // Figure out what type of partition this is switch (partition->type) { // NTFS partition case PARTITION_TYPE_NTFS: { debug_printf("Partition %i: Claims to be NTFS\n", i + 1); // Read and validate the NTFS partition if (interface->readSectors(part_lba, 1, §or)) { debug_printf("sector.boot.oem_id: 0x%x\n", sector.boot.oem_id); debug_printf("NTFS_OEM_ID: 0x%x\n", NTFS_OEM_ID); if (sector.boot.oem_id == NTFS_OEM_ID) { debug_printf("Partition %i: Valid NTFS boot sector found\n", i + 1); AddPartition(part_lba, device, T_NTFS, &devnum); } else { debug_printf("Partition %i: Invalid NTFS boot sector, not actually NTFS\n", i + 1); } } break; } // DOS 3.3+ or Windows 95 extended partition case PARTITION_TYPE_DOS33_EXTENDED: case PARTITION_TYPE_WIN95_EXTENDED: { debug_printf("Partition %i: Claims to be Extended\n", i + 1); // Walk the extended partition chain, finding all NTFS partitions within it sec_t ebr_lba = part_lba; sec_t next_erb_lba = 0; do { // Read and validate the extended boot record if (interface->readSectors(ebr_lba + next_erb_lba, 1, §or)) { if (sector.ebr.signature == EBR_SIGNATURE) { debug_printf( "Logical Partition @ %d: %s type 0x%x\n", ebr_lba + next_erb_lba, sector.ebr.partition.status == PARTITION_STATUS_BOOTABLE ? "bootable (active)" : "non-bootable", sector.ebr.partition.type); // Get the start sector of the current partition // and the next extended boot record in the chain part_lba = ebr_lba + next_erb_lba + le32_to_cpu( sector.ebr.partition.lba_start); next_erb_lba = le32_to_cpu( sector.ebr.next_ebr.lba_start); if (sector.ebr.partition.type == PARTITION_TYPE_LINUX) { debug_printf("Partition : type ext2/3/4 found\n"); AddPartition(part_lba, device, T_EXT2, &devnum); }// Check if this partition has a valid NTFS boot record else if (interface->readSectors(part_lba, 1, §or)) { if (sector.boot.oem_id == NTFS_OEM_ID) { debug_printf( "Logical Partition @ %d: Valid NTFS boot sector found\n", part_lba); if (sector.ebr.partition.type != PARTITION_TYPE_NTFS) { debug_printf( "Logical Partition @ %d: Is NTFS but type is 0x%x; 0x%x was expected\n", part_lba, sector.ebr.partition.type, PARTITION_TYPE_NTFS); } AddPartition(part_lba, device, T_NTFS, &devnum); } else if (!memcmp(sector.buffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof (FAT_SIG)) || !memcmp( sector.buffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof (FAT_SIG))) { debug_printf("Partition : Valid FAT boot sector found\n"); AddPartition(part_lba, device, T_FAT, &devnum); } } } else { next_erb_lba = 0; } } } while (next_erb_lba); break; } case PARTITION_TYPE_LINUX: { debug_printf("Partition %i: Claims to be LINUX\n", i + 1); // Read and validate the EXT2 partition AddPartition(part_lba, device, T_EXT2, &devnum); break; } // Ignore empty partitions case PARTITION_TYPE_EMPTY: debug_printf("Partition %i: Claims to be empty\n", i + 1); // Unknown or unsupported partition type default: { // Check if this partition has a valid NTFS boot record anyway, // it might be misrepresented due to a lazy partition editor if (interface->readSectors(part_lba, 1, §or)) { if (sector.boot.oem_id == NTFS_OEM_ID) { debug_printf("Partition %i: Valid NTFS boot sector found\n", i + 1); if (partition->type != PARTITION_TYPE_NTFS) { debug_printf( "Partition %i: Is NTFS but type is 0x%x; 0x%x was expected\n", i + 1, partition->type, PARTITION_TYPE_NTFS); } AddPartition(part_lba, device, T_NTFS, &devnum); } else if (!memcmp(sector.buffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof (FAT_SIG)) || !memcmp( sector.buffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof (FAT_SIG))) { debug_printf("Partition : Valid FAT boot sector found\n"); AddPartition(part_lba, device, T_FAT, &devnum); } else { debug_printf("Trying : ext partition\n"); AddPartition(part_lba, device, T_EXT2, &devnum); } } break; } } } } if (devnum == 0) // it is assumed this device has no master boot record or no partitions found { debug_printf("No Master Boot Record was found or no partitions found!\n"); // As a last-ditched effort, search the first 64 sectors of the device for stray NTFS/FAT partitions for (i = 0; i < 64; i++) { if (interface->readSectors(i, 1, §or)) { if (sector.boot.oem_id == NTFS_OEM_ID) { debug_printf("Valid NTFS boot sector found at sector %d!\n", i); AddPartition(i, device, T_NTFS, &devnum); break; } else if (!memcmp(sector.buffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof (FAT_SIG)) || !memcmp(sector.buffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof (FAT_SIG))) { debug_printf("Partition : Valid FAT boot sector found\n"); AddPartition(i, device, T_FAT, &devnum); break; } else { debug_printf("Trying : ext partition\n"); AddPartition(part_lba, device, T_EXT2, &devnum); } } } } return devnum; }
// Attempt to improve this by adding partitions or expanding partitions. void ColPartitionSet::ImproveColumnCandidate(WidthCallback* cb, PartSetVector* src_sets) { int set_size = src_sets->size(); // Iterate over the provided column sets, as each one may have something // to improve this. for (int i = 0; i < set_size; ++i) { ColPartitionSet* column_set = src_sets->get(i); if (column_set == NULL) continue; // Iterate over the parts in this and column_set, adding bigger or // new parts in column_set to this. ColPartition_IT part_it(&parts_); ASSERT_HOST(!part_it.empty()); int prev_right = MIN_INT32; part_it.mark_cycle_pt(); ColPartition_IT col_it(&column_set->parts_); for (col_it.mark_cycle_pt(); !col_it.cycled_list(); col_it.forward()) { ColPartition* col_part = col_it.data(); if (col_part->blob_type() < BRT_UNKNOWN) continue; // Ignore image partitions. int col_left = col_part->left_key(); int col_right = col_part->right_key(); // Sync-up part_it (in this) so it matches the col_part in column_set. ColPartition* part = part_it.data(); while (!part_it.at_last() && part->right_key() < col_left) { prev_right = part->right_key(); part_it.forward(); part = part_it.data(); } int part_left = part->left_key(); int part_right = part->right_key(); if (part_right < col_left || col_right < part_left) { // There is no overlap so this is a new partition. AddPartition(col_part->ShallowCopy(), &part_it); continue; } // Check the edges of col_part to see if they can improve part. bool part_width_ok = cb->Run(part->KeyWidth(part_left, part_right)); if (col_left < part_left && col_left > prev_right) { // The left edge of the column is better and it doesn't overlap, // so we can potentially expand it. int col_box_left = col_part->BoxLeftKey(); bool tab_width_ok = cb->Run(part->KeyWidth(col_left, part_right)); bool box_width_ok = cb->Run(part->KeyWidth(col_box_left, part_right)); if (tab_width_ok || (!part_width_ok )) { // The tab is leaving the good column metric at least as good as // it was before, so use the tab. part->CopyLeftTab(*col_part, false); part->SetColumnGoodness(cb); } else if (col_box_left < part_left && (box_width_ok || !part_width_ok)) { // The box is leaving the good column metric at least as good as // it was before, so use the box. part->CopyLeftTab(*col_part, true); part->SetColumnGoodness(cb); } part_left = part->left_key(); } if (col_right > part_right && (part_it.at_last() || part_it.data_relative(1)->left_key() > col_right)) { // The right edge is better, so we can possibly expand it. int col_box_right = col_part->BoxRightKey(); bool tab_width_ok = cb->Run(part->KeyWidth(part_left, col_right)); bool box_width_ok = cb->Run(part->KeyWidth(part_left, col_box_right)); if (tab_width_ok || (!part_width_ok )) { // The tab is leaving the good column metric at least as good as // it was before, so use the tab. part->CopyRightTab(*col_part, false); part->SetColumnGoodness(cb); } else if (col_box_right > part_right && (box_width_ok || !part_width_ok)) { // The box is leaving the good column metric at least as good as // it was before, so use the box. part->CopyRightTab(*col_part, true); part->SetColumnGoodness(cb); } } } } ComputeCoverage(); }
bool PartitionHandle::Mount(int pos, const char *name, bool forceFAT) { if(valid(pos)) UnMount(pos); if(!name) return false; if(pos >= (int)MountNameList.size()) MountNameList.resize(pos + 1); MountNameList[pos] = name; char DeviceSyn[10]; memcpy(DeviceSyn, name, 8); strcat(DeviceSyn, ":"); DeviceSyn[9] = '\0'; //! Some stupid partition manager think they don't need to edit the freaken MBR. //! So we need to check the first 64 sectors and see if some partition is there. //! libfat does that by default so let's use it. if(forceFAT && (strlen(GetFSName(pos)) == 0 || strcmp(GetFSName(pos), "Unknown") == 0)) { if(fatMount(MountNameList[pos].c_str(), interface, 0, CACHE, SECTORS)) { sec_t FAT_startSector = FindFirstValidPartition(interface); AddPartition("FAT", FAT_startSector, 0xdeadbeaf, true, 0x0c, 0); gprintf("FAT Partition at %s (forceFAT) mounted.\n", DeviceSyn); SetWbfsHandle(pos, NULL); return true; } } if(!valid(pos)) return false; SetWbfsHandle(pos, NULL); if(strncmp(GetFSName(pos), "FAT", 3) == 0 || strcmp(GetFSName(pos), "GUID-Entry") == 0) { if(fatMount(MountNameList[pos].c_str(), interface, GetLBAStart(pos), CACHE, SECTORS)) { gprintf("FAT Partition at %s mounted.\n", DeviceSyn); PartitionList[pos].FSName = "FAT"; return true; } } else if(strncmp(GetFSName(pos), "NTFS", 4) == 0 || strcmp(GetFSName(pos), "GUID-Entry") == 0) { if(ntfsMount(MountNameList[pos].c_str(), interface, GetLBAStart(pos), CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER)) { gprintf("NTFS Partition at %s mounted.\n", DeviceSyn); PartitionList[pos].FSName = "NTFS"; return true; } } else if(strncmp(GetFSName(pos), "LINUX", 5) == 0 || strcmp(GetFSName(pos), "GUID-Entry") == 0) { if(ext2Mount(MountNameList[pos].c_str(), interface, GetLBAStart(pos), CACHE, SECTORS, EXT2_FLAG_DEFAULT)) { gprintf("EXT Partition at %s mounted.\n", DeviceSyn); PartitionList[pos].FSName = "LINUX"; return true; } } else if(strncmp(GetFSName(pos), "WBFS", 4) == 0) { if(interface == &__io_usbstorage2_port0 || interface == &__io_usbstorage2_port1) SetWbfsHandle(pos, wbfs_open_partition(__WBFS_ReadUSB, __WBFS_WriteUSB, NULL, USBStorage2_GetSectorSize(), GetSecCount(pos), GetLBAStart(pos), 0)); else if(interface == &__io_sdhc) SetWbfsHandle(pos, wbfs_open_partition(__WBFS_ReadSDHC, __WBFS_WriteSDHC, NULL, 512, GetSecCount(pos), GetLBAStart(pos), 0)); if(GetWbfsHandle(pos)) { gprintf("WBFS Partition at %s mounted.\n", DeviceSyn); PartitionList[pos].FSName = "WBFS"; return true; } } /* FAIL */ MountNameList[pos].clear(); return false; }