nyx: tools: fix hybrid mbr changes

- MBR is now checked if it has GPT partition, in order to avoid revival of a dead but valid GPT
- MBR secret attributes can now be cleared even if there's no GPT
This commit is contained in:
CTCaer 2022-05-27 04:44:42 +03:00
parent c77c741c07
commit 0e526bf9e8

View file

@ -2074,6 +2074,14 @@ static lv_res_t _action_fix_mbr(lv_obj_t *btn)
lv_obj_t *lbl_status = lv_label_create(mbox, NULL); lv_obj_t *lbl_status = lv_label_create(mbox, NULL);
lv_label_set_recolor(lbl_status, true); lv_label_set_recolor(lbl_status, true);
mbr_t mbr[2] = { 0 };
gpt_t *gpt = calloc(1, sizeof(gpt_t));
gpt_header_t gpt_hdr_backup = { 0 };
bool has_mbr_attributes = false;
bool hybrid_mbr_changed = false;
bool gpt_partition_exists = false;
// Try to init sd card. No need for valid MBR. // Try to init sd card. No need for valid MBR.
if (!sd_mount() && !sd_get_card_initialized()) if (!sd_mount() && !sd_get_card_initialized())
{ {
@ -2081,10 +2089,6 @@ static lv_res_t _action_fix_mbr(lv_obj_t *btn)
goto out; goto out;
} }
mbr_t mbr[2] = { 0 };
gpt_t *gpt = calloc(1, sizeof(gpt_t));
gpt_header_t gpt_hdr_backup = { 0 };
sdmmc_storage_read(&sd_storage, 0, 1, &mbr[0]); sdmmc_storage_read(&sd_storage, 0, 1, &mbr[0]);
sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, gpt); sdmmc_storage_read(&sd_storage, 1, sizeof(gpt_t) >> 9, gpt);
@ -2092,10 +2096,27 @@ static lv_res_t _action_fix_mbr(lv_obj_t *btn)
sd_unmount(); sd_unmount();
if (memcmp(&gpt->header.signature, "EFI PART", 8) || gpt->header.num_part_ents > 128) // Check for secret MBR attributes.
if (gpt->entries[0].part_guid[7])
has_mbr_attributes = true;
// Check if there's a GPT Protective partition.
for (u32 i = 0; i < 4; i++)
{
if (mbr[0].partitions[i].type == 0xEE)
gpt_partition_exists = true;
}
// Check if GPT is valid.
if (!gpt_partition_exists || memcmp(&gpt->header.signature, "EFI PART", 8) || gpt->header.num_part_ents > 128)
{ {
lv_label_set_text(lbl_status, "#FFDD00 Warning:# No valid GPT was found!"); lv_label_set_text(lbl_status, "#FFDD00 Warning:# No valid GPT was found!");
free(gpt);
gpt_partition_exists = false;
if (has_mbr_attributes)
goto check_changes;
else
goto out; goto out;
} }
@ -2166,7 +2187,6 @@ static lv_res_t _action_fix_mbr(lv_obj_t *btn)
mbr[1].partitions[mbr_idx].size_sct = sd_storage.sec_cnt - 1; mbr[1].partitions[mbr_idx].size_sct = sd_storage.sec_cnt - 1;
// Check for differences. // Check for differences.
bool hybrid_mbr_changed = false;
for (u32 i = 1; i < 4; i++) for (u32 i = 1; i < 4; i++)
{ {
if ((mbr[0].partitions[i].type != mbr[1].partitions[i].type) || if ((mbr[0].partitions[i].type != mbr[1].partitions[i].type) ||
@ -2178,15 +2198,10 @@ static lv_res_t _action_fix_mbr(lv_obj_t *btn)
} }
} }
// Check for secret MBR attributes. check_changes:
bool has_mbr_attributes = false;
if (gpt->entries[0].part_guid[7])
has_mbr_attributes = true;
if (!hybrid_mbr_changed && !has_mbr_attributes) if (!hybrid_mbr_changed && !has_mbr_attributes)
{ {
lv_label_set_text(lbl_status, "#96FF00 Warning:# The Hybrid MBR needs no change!#"); lv_label_set_text(lbl_status, "#96FF00 Warning:# The Hybrid MBR needs no change!#");
free(gpt);
goto out; goto out;
} }
@ -2248,6 +2263,8 @@ static lv_res_t _action_fix_mbr(lv_obj_t *btn)
// Clear secret attributes. // Clear secret attributes.
gpt->entries[0].part_guid[7] = 0; gpt->entries[0].part_guid[7] = 0;
if (gpt_partition_exists)
{
// Fix CRC32s. // Fix CRC32s.
u32 entries_size = sizeof(gpt_entry_t) * gpt->header.num_part_ents; u32 entries_size = sizeof(gpt_entry_t) * gpt->header.num_part_ents;
gpt->header.part_ents_crc32 = crc32_calc(0, (const u8 *)gpt->entries, entries_size); gpt->header.part_ents_crc32 = crc32_calc(0, (const u8 *)gpt->entries, entries_size);
@ -2268,6 +2285,12 @@ static lv_res_t _action_fix_mbr(lv_obj_t *btn)
// Write backup GPT header. // Write backup GPT header.
sdmmc_storage_write(&sd_storage, gpt_hdr_backup.my_lba, 1, &gpt_hdr_backup); sdmmc_storage_write(&sd_storage, gpt_hdr_backup.my_lba, 1, &gpt_hdr_backup);
} }
else
{
// Only write the relevant sector if the only change is MBR attributes.
sdmmc_storage_write(&sd_storage, 2, 1, &gpt->entries[0]);
}
}
sd_unmount(); sd_unmount();
@ -2275,9 +2298,10 @@ static lv_res_t _action_fix_mbr(lv_obj_t *btn)
} }
else else
lv_label_set_text(lbl_status, "#FFDD00 Warning: The Hybrid MBR Fix was canceled!#"); lv_label_set_text(lbl_status, "#FFDD00 Warning: The Hybrid MBR Fix was canceled!#");
free(gpt);
out: out:
free(gpt);
lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action); lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action);
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);