From e66b9bfe0c7552df2d174cea158a464140c57b6f Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Mon, 27 Feb 2017 09:59:34 +0100 Subject: [PATCH] New API call iso_write_opts_set_iso_mbr_part_type() --- libisofs/ecma119.c | 11 ++++++++++- libisofs/ecma119.h | 10 +++++++++- libisofs/libisofs.h | 17 ++++++++++++++++- libisofs/libisofs.ver | 1 + libisofs/system_area.c | 38 +++++++++++++++++++++++++++++++------- 5 files changed, 67 insertions(+), 10 deletions(-) diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index c150e0b..e4f90a1 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2007 Vreixo Formoso * Copyright (c) 2007 Mario Danic - * Copyright (c) 2009 - 2016 Thomas Schmitt + * Copyright (c) 2009 - 2017 Thomas Schmitt * * This file is part of the libisofs project; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 @@ -3483,6 +3483,7 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile) wopts->appended_as_gpt = 0; wopts->appended_as_apm = 0; wopts->part_like_isohybrid = 0; + wopts->iso_mbr_part_type = -1; wopts->ascii_disc_label[0] = 0; wopts->will_cancel = 0; wopts->allow_dir_id_ext = 0; @@ -4218,6 +4219,14 @@ int iso_write_opts_set_part_like_isohybrid(IsoWriteOpts *opts, int alike) return ISO_SUCCESS; } +int iso_write_opts_set_iso_mbr_part_type(IsoWriteOpts *opts, int part_type) +{ + if (part_type < -1 || part_type > 255) + part_type = -1; + opts->iso_mbr_part_type = part_type; + return ISO_SUCCESS; +} + int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label) { strncpy(opts->ascii_disc_label, label, ISO_DISC_LABEL_SIZE - 1); diff --git a/libisofs/ecma119.h b/libisofs/ecma119.h index 9792dca..07f1f64 100644 --- a/libisofs/ecma119.h +++ b/libisofs/ecma119.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2007 Vreixo Formoso - * Copyright (c) 2009 - 2015 Thomas Schmitt + * Copyright (c) 2009 - 2017 Thomas Schmitt * * This file is part of the libisofs project; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 @@ -496,6 +496,14 @@ struct iso_write_opts { */ int part_like_isohybrid; + /* The type to use for the mountable ISO partition if there is any and if + the type is not mandatorily determined for particular circumstances like + compliant GPT, CHRP, or PReP. + -1 = use the default value (e.g. 0xcd, 0x83, 0x17) + 0x00 to 0xff = value to use if possible + */ + int iso_mbr_part_type; + /* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label. */ char ascii_disc_label[ISO_DISC_LABEL_SIZE]; diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 759dce2..21c18f2 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -4,7 +4,7 @@ /* * Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic - * Copyright (c) 2009-2016 Thomas Schmitt + * Copyright (c) 2009-2017 Thomas Schmitt * * This file is part of the libisofs project; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 @@ -2749,6 +2749,21 @@ int iso_write_opts_set_appended_as_apm(IsoWriteOpts *opts, int apm); */ int iso_write_opts_set_part_like_isohybrid(IsoWriteOpts *opts, int alike); +/** + * Set the partition type of the MBR partition which represents the ISO + * filesystem or at least protects it. + * This is without effect if no such partition emerges by other settings or + * if the partition type is prescribed mandatorily like 0xee for GPT protective + * MBR or 0x96 for CHRP. + * @param opts + * The option set to be manipulated. + * @param part_type + * 0x00 to 0xff as desired partition type. + * Any other value (e.g. -1) enables the default types of the various + * occasions. + * @since 1.4.8 + */ +int iso_write_opts_set_iso_mbr_part_type(IsoWriteOpts *opts, int part_type); /** * Inquire the start address of the file data blocks after having used diff --git a/libisofs/libisofs.ver b/libisofs/libisofs.ver index d0052b7..c1be389 100644 --- a/libisofs/libisofs.ver +++ b/libisofs/libisofs.ver @@ -330,6 +330,7 @@ iso_write_opts_set_hfsp_serial_number; iso_write_opts_set_hfsplus; iso_write_opts_set_iso1999; iso_write_opts_set_iso_level; +iso_write_opts_set_iso_mbr_part_type; iso_write_opts_set_joliet; iso_write_opts_set_joliet_long_names; iso_write_opts_set_joliet_longer_paths; diff --git a/libisofs/system_area.c b/libisofs/system_area.c index 5a7fd95..1dda499 100644 --- a/libisofs/system_area.c +++ b/libisofs/system_area.c @@ -1918,6 +1918,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf) pml_blocks = gpt_blocks; } else { part_type = 0xcd; + if (t->opts->iso_mbr_part_type >= 0 && + t->opts->iso_mbr_part_type <= 255) + part_type= t->opts->iso_mbr_part_type; pml_blocks = img_blocks; } ret = make_grub_msdos_label(pml_blocks, t->partition_secs_per_head, @@ -1942,8 +1945,12 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf) if (gpt_count > 0 || apm_count > 0) part_type = 0x00; - else + else { part_type = 0x17; + 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; @@ -1985,9 +1992,13 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf) } else if ((t->opts->partition_offset > 0 || will_append) && sa_type == 0 && t->mbr_req_count == 0) { /* Write a simple partition table. */ + part_type = 0xcd; + if (t->opts->iso_mbr_part_type >= 0 && + t->opts->iso_mbr_part_type <= 255) + part_type= t->opts->iso_mbr_part_type; ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head, t->partition_heads_per_cyl, - (uint8_t) 0xcd, buf, 2); + (uint8_t) part_type, buf, 2); if (ret != ISO_SUCCESS) /* error should never happen */ return ISO_ASSERT_FAILURE; risk_of_ee = 1; @@ -2007,7 +2018,11 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf) } else if (t->opts->partition_offset == 0) { /* Re-write partion entry 1 : start at 0, type Linux */ blk = ((uint64_t) img_blocks) * 4 - t->post_iso_part_pad / 512; - ret = write_mbr_partition_entry(1, 0x83, (uint64_t) 0, blk, + part_type = 0x83; + 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(1, part_type, (uint64_t) 0, blk, t->partition_secs_per_head, t->partition_heads_per_cyl, buf, 2); if (ret < 0) @@ -2087,7 +2102,11 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf) iso_msgs_submit(0, "Prevented partition type 0xEE in MBR without GPT", 0, "WARNING", 0); - buf[446 + 16 * i + 4] = 0xcd; + part_type = 0xcd; + if (t->opts->iso_mbr_part_type >= 0 && + t->opts->iso_mbr_part_type <= 255) + part_type= t->opts->iso_mbr_part_type; + buf[446 + 16 * i + 4] = (uint8_t) part_type; } } } @@ -2821,7 +2840,7 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer) { Ecma119Image *t; IsoFileSrc *src; - int ret, will_have_gpt = 0, with_chrp = 0, i; + int ret, will_have_gpt = 0, with_chrp = 0, i, part_type; static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; static uint64_t gpt_flags = (((uint64_t) 1) << 60) | 1; uint8_t gpt_name[72]; @@ -2893,11 +2912,16 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer) } if (t->prep_part_size > 0 || t->opts->fat || will_have_gpt) { /* Protecting MBR entry for ISO start or whole ISO */ + part_type = 0xcd; + if (t->opts->iso_mbr_part_type >= 0 && + t->opts->iso_mbr_part_type <= 255) + part_type= t->opts->iso_mbr_part_type; + if (will_have_gpt) + part_type = 0xee; ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count), will_have_gpt ? (uint64_t) 1 : ((uint64_t) t->opts->partition_offset) * 4, - (uint64_t) 0, - will_have_gpt ? 0xee : 0xcd, 0, 0); + (uint64_t) 0, part_type, 0, 0); if (ret < 0) return ret; }