New bit15 with options of iso_write_opts_set_system_area() to enforce

MBR bootable/active flag.
This commit is contained in:
Thomas Schmitt 2016-01-01 18:17:40 +01:00
parent ec35bb21c0
commit 872b5c6c67
4 changed files with 62 additions and 68 deletions

View File

@ -3990,7 +3990,7 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
opts->system_area_size = 32768; opts->system_area_size = 32768;
} }
if (!(flag & 4)) if (!(flag & 4))
opts->system_area_options = options & 0x7fff; opts->system_area_options = options & 0xffff;
return ISO_SUCCESS; return ISO_SUCCESS;
} }

View File

@ -3940,6 +3940,7 @@ int iso_analyze_mbr(IsoImage *image, IsoDataSource *src, int flag)
{ {
int sub_type = 2, ret, is_isohybrid = 0, is_grub2_mbr = 0; int sub_type = 2, ret, is_isohybrid = 0, is_grub2_mbr = 0;
int is_protective_label = 0; int is_protective_label = 0;
uint64_t part2_start;
char *sad; char *sad;
struct iso_imported_sys_area *sai; struct iso_imported_sys_area *sai;
struct iso_mbr_partition_request *part; struct iso_mbr_partition_request *part;
@ -3969,8 +3970,12 @@ int iso_analyze_mbr(IsoImage *image, IsoDataSource *src, int flag)
if (sai->mbr_req_count >= 1 && !is_isohybrid) { if (sai->mbr_req_count >= 1 && !is_isohybrid) {
part = sai->mbr_req[0]; part = sai->mbr_req[0];
part2_start = 0;
if (sai->mbr_req_count >= 2)
part2_start = sai->mbr_req[1]->start_block;
if (part->start_block == 1 && if (part->start_block == 1 &&
part->block_count + 1 == ((uint64_t) sai->image_size) * 4) { (part->block_count + 1 == ((uint64_t) sai->image_size) * 4 ||
part->block_count + 1 == part2_start)) {
/* libisofs protective msdos label for GRUB2 */ /* libisofs protective msdos label for GRUB2 */
is_protective_label = 1; is_protective_label = 1;
sub_type = 0; sub_type = 0;

View File

@ -2215,8 +2215,9 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* @since 1.2.6 * @since 1.2.6
* bit10-13= System area sub type * bit10-13= System area sub type
* @since 1.2.4 * @since 1.2.4
* With type 0 = MBR: * With type 0:
* Gets overridden by bit0 and bit1. * bit0 ... MBR with partition start at block 1
* bit1 ... ISOLINUX isohybrid MBR
* 0 = no particular sub type, use unaltered * 0 = no particular sub type, use unaltered
* 1 = CHRP: A single MBR partition of type 0x96 covers the * 1 = CHRP: A single MBR partition of type 0x96 covers the
* ISO image. Not compatible with any other feature * ISO image. Not compatible with any other feature
@ -2228,8 +2229,12 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* Patch system area at byte 0x1b0 to 0x1b7 with * Patch system area at byte 0x1b0 to 0x1b7 with
* (512-block address + 4) of the first boot image file. * (512-block address + 4) of the first boot image file.
* Little-endian 8-byte. * Little-endian 8-byte.
* Should be combined with options bit0. * Is normally combined with options bit0.
* Will not be in effect if options bit1 is set. * Will not be in effect if options bit1 is set.
* bit15= Only with System area type MBR but not with CHRP
* Enforce MBR "bootable/active" flag. In worst case by dummy
* partition of type 0x00 which occupies block 0.
* @since 1.4.4
* @param flag * @param flag
* bit0 = invalidate any attached system area data. Same as data == NULL * bit0 = invalidate any attached system area data. Same as data == NULL
* (This re-activates eventually loaded image System Area data. * (This re-activates eventually loaded image System Area data.
@ -3403,7 +3408,7 @@ int iso_image_get_pvd_times(IsoImage *image,
* @param image_path * @param image_path
* The absolute path of a IsoFile to be used as default boot image. * The absolute path of a IsoFile to be used as default boot image.
>>> or --interval:appended_partition_$number... >>> or --interval:appended_partition_$number_start_$start_size_$size:...
* @param type * @param type
* The boot media type. This can be one of 3 types: * The boot media type. This can be one of 3 types:

View File

@ -1749,38 +1749,33 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
} }
#ifdef Libisofs_protective_msdos_plus_boot_dummY /* Add a dummy MBR partition of type 0 with boot flag */
static void iso_dummy_mbr_partition(uint8_t *buf, int mode) static void iso_dummy_mbr_partition(uint8_t *buf, int mode)
{ {
/* Add a dummy partition of type 0 with boot flag */ int i;
if (mode == 0) { /* bootable , start 0/0/1, type 0x00, end 0/0/1,
/* Start LBA 0, block count 1 */ start LBA 0, block count 1 */
buf[446 + 16 + 0] = 0x80; /* bootable */ static uint8_t dummy_entry[16] = {
buf[446 + 16 + 1] = 0x00; /* start head */ 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
buf[446 + 16 + 2] = 0x01; /* start sector */ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 };
buf[446 + 16 + 3] = 0x00; /* start cylinder */
buf[446 + 16 + 4] = 0x00; /* partition type */ for (i = 0; i < 4; i++) {
buf[446 + 16 + 5] = 0x00; /* end head */ if (buf[446 + 16 * i + 4] == 0x00) {
buf[446 + 16 + 6] = 0x01; /* last sector */ memcpy(buf + 446 + 16 * i, dummy_entry, 16);
buf[446 + 16 + 7] = 0x00; /* end cylinder */ return;
buf[446 + 16 + 8] = 0x00; /* start LBA */ }
buf[446 + 16 + 9] = 0x00;
buf[446 + 16 + 10] = 0x00;
buf[446 + 16 + 11] = 0x00;
buf[446 + 16 + 12] = 0x01; /* block count */
buf[446 + 16 + 13] = 0x00;
buf[446 + 16 + 14] = 0x00;
buf[446 + 16 + 15] = 0x00;
} else {
/* copy partition 1 to 2, set boot flag and type 0x00 */
memcpy(buf + 446 + 16, buf + 446, 16);
buf[446 + 16 + 0] = 0x80; /* bootable */
buf[446 + 16 + 4] = 0x00; /* partition type */
} }
/* Abundance of 0xee and 0xef partitions. No other one free. */
for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] != 0xef) {
buf[446 + 16 * i] |= 0x80;
return;
}
}
i = 3;
buf[446 + 16 * i] |= 0x80;
} }
#endif /* Libisofs_protective_msdos_plus_boot_dummY */
int iso_write_system_area(Ecma119Image *t, uint8_t *buf) int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
{ {
@ -2077,24 +2072,6 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
#ifdef Libisofs_mjg_boot_for_grub2 #ifdef Libisofs_mjg_boot_for_grub2
if (buf[446 + 4] != 0x00) {
if (buf[446 + 4] != 0xef && buf[446 + 4] != 0xee)
buf[446] |= 0x80;
#ifdef Libisofs_protective_msdos_plus_boot_dummY
else if (buf[446 + 16 + 4] == 0x00 && (buf[446 + 16] & 0x80) == 0)
#ifdef Libisofs_pmpbd_on_lba0
iso_dummy_mbr_partition(buf, 0);
#else
iso_dummy_mbr_partition(buf, 1);
#endif /* ! Libisofs_pmpbd_on_lba0 */
#endif
}
/* Prevent MBR partition type 0xee */ /* Prevent MBR partition type 0xee */
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->have_appended_partitions || t->gpt_req_count == 0)) { (t->have_appended_partitions || t->gpt_req_count == 0)) {
@ -2120,27 +2097,34 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
} }
} }
#ifdef Libisofs_protective_msdos_plus_boot_dummY if (sa_type == 0 && (
(t->system_area_options & 3) ||
if (sa_type == 0 && (t->system_area_options & 3) == 1 && (t->system_area_options & (1 << 14)) ||
buf[446 + 4] == 0xee && buf[446] == 0x00) { (((t->system_area_options >> 2) & 0x3f) == 2 &&
for (i = 446 + 16 ; i < 510; i++) (t->system_area_options & (1 << 15)))
if(buf[i]) )) {
/* This is an MBR which shall have a bootable/active flag
protective-msdos-label, isohybrid, grub2-mbr, mbr-force-bootable
*/
for (i = 0; i < 4; i++)
if (buf[446 + 16 * i] & 0x80)
break; break;
if (i >= 510) { if (i >= 4) { /* no bootable/active flag set yet */
/* Add a dummy partition of type 0 with boot flag */ for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] != 0x00 &&
#ifdef Libisofs_pmpbd_on_lba0 buf[446 + 16 * i + 4] != 0xee &&
iso_dummy_mbr_partition(buf, 0); buf[446 + 16 * i + 4] != 0xef) {
#else buf[446 + 16 * i] |= 0x80;
iso_dummy_mbr_partition(buf, 1); break;
#endif /* ! Libisofs_pmpbd_on_lba0 */ }
}
if (i >= 4) { /* still no bootable/active flag set */
if (t->system_area_options & (1 << 15)) /* Force it */
iso_dummy_mbr_partition(buf, 0);
}
} }
} }
#endif /* Libisofs_protective_msdos_plus_boot_dummY */
return ISO_SUCCESS; return ISO_SUCCESS;
} }