diff --git a/libisofs/make_isohybrid_mbr.c b/libisofs/make_isohybrid_mbr.c index 810e34e..20be2b8 100644 --- a/libisofs/make_isohybrid_mbr.c +++ b/libisofs/make_isohybrid_mbr.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2002 - 2008 H. Peter Anvin - * Copyright (c) 2008 - 2015 Thomas Schmitt + * Copyright (c) 2008 - 2022 Thomas Schmitt * with special credits to Matthew Garrett for isohybrid with GPT and APM * * This file is part of the libisofs project; you can redistribute it and/or @@ -625,8 +625,12 @@ static uint32_t iso_make_mbr_id(Ecma119Image *t, int flag) /* * @param flag bit0= make own random MBR Id from current time - * >>> or from overridden modification time + * or from overridden modification time * bit1= create protective MBR as of UEFI/GPT specs + * bit2= write only partition table + * do not insert APM mockup head + * do not treat bytes before code as isohybrid MBR + * do not create MBR id */ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t, int part_offset, int part_number, int fs_type, @@ -662,39 +666,44 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t, if (ret < 0) return ret; - /* The rest of APM has already been written by iso_write_apm(). - But the isohybrid APM head differs from the hfsplus_writer APM head. - */ - ret = insert_apm_head(buf, apm_count); - if (ret < 0) - return ret; - - /* Padding of image_size to a multiple of sector_count*head_count - happens already at compute time and is implemented by - an appropriate increase of Ecma119Image->tail_blocks. - */ - - wpt = (char *) buf + 432; - - /* write qword boot_lba # Offset 432 - */ - hd_boot_lba = ((off_t) boot_lba) * (off_t) 4; - lsb_to_buf(&wpt, hd_boot_lba & 0xffffffff, 32, 0); - lsb_to_buf(&wpt, hd_boot_lba >> 32, 32, 0); - - /* write dword mbr_id # Offset 440 - (here some 32-bit random value with no crypto strength) - */ - if (flag & 1) { - id = iso_make_mbr_id(t, 0); - lsb_to_buf(&wpt, id, 32, 0); + if(flag & 4) { + wpt= (char *) buf + 446; } else { - wpt+= 4; - } - /* write word 0 # Offset 444 - */ - lsb_to_buf(&wpt, 0, 16, 0); + /* The rest of APM has already been written by iso_write_apm(). + But the isohybrid APM head differs from the hfsplus_writer APM head. + */ + ret = insert_apm_head(buf, apm_count); + if (ret < 0) + return ret; + + /* Padding of image_size to a multiple of sector_count*head_count + happens already at compute time and is implemented by + an appropriate increase of Ecma119Image->tail_blocks. + */ + + wpt = (char *) buf + 432; + + /* write qword boot_lba # Offset 432 + */ + hd_boot_lba = ((off_t) boot_lba) * (off_t) 4; + lsb_to_buf(&wpt, hd_boot_lba & 0xffffffff, 32, 0); + lsb_to_buf(&wpt, hd_boot_lba >> 32, 32, 0); + + /* write dword mbr_id # Offset 440 + (here some 32-bit random value with no crypto strength) + */ + if (flag & 1) { + id = iso_make_mbr_id(t, 0); + lsb_to_buf(&wpt, id, 32, 0); + } else { + wpt+= 4; + } + + /* write word 0 # Offset 444 + */ + lsb_to_buf(&wpt, 0, 16, 0); + } /* # Offset 446 */ diff --git a/libisofs/system_area.c b/libisofs/system_area.c index 05aa603..b8607f1 100644 --- a/libisofs/system_area.c +++ b/libisofs/system_area.c @@ -1912,7 +1912,7 @@ int iso_ensure_mbr_part_table(Ecma119Image *t, uint32_t img_blocks, if (t->opts->iso_mbr_part_type >= 0 && t->opts->iso_mbr_part_type <= 255) part_type= t->opts->iso_mbr_part_type; - ret = write_mbr_partition_entry(found_part, part_type, + ret = write_mbr_partition_entry(found_part, part_type, start_lba, img_blocks * 4, t->partition_secs_per_head, t->partition_heads_per_cyl, buf, 2); @@ -2006,8 +2006,10 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag) */ apm_flag = 0; - if (sa_type == 0 && (t->system_area_options & 3) == 2) { - do_isohybrid = 1; + if (sa_type == 0 && ((t->system_area_options & 3) == 2 || + t->opts->part_like_isohybrid)) { + if (sa_type == 0 && (t->system_area_options & 3) == 2) + do_isohybrid = 1; /* >>> Coordinate with partprepend writer */ /* <<< provisory trap */ @@ -2078,9 +2080,12 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag) /* >>> ??? change first partition type to 0xee */; } - } else if (do_isohybrid) { - /* Patch externally provided system area as isohybrid MBR */ - if (t->catalog == NULL || t->system_area_data == NULL) { + } else if (do_isohybrid || t->opts->part_like_isohybrid) { + /* Patch externally provided system area as isohybrid MBR + or at least write an MBR partition table as of isohybrid + */ + if ((t->catalog == NULL || t->system_area_data == NULL) && + do_isohybrid) { /* isohybrid makes only sense together with ISOLINUX boot image and externally provided System Area. */ @@ -2089,12 +2094,13 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag) if (gpt_count > 0 || apm_count > 0) part_type = 0x00; - else { + else part_type = 0x17; + /* By tradition, real isohybrid insists in 0x00 if GPT or APM */ + if (part_type != 0x00 || !do_isohybrid) if (t->opts->iso_mbr_part_type >= 0 && t->opts->iso_mbr_part_type <= 255) part_type= t->opts->iso_mbr_part_type; - } if (t->opts->appended_as_gpt && t->have_appended_partitions) { part_type = 0xee; @@ -2109,7 +2115,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag) */; ret = make_isolinux_mbr(&img_blocks, t, 0, 1, part_type, buf, - 1 | no_boot_mbr); + 1 | no_boot_mbr | ((!do_isohybrid) << 2)); if (ret != 1) return ret; } else if (sa_type == 1) {