From aed8bda95544bff465457e9a0d72502e343e91b0 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Mon, 18 Feb 2019 12:47:09 +0100 Subject: [PATCH] New API calls iso_write_opts_set_part_type_guid(), iso_write_opts_set_iso_type_guid() --- libisofs/ecma119.c | 27 +++++++++++++++++++ libisofs/ecma119.h | 19 +++++++++++-- libisofs/libisofs.h | 60 +++++++++++++++++++++++++++++++++++++++--- libisofs/libisofs.ver | 2 ++ libisofs/system_area.c | 15 ++++++++--- 5 files changed, 113 insertions(+), 10 deletions(-) diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index 38072de..0b6aa61 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -3588,11 +3588,15 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile) wopts->appended_partitions[i] = NULL; wopts->appended_part_types[i] = 0; wopts->appended_part_flags[i] = 0; + memset(wopts->appended_part_type_guids[i], 0, 16); + wopts->appended_part_gpt_flags[i] = 0; } wopts->appended_as_gpt = 0; wopts->appended_as_apm = 0; wopts->part_like_isohybrid = 0; wopts->iso_mbr_part_type = -1; + memset(wopts->iso_gpt_type_guid, 0, 16); + wopts->iso_gpt_flag= 0; wopts->ascii_disc_label[0] = 0; wopts->will_cancel = 0; wopts->allow_dir_id_ext = 0; @@ -4310,6 +4314,20 @@ int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number, return ISO_SUCCESS; } +int iso_write_opts_set_part_type_guid(IsoWriteOpts *opts, int partition_number, + uint8_t guid[16], int valid) +{ + if (partition_number < 1 || partition_number > ISO_MAX_PARTITIONS) + return ISO_BAD_PARTITION_NO; + if (valid) + memcpy(opts->appended_part_type_guids[partition_number - 1], guid, 16); + if (valid) + opts->appended_part_gpt_flags[partition_number - 1]|= 1; + else + opts->appended_part_gpt_flags[partition_number - 1]&= ~1; + return ISO_SUCCESS; +} + int iso_write_opts_set_appended_as_gpt(IsoWriteOpts *opts, int gpt) { opts->appended_as_gpt = !!gpt; @@ -4336,6 +4354,15 @@ int iso_write_opts_set_iso_mbr_part_type(IsoWriteOpts *opts, int part_type) return ISO_SUCCESS; } +int iso_write_opts_set_iso_type_guid(IsoWriteOpts *opts, uint8_t guid[16], + int valid) +{ + if (valid) + memcpy(opts->iso_gpt_type_guid, guid, 16); + opts->iso_gpt_flag = (opts->iso_gpt_flag & ~1) | !!valid; + 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 8a4b0cf..3584b32 100644 --- a/libisofs/ecma119.h +++ b/libisofs/ecma119.h @@ -476,12 +476,19 @@ struct iso_write_opts { char *efi_boot_partition; int efi_boot_part_flag; - /* Eventual disk file paths of prepared images which shall be appended - after the ISO image and described by partiton table entries in a MBR + /* Disk file paths of prepared images which shall be appended + after the ISO image and described by partiton table entries in a MBR. + NULL means unused. */ char *appended_partitions[ISO_MAX_PARTITIONS]; uint8_t appended_part_types[ISO_MAX_PARTITIONS]; int appended_part_flags[ISO_MAX_PARTITIONS]; + uint8_t appended_part_type_guids[ISO_MAX_PARTITIONS][16]; + + /* Flags in case that appended partitions show up in GPT: + bit0= appended_part_type_guids is valid + */ + uint8_t appended_part_gpt_flags[ISO_MAX_PARTITIONS]; /* If 1: With appended partitions: create protective MBR and mark by GPT */ @@ -504,6 +511,14 @@ struct iso_write_opts { */ int iso_mbr_part_type; + /* iso_write_opts_set_iso_type_guid + */ + uint8_t iso_gpt_type_guid[16]; + /* bit0= iso_gpt_type_guid is valid + */ + int iso_gpt_flag; + + /* 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 3c7456b..030e4c1 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -4,7 +4,7 @@ /* * Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic - * Copyright (c) 2009-2018 Thomas Schmitt + * Copyright (c) 2009-2019 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 @@ -2626,9 +2626,10 @@ int iso_write_opts_set_efi_bootp(IsoWriteOpts *opts, char *image_path, * @param opts * The option set to be manipulated. * @param guid - * 16 bytes of user supplied GUID. Readily byte-swapped as prescribed by - * UEFI specs: 4 byte, 2 byte, 2 byte as little-endian. The rest as - * big-endian. + * 16 bytes of user supplied GUID. Readily byte-swapped from the text + * form as prescribed by UEFI specs: + * 4 byte, 2 byte, 2 byte as little-endian. + * 2 byte, 6 byte as big-endian. * The upper 4 bit of guid[7] should bear the value 4 to express the * RFC 4122 version 4. Bit 7 of byte[8] should be set to 1 and bit 6 * be set to 0, in order to express the RFC 4122 variant of UUID, @@ -2721,6 +2722,32 @@ int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number, */ int iso_write_opts_set_appended_as_gpt(IsoWriteOpts *opts, int gpt); +/** + * Set the GPT Type GUID for a partition defined by + * iso_write_opts_set_partition_img(). + * + * @param opts + * The option set to be manipulated. + * @param partition_number + * Depicts the partition table entry which shall get the Type GUID. + * @param guid + * 16 bytes of user supplied GUID. Readily byte-swapped from the text + * form as prescribed by UEFI specs: + * 4 byte, 2 byte, 2 byte as little-endian. + * 2 byte, 6 byte as big-endian. + * @param valid + * Set to 1 to make this Type GUID valid. + * Set to 0 in order to invalidate a previously made setting. In this + * case MBR type 0xEF will become the EFI Type GUID. All others will + * become the Basic Data Partition Type GUID. + * @return + * ISO_SUCCESS or error + * + * @since 1.5.2 + */ +int iso_write_opts_set_part_type_guid(IsoWriteOpts *opts, int partition_number, + uint8_t guid[16], int valid); + /** * Control whether partitions created by iso_write_opts_set_partition_img() * are to be represented in Apple Partition Map. @@ -2780,10 +2807,35 @@ int iso_write_opts_set_part_like_isohybrid(IsoWriteOpts *opts, int alike); * 0x00 to 0xff as desired partition type. * Any other value (e.g. -1) enables the default types of the various * occasions. + * @return + * ISO_SUCCESS or error * @since 1.4.8 */ int iso_write_opts_set_iso_mbr_part_type(IsoWriteOpts *opts, int part_type); +/** + * Set the GPT Type GUID for the partition which represents the ISO 9660 + * filesystem, if such a partition emerges in GPT. + * @param opts + * The option set to be manipulated. + * @param guid + * 16 bytes of user supplied GUID. Readily byte-swapped from the text + * form as prescribed by UEFI specs: + * 4 byte, 2 byte, 2 byte as little-endian. + * 2 byte, 6 byte as big-endian. + * @param valid + * Set to 1 to make this Type GUID valid. + * Set to 0 in order to invalidate a previously made setting. In this + * case the setting of iso_write_opts_set_iso_mbr_part_type() or its + * default will get into effect. + * @return + * ISO_SUCCESS or error + * + * @since 1.5.2 + */ +int iso_write_opts_set_iso_type_guid(IsoWriteOpts *opts, uint8_t guid[16], + int valid); + /** * Inquire the start address of the file data blocks after having used * IsoWriteOpts with iso_image_create_burn_source(). diff --git a/libisofs/libisofs.ver b/libisofs/libisofs.ver index 4f03ac4..70cd2c2 100644 --- a/libisofs/libisofs.ver +++ b/libisofs/libisofs.ver @@ -334,6 +334,7 @@ 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_iso_type_guid; iso_write_opts_set_joliet; iso_write_opts_set_joliet_long_names; iso_write_opts_set_joliet_longer_paths; @@ -347,6 +348,7 @@ iso_write_opts_set_output_charset; iso_write_opts_set_overwrite_buf; iso_write_opts_set_part_offset; iso_write_opts_set_part_like_isohybrid; +iso_write_opts_set_part_type_guid; iso_write_opts_set_partition_img; iso_write_opts_set_prep_img; iso_write_opts_set_pvd_times; diff --git a/libisofs/system_area.c b/libisofs/system_area.c index ebe76aa..ab1ba8a 100644 --- a/libisofs/system_area.c +++ b/libisofs/system_area.c @@ -1726,6 +1726,7 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf) struct iso_gpt_partition_request *req; uint8_t gpt_name[72]; static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + static uint8_t *type_guid; static uint64_t gpt_flags = (((uint64_t) 1) << 60) | 1; if (t->gpt_req_count == 0) @@ -1774,16 +1775,20 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf) } } else if (part_end < goal) { memset(gpt_name, 0, 72); + type_guid = basic_data_uuid; if (goal == t->vol_space_size * (uint64_t) 4 && - part_end == t->opts->partition_offset * (uint64_t) 4) + part_end == t->opts->partition_offset * (uint64_t) 4) { sprintf((char *) gpt_name, "ISO9660"); - else + if (t->opts->iso_gpt_flag & 1) + type_guid = t->opts->iso_gpt_type_guid; + } else { sprintf((char *) gpt_name, "Gap%d", gap_counter); + } iso_ascii_utf_16le(gpt_name); gap_counter++; ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count), part_end, goal - part_end, - basic_data_uuid, zero_uuid, + type_guid, zero_uuid, gpt_flags, gpt_name); if (ret < 0) return ret; @@ -2664,7 +2669,9 @@ int assess_appended_gpt(Ecma119Image *t, int flag) memset(gpt_name, 0, 72); sprintf((char *) gpt_name, "Appended%d", i + 1); iso_ascii_utf_16le(gpt_name); - if (t->opts->appended_part_types[i] == 0xef) + if (t->opts->appended_part_gpt_flags[i] & 1) + type_uuid = t->opts->appended_part_type_guids[i]; + else if (t->opts->appended_part_types[i] == 0xef) type_uuid = efi_sys_uuid; else type_uuid = basic_data_uuid;