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;
}
if (!(flag & 4))
opts->system_area_options = options & 0x7fff;
opts->system_area_options = options & 0xffff;
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 is_protective_label = 0;
uint64_t part2_start;
char *sad;
struct iso_imported_sys_area *sai;
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) {
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 &&
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 */
is_protective_label = 1;
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
* bit10-13= System area sub type
* @since 1.2.4
* With type 0 = MBR:
* Gets overridden by bit0 and bit1.
* With type 0:
* bit0 ... MBR with partition start at block 1
* bit1 ... ISOLINUX isohybrid MBR
* 0 = no particular sub type, use unaltered
* 1 = CHRP: A single MBR partition of type 0x96 covers the
* 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
* (512-block address + 4) of the first boot image file.
* 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.
* 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
* bit0 = invalidate any attached system area data. Same as data == NULL
* (This re-activates eventually loaded image System Area data.
@ -3403,7 +3408,7 @@ int iso_image_get_pvd_times(IsoImage *image,
* @param image_path
* 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
* 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)
{
/* Add a dummy partition of type 0 with boot flag */
if (mode == 0) {
/* Start LBA 0, block count 1 */
buf[446 + 16 + 0] = 0x80; /* bootable */
buf[446 + 16 + 1] = 0x00; /* start head */
buf[446 + 16 + 2] = 0x01; /* start sector */
buf[446 + 16 + 3] = 0x00; /* start cylinder */
buf[446 + 16 + 4] = 0x00; /* partition type */
buf[446 + 16 + 5] = 0x00; /* end head */
buf[446 + 16 + 6] = 0x01; /* last sector */
buf[446 + 16 + 7] = 0x00; /* end cylinder */
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 */
int i;
/* bootable , start 0/0/1, type 0x00, end 0/0/1,
start LBA 0, block count 1 */
static uint8_t dummy_entry[16] = {
0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 };
for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] == 0x00) {
memcpy(buf + 446 + 16 * i, dummy_entry, 16);
return;
}
}
/* 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)
{
@ -2077,24 +2072,6 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
#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 */
if (sa_type == 0 && ((t->system_area_options & 3) || risk_of_ee) &&
(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) == 1 &&
buf[446 + 4] == 0xee && buf[446] == 0x00) {
for (i = 446 + 16 ; i < 510; i++)
if(buf[i])
if (sa_type == 0 && (
(t->system_area_options & 3) ||
(t->system_area_options & (1 << 14)) ||
(((t->system_area_options >> 2) & 0x3f) == 2 &&
(t->system_area_options & (1 << 15)))
)) {
/* 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;
if (i >= 510) {
/* Add a dummy partition of type 0 with boot flag */
#ifdef Libisofs_pmpbd_on_lba0
iso_dummy_mbr_partition(buf, 0);
#else
iso_dummy_mbr_partition(buf, 1);
#endif /* ! Libisofs_pmpbd_on_lba0 */
if (i >= 4) { /* no bootable/active flag set yet */
for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] != 0x00 &&
buf[446 + 16 * i + 4] != 0xee &&
buf[446 + 16 * i + 4] != 0xef) {
buf[446 + 16 * i] |= 0x80;
break;
}
}
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;
}