New API calls iso_write_opts_set_appended_as_apm(), iso_write_opts_set_part_like_isohybrid()

This commit is contained in:
Thomas Schmitt 2016-02-05 10:47:04 +01:00
parent 7c05d2a865
commit 31fcdc0ba6
5 changed files with 113 additions and 85 deletions

View File

@ -3398,6 +3398,8 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
wopts->appended_part_flags[i] = 0; wopts->appended_part_flags[i] = 0;
} }
wopts->appended_as_gpt = 0; wopts->appended_as_gpt = 0;
wopts->appended_as_apm = 0;
wopts->part_like_isohybrid = 0;
wopts->ascii_disc_label[0] = 0; wopts->ascii_disc_label[0] = 0;
wopts->will_cancel = 0; wopts->will_cancel = 0;
wopts->allow_dir_id_ext = 0; wopts->allow_dir_id_ext = 0;
@ -4119,6 +4121,18 @@ int iso_write_opts_set_appended_as_gpt(IsoWriteOpts *opts, int gpt)
return ISO_SUCCESS; return ISO_SUCCESS;
} }
int iso_write_opts_set_appended_as_apm(IsoWriteOpts *opts, int apm)
{
opts->appended_as_apm = !!apm;
return ISO_SUCCESS;
}
int iso_write_opts_set_part_like_isohybrid(IsoWriteOpts *opts, int alike)
{
opts->part_like_isohybrid = !!alike;
return ISO_SUCCESS;
}
int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label) int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label)
{ {
strncpy(opts->ascii_disc_label, label, ISO_DISC_LABEL_SIZE - 1); strncpy(opts->ascii_disc_label, label, ISO_DISC_LABEL_SIZE - 1);

View File

@ -487,6 +487,15 @@ struct iso_write_opts {
*/ */
int appended_as_gpt; int appended_as_gpt;
/* If 1: With appended partitions: mark by APM partition
*/
int appended_as_apm;
/* If 1: Obey struct el_torito_boot_image.isolinux_options bit2-7 and bit8.
I.e. mention boot image as partition in GPT and/or APM.
*/
int part_like_isohybrid;
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label. /* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
*/ */
char ascii_disc_label[ISO_DISC_LABEL_SIZE]; char ascii_disc_label[ISO_DISC_LABEL_SIZE];

View File

@ -4,7 +4,7 @@
/* /*
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic * Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
* Copyright (c) 2009-2015 Thomas Schmitt * Copyright (c) 2009-2016 Thomas Schmitt
* *
* This file is part of the libisofs project; you can redistribute it and/or * 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 * modify it under the terms of the GNU General Public License version 2
@ -2649,6 +2649,54 @@ int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
*/ */
int iso_write_opts_set_appended_as_gpt(IsoWriteOpts *opts, int gpt); int iso_write_opts_set_appended_as_gpt(IsoWriteOpts *opts, int gpt);
/**
* Control whether partitions created by iso_write_opts_set_partition_img()
* are to be represented in Apple Partition Map.
*
* @param opts
* The option set to be manipulated.
* @param apm
* 0= do not represent appended partitions in APM
* 1= represent in APM, even if not
* iso_write_opts_set_part_like_isohybrid() enables it and no
* other APM partitions emerge.
* @return
* ISO_SUCCESS or error
*
* @since 1.4.4
*/
int iso_write_opts_set_appended_as_apm(IsoWriteOpts *opts, int apm);
/**
* Control whether bits 2 to 8 of el_torito_set_isolinux_options()
* shall apply even if not isohybrid MBR patching is enabled (bit1 of
* parameter options of iso_write_opts_set_system_area()):
* - Mentioning of El Torito boot images in GPT.
* - Mentioning of El Torito boot images in APM.
*
* In this case some other behavior from isohybrid processing will apply too:
* - No MBR partition of type 0xee emerges, even if GPT gets produced.
* - Gaps between GPT and APM partitions will not be filled by more partitions.
*
* An extra feature towards isohybrid is enabled:
* - Appended partitions get mentioned in APM if other APM partitions emerge.
*
* @param opts
* The option set to be manipulated.
* @param alike
* 0= Apply the described behavior only with ISOLINUX isohybrid.
* Do not mention appended partitions in APM unless
* iso_write_opts_set_appended_as_apm() is enabled.
* 1= Apply the described behavior even without ISOLINUX isohybrid.
*
* @return
* ISO_SUCCESS or error
*
* @since 1.4.4
*/
int iso_write_opts_set_part_like_isohybrid(IsoWriteOpts *opts, int alike);
/** /**
* Inquire the start address of the file data blocks after having used * Inquire the start address of the file data blocks after having used
* IsoWriteOpts with iso_image_create_burn_source(). * IsoWriteOpts with iso_image_create_burn_source().

View File

@ -308,6 +308,7 @@ iso_write_opts_set_allow_longer_paths;
iso_write_opts_set_allow_lowercase; iso_write_opts_set_allow_lowercase;
iso_write_opts_set_always_gmt; iso_write_opts_set_always_gmt;
iso_write_opts_set_appendable; iso_write_opts_set_appendable;
iso_write_opts_set_appended_as_apm;
iso_write_opts_set_appended_as_gpt; iso_write_opts_set_appended_as_gpt;
iso_write_opts_set_default_dir_mode; iso_write_opts_set_default_dir_mode;
iso_write_opts_set_default_file_mode; iso_write_opts_set_default_file_mode;
@ -337,6 +338,7 @@ iso_write_opts_set_omit_version_numbers;
iso_write_opts_set_output_charset; iso_write_opts_set_output_charset;
iso_write_opts_set_overwrite_buf; iso_write_opts_set_overwrite_buf;
iso_write_opts_set_part_offset; iso_write_opts_set_part_offset;
iso_write_opts_set_part_like_isohybrid;
iso_write_opts_set_partition_img; iso_write_opts_set_partition_img;
iso_write_opts_set_prep_img; iso_write_opts_set_prep_img;
iso_write_opts_set_pvd_times; iso_write_opts_set_pvd_times;

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2008 Vreixo Formoso * Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2010 - 2015 Thomas Schmitt * Copyright (c) 2010 - 2016 Thomas Schmitt
* *
* This file is part of the libisofs project; you can redistribute it and/or * 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 * modify it under the terms of the GNU General Public License version 2
@ -1187,9 +1187,8 @@ static int fill_apm_gaps(Ecma119Image *t, uint32_t img_blocks)
qsort(t->apm_req, t->apm_req_count, qsort(t->apm_req, t->apm_req_count,
sizeof(struct iso_apm_partition_request *), cmp_partition_request); sizeof(struct iso_apm_partition_request *), cmp_partition_request);
#ifdef Libisofs_mjg_boot_for_grub2 if (t->opts->part_like_isohybrid)
return 1; return 1; /* No filling, only sorting */
#endif
/* t->apm_req_count will grow during the loop */ /* t->apm_req_count will grow during the loop */
up_to = t->apm_req_count + 1; up_to = t->apm_req_count + 1;
@ -1665,11 +1664,8 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
goal = 0; goal = 0;
part_end = 0; part_end = 0;
#ifdef Libisofs_mjg_boot_for_grub2 if (t->opts->part_like_isohybrid)
up_to = 0; /* No gap filling */
up_to = 0; /* No gap filling */
#endif /* Libisofs_mjg_boot_for_grub2 */
for (i = 0; i < up_to; i++) { for (i = 0; i < up_to; i++) {
if (i < up_to - 1) { if (i < up_to - 1) {
@ -1896,24 +1892,13 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
if (t->mbr_req_count == 0){ if (t->mbr_req_count == 0){
/* Write GRUB protective msdos label, i.e. a simple partition /* Write GRUB protective msdos label, i.e. a simple partition
table */ table */
if (t->gpt_req_count > 0 && ! t->opts->part_like_isohybrid) {
#ifdef Libisofs_mjg_boot_for_grub2
part_type = 0xcd;
pml_blocks = img_blocks;
#else
if (t->gpt_req_count > 0) {
part_type = 0xee; part_type = 0xee;
pml_blocks = gpt_blocks; pml_blocks = gpt_blocks;
} else { } else {
part_type = 0xcd; part_type = 0xcd;
pml_blocks = img_blocks; pml_blocks = img_blocks;
} }
#endif /* Libisofs_mjg_boot_for_grub2 */
ret = make_grub_msdos_label(pml_blocks, t->partition_secs_per_head, ret = make_grub_msdos_label(pml_blocks, t->partition_secs_per_head,
t->partition_heads_per_cyl, t->partition_heads_per_cyl,
(uint8_t) part_type, buf, 0); (uint8_t) part_type, buf, 0);
@ -2070,23 +2055,12 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
wpt[i] = blk >> (i * 8); wpt[i] = blk >> (i * 8);
} }
#ifdef Libisofs_mjg_boot_for_grub2
/* Prevent MBR partition type 0xee */
if (sa_type == 0 && ((t->system_area_options & 3) || risk_of_ee) &&
(t->have_appended_partitions || t->gpt_req_count == 0)) {
#else
/* Prevent partition type 0xee if no GPT emerged */ /* Prevent partition type 0xee if no GPT emerged */
/* >>> check for GPT magic number at byte 512 ff. */; /* >>> ??? check for GPT magic number at byte 512 ff. ? */;
if (sa_type == 0 && ((t->system_area_options & 3) || risk_of_ee) && if (sa_type == 0 && ((t->system_area_options & 3) || risk_of_ee) &&
t->gpt_req_count == 0) { (t->opts->part_like_isohybrid || t->gpt_req_count == 0)) {
#endif /* ! Libisofs_mjg_boot_for_grub2 */
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] == 0xee) { if (buf[446 + 16 * i + 4] == 0xee) {
iso_msgs_submit(0, iso_msgs_submit(0,
@ -2453,14 +2427,6 @@ fallback:;
int assess_appended_gpt(Ecma119Image *t, int flag) int assess_appended_gpt(Ecma119Image *t, int flag)
{ {
#ifdef Libisofs_mjg_boot_for_grub2
int i, ret;
uint8_t gpt_name[72];
#else
static uint8_t basic_data_uuid[16] = { static uint8_t basic_data_uuid[16] = {
0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44, 0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44,
0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7
@ -2470,57 +2436,54 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b
}; };
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 zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int i, ret; int i, ret, do_apm = 0, do_gpt = 0;
uint8_t gpt_name[72], *type_uuid; uint8_t gpt_name[72], *type_uuid;
#endif /* ! Libisofs_mjg_boot_for_grub2 */
#ifndef Libisofs_appended_partitions_inlinE #ifndef Libisofs_appended_partitions_inlinE
if (!t->gpt_backup_outside) if (!t->gpt_backup_outside)
return 2; return 2;
#endif #endif
/* Represent in GPT only if other GPT partitions are already registered if ((t->apm_req_count > 0 && t->opts->part_like_isohybrid) ||
or if appended partitions are explicitely desired for GPT-only. (t->have_appended_partitions && t->opts->appended_as_apm))
*/ do_apm = 1;
if (t->gpt_req_count == 0 && if (t->gpt_req_count > 0 ||
!(t->have_appended_partitions && t->opts->appended_as_gpt)) (t->have_appended_partitions && t->opts->appended_as_gpt))
return 2; do_gpt = 1;
if (do_apm == 0 && do_gpt == 0)
return 2;
/* Represent appended partitions */ /* Represent appended partitions */
for (i = 0; i <= 3; i++) { for (i = 0; i <= 3; i++) {
if (t->opts->appended_partitions[i] == NULL) if (t->opts->appended_partitions[i] == NULL)
continue; continue;
if (do_apm) {
#ifdef Libisofs_mjg_boot_for_grub2 memset(gpt_name, 0, 32);
sprintf((char *) gpt_name, "Appended%d", i + 1);
sprintf((char *) gpt_name, "Appended%d", i + 1); ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
t->appended_part_start[i] * t->hfsp_iso_block_fac, t->appended_part_start[i] * t->hfsp_iso_block_fac,
t->appended_part_size[i] * t->hfsp_iso_block_fac, t->appended_part_size[i] * t->hfsp_iso_block_fac,
(char *) gpt_name, "Data"); (char *) gpt_name, "Data");
if (ret < 0) if (ret < 0)
return ret; return ret;
}
#else /* Libisofs_mjg_boot_for_grub2 */ if (do_gpt) {
memset(gpt_name, 0, 72);
memset(gpt_name, 0, 72); sprintf((char *) gpt_name, "Appended%d", i + 1);
sprintf((char *) gpt_name, "Appended%d", i + 1); iso_ascii_utf_16le(gpt_name);
iso_ascii_utf_16le(gpt_name); if (t->opts->appended_part_types[i] == 0xef)
if (t->opts->appended_part_types[i] == 0xef) type_uuid = efi_sys_uuid;
type_uuid = efi_sys_uuid; else
else type_uuid = basic_data_uuid;
type_uuid = basic_data_uuid; ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
((uint64_t) t->appended_part_start[i]) * 4, ((uint64_t) t->appended_part_start[i]) * 4,
((uint64_t) t->appended_part_size[i]) * 4, ((uint64_t) t->appended_part_size[i]) * 4,
type_uuid, zero_uuid, type_uuid, zero_uuid,
(uint64_t) 0, gpt_name); (uint64_t) 0, gpt_name);
if (ret < 0) if (ret < 0)
return ret; return ret;
}
#endif /* ! Libisofs_mjg_boot_for_grub2 */
} }
return ISO_SUCCESS; return ISO_SUCCESS;
} }
@ -2534,10 +2497,6 @@ static int precompute_gpt(Ecma119Image *t)
int ret, sa_type; int ret, sa_type;
int gpt_count, gpt_idx[128], apm_count; int gpt_count, gpt_idx[128], apm_count;
#ifdef Libisofs_mjg_boot_for_grub2X
int mjg_gpt_count = 0, mjg_apm_count = 0;
#endif
/* Avoid repetition by gpt_tail_writer_compute_data_blocks */ /* Avoid repetition by gpt_tail_writer_compute_data_blocks */
t->gpt_is_computed = 1; t->gpt_is_computed = 1;
@ -2563,14 +2522,12 @@ static int precompute_gpt(Ecma119Image *t)
return ret; return ret;
} }
#ifdef Libisofs_mjg_boot_for_grub2 /* With part_like_isohybrid:
/* Experimental:
If no GPT is registered yet, and MBR, but neither CHRP nor ISOLINUX If no GPT is registered yet, and MBR, but neither CHRP nor ISOLINUX
isohybrid is desired, then try to apply the isohybrid GPT and APM flags isohybrid is desired, then try to apply the isohybrid GPT and APM flags
nevertheless. Avoid an overall ISO image GPT partition. nevertheless. Avoid an overall ISO image GPT partition.
*/ */
if (t->gpt_req_count <= 0 && if (t->opts->part_like_isohybrid && t->gpt_req_count <= 0 &&
((t->system_area_options >> 2) & 0x3f) == 0 && ((t->system_area_options >> 2) & 0x3f) == 0 &&
((t->system_area_options >> 10) & 0xf) != 1 && ((t->system_area_options >> 10) & 0xf) != 1 &&
(!(t->system_area_options & 2))) { (!(t->system_area_options & 2))) {
@ -2582,8 +2539,6 @@ static int precompute_gpt(Ecma119Image *t)
t->apm_req_flags |= 2; /* Do not fill APM gaps, t->apm_req_flags |= 2; /* Do not fill APM gaps,
do not adjust final APM partition size */ do not adjust final APM partition size */
} }
#endif /* Libisofs_mjg_boot_for_grub2 */
/* Rectify APM requests early in order to learn the size of GPT. /* Rectify APM requests early in order to learn the size of GPT.
iso_write_apm() relies on this being already done here. iso_write_apm() relies on this being already done here.