Provisory new pseudo path for El Torito boot images:

--interval:appened_partition_N:all::
This commit is contained in:
Thomas Schmitt 2015-12-30 18:56:32 +01:00
parent 93f3cb1823
commit ec35bb21c0
7 changed files with 220 additions and 60 deletions

View File

@ -104,6 +104,8 @@ void ecma119_image_free(Ecma119Image *t)
free(t->output_charset); free(t->output_charset);
if (t->bootsrc != NULL) if (t->bootsrc != NULL)
free(t->bootsrc); free(t->bootsrc);
if (t->boot_appended_idx != NULL)
free(t->boot_appended_idx);
if (t->system_area_data != NULL) if (t->system_area_data != NULL)
free(t->system_area_data); free(t->system_area_data);
if (t->checksum_ctx != NULL) { /* dispose checksum context */ if (t->checksum_ctx != NULL) { /* dispose checksum context */
@ -567,8 +569,13 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
vol.vol_desc_version[0] = 1; vol.vol_desc_version[0] = 1;
strncpy_pad((char*)vol.system_id, system_id, 32); strncpy_pad((char*)vol.system_id, system_id, 32);
strncpy_pad((char*)vol.volume_id, vol_id, 32); strncpy_pad((char*)vol.volume_id, vol_id, 32);
iso_bb(vol.vol_space_size, t->vol_space_size - t->eff_partition_offset, if (t->pvd_size_is_total_size) {
4); iso_bb(vol.vol_space_size,
t->total_size / 2048 - t->eff_partition_offset, 4);
} else {
iso_bb(vol.vol_space_size,
t->vol_space_size - t->eff_partition_offset, 4);
}
iso_bb(vol.vol_set_size, (uint32_t) 1, 2); iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2); iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2); iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
@ -2376,12 +2383,16 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
target->num_bootsrc = target->catalog->num_bootimages; target->num_bootsrc = target->catalog->num_bootimages;
target->bootsrc = calloc(target->num_bootsrc + 1, target->bootsrc = calloc(target->num_bootsrc + 1,
sizeof(IsoFileSrc *)); sizeof(IsoFileSrc *));
if (target->bootsrc == NULL) { target->boot_appended_idx = calloc(target->num_bootsrc + 1,
sizeof(int));
if (target->bootsrc == NULL || target->boot_appended_idx == NULL) {
ret = ISO_OUT_OF_MEM; ret = ISO_OUT_OF_MEM;
goto target_cleanup; goto target_cleanup;
} }
for (i= 0; i < target->num_bootsrc; i++) for (i= 0; i < target->num_bootsrc; i++) {
target->bootsrc[i] = NULL; target->bootsrc[i] = NULL;
target->boot_appended_idx[i] = -1;
}
} else { } else {
target->num_bootsrc = 0; target->num_bootsrc = 0;
target->bootsrc = NULL; target->bootsrc = NULL;
@ -2448,6 +2459,10 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
goto target_cleanup; goto target_cleanup;
} }
target->total_size = 0;
target->vol_space_size = 0;
target->pvd_size_is_total_size = 0;
target->checksum_idx_counter = 0; target->checksum_idx_counter = 0;
target->checksum_ctx = NULL; target->checksum_ctx = NULL;
target->checksum_counter = 0; target->checksum_counter = 0;

View File

@ -554,10 +554,19 @@ struct ecma119_image
time_t now; /**< Time at which writing began. */ time_t now; /**< Time at which writing began. */
/** Total size of the output. This only includes the current volume. */ /* Total size of the output. Counted in bytes.
* Includes ISO filesystem and appended data.
*/
off_t total_size; off_t total_size;
/** Size actually governed by the ISO filesystem part of the output */
uint32_t vol_space_size; uint32_t vol_space_size;
/* 1= write the total size into the PVD of the ISO,
* 0= write vol_space_size
*/
int pvd_size_is_total_size;
/* Bytes already written to image output */ /* Bytes already written to image output */
off_t bytes_written; off_t bytes_written;
/* just for progress notification */ /* just for progress notification */
@ -640,6 +649,8 @@ struct ecma119_image
int num_bootsrc; int num_bootsrc;
IsoFileSrc **bootsrc; /* location of the boot images in the new image */ IsoFileSrc **bootsrc; /* location of the boot images in the new image */
int *boot_appended_idx; /* Appended partition which serve as boot images */
/* /*
* System Area related information * System Area related information
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2007 Vreixo Formoso * Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 - 2014 Thomas Schmitt * Copyright (c) 2010 - 2015 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
@ -19,6 +19,7 @@
#include "image.h" #include "image.h"
#include "messages.h" #include "messages.h"
#include "writer.h" #include "writer.h"
#include "ecma119.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -323,36 +324,61 @@ int create_image(IsoImage *image, const char *image_path,
struct el_torito_boot_image *boot; struct el_torito_boot_image *boot;
int boot_media_type = 0; int boot_media_type = 0;
int load_sectors = 0; /* number of sector to load */ int load_sectors = 0; /* number of sector to load */
int part_idx = -1;
unsigned char partition_type = 0; unsigned char partition_type = 0;
off_t size; off_t size;
IsoNode *imgfile; IsoNode *imgfile = NULL;
IsoStream *stream; IsoStream *stream = NULL;
*bootnode = NULL; *bootnode = NULL;
ret = iso_tree_path_to_node(image, image_path, &imgfile);
if (ret < 0) { if (strncmp(image_path, "--interval:appended_partition_", 30) == 0) {
return ret; /* --interval:appended_partition_N... */
} if (type != ELTORITO_NO_EMUL) {
if (ret == 0) {
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0, /* >>> ??? lift this ban by making a temporary IsoStream from
partition source, determine size,
and read ELTORITO_HARD_DISC_EMUL MBR ?
*/
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Appended partition cannot serve as El Torito boot image with FD/HD emulation");
return ISO_BOOT_IMAGE_NOT_VALID;
}
sscanf(image_path + 30, "%d", &part_idx);
if (part_idx < 1 || part_idx > ISO_MAX_PARTITIONS) {
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Appended partition index for El Torito boot image is out of range");
return ISO_BOOT_IMAGE_NOT_VALID;
}
part_idx--;
size = 1;
} else {
ret = iso_tree_path_to_node(image, image_path, &imgfile);
if (ret < 0) {
return ret;
}
if (ret == 0) {
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0,
"El Torito boot image file missing in ISO image: '%s'", "El Torito boot image file missing in ISO image: '%s'",
image_path); image_path);
return ISO_NODE_DOESNT_EXIST; return ISO_NODE_DOESNT_EXIST;
}
if (imgfile->type != LIBISO_FILE) {
return ISO_BOOT_IMAGE_NOT_VALID;
}
*bootnode = (IsoFile *) imgfile;
stream = ((IsoFile*)imgfile)->stream;
/* we need to read the image at least two times */
if (!iso_stream_is_repeatable(stream)) {
return ISO_BOOT_IMAGE_NOT_VALID;
}
size = iso_stream_get_size(stream);
} }
if (imgfile->type != LIBISO_FILE) {
return ISO_BOOT_IMAGE_NOT_VALID;
}
*bootnode = (IsoFile *) imgfile;
stream = ((IsoFile*)imgfile)->stream;
/* we need to read the image at least two times */
if (!iso_stream_is_repeatable(stream)) {
return ISO_BOOT_IMAGE_NOT_VALID;
}
size = iso_stream_get_size(stream);
if (size <= 0) { if (size <= 0) {
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0, iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Boot image file is empty"); "Boot image file is empty");
@ -441,7 +467,9 @@ int create_image(IsoImage *image, const char *image_path,
return ISO_OUT_OF_MEM; return ISO_OUT_OF_MEM;
} }
boot->image = (IsoFile*)imgfile; boot->image = (IsoFile*)imgfile;
iso_node_ref(imgfile); /* get our ref */ boot->appended_idx = part_idx;
if (imgfile != NULL)
iso_node_ref(imgfile); /* get our ref */
boot->bootable = 1; boot->bootable = 1;
boot->seems_boot_info_table = 0; boot->seems_boot_info_table = 0;
boot->seems_grub2_boot_info = 0; boot->seems_grub2_boot_info = 0;
@ -538,8 +566,9 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
catalog->bootimages[i] = NULL; catalog->bootimages[i] = NULL;
catalog->node = cat_node; catalog->node = cat_node;
catalog->sort_weight = 1000000000; /* very high */ catalog->sort_weight = 1000000000; /* very high */
if (!(boot_node->explicit_weight || boot_node->from_old_session)) if (boot_node != NULL)
boot_node->sort_weight = 2; if (!(boot_node->explicit_weight || boot_node->from_old_session))
boot_node->sort_weight = 2;
iso_node_ref((IsoNode*)cat_node); iso_node_ref((IsoNode*)cat_node);
image->bootcat = catalog; image->bootcat = catalog;
@ -555,7 +584,8 @@ boot_image_cleanup:;
iso_node_unref((IsoNode*)cat_node); iso_node_unref((IsoNode*)cat_node);
} }
if (boot_image) { if (boot_image) {
iso_node_unref((IsoNode*)boot_image->image); if (boot_image->image != NULL)
iso_node_unref((IsoNode*)boot_image->image);
free(boot_image); free(boot_image);
} }
return ret; return ret;
@ -719,8 +749,9 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
ret = create_image(image, image_path, type, &boot_img, &boot_node); ret = create_image(image, image_path, type, &boot_img, &boot_node);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (!(boot_node->explicit_weight || boot_node->from_old_session)) if (boot_node != NULL)
boot_node->sort_weight = 2; if (!(boot_node->explicit_weight || boot_node->from_old_session))
boot_node->sort_weight = 2;
catalog->bootimages[catalog->num_bootimages] = boot_img; catalog->bootimages[catalog->num_bootimages] = boot_img;
catalog->num_bootimages++; catalog->num_bootimages++;
if (boot != NULL) if (boot != NULL)
@ -827,12 +858,13 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
* Usable for the Default Entry * Usable for the Default Entry
* and for Section Entries with Selection criteria type == 0 * and for Section Entries with Selection criteria type == 0
*/ */
static void static
write_section_entry(uint8_t *buf, Ecma119Image *t, int idx) int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
{ {
struct el_torito_boot_image *img; struct el_torito_boot_image *img;
struct el_torito_section_entry *se = struct el_torito_section_entry *se =
(struct el_torito_section_entry*)buf; (struct el_torito_section_entry*)buf;
int app_idx;
img = t->catalog->bootimages[idx]; img = t->catalog->bootimages[idx];
@ -840,16 +872,37 @@ write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
se->boot_media_type[0] = img->type; se->boot_media_type[0] = img->type;
iso_lsb(se->load_seg, img->load_seg, 2); iso_lsb(se->load_seg, img->load_seg, 2);
se->system_type[0] = img->partition_type; se->system_type[0] = img->partition_type;
iso_lsb(se->sec_count, img->load_size, 2);
iso_lsb(se->block, t->bootsrc[idx]->sections[0].block, 4); if (t->boot_appended_idx[idx] >= 0) {
app_idx = t->boot_appended_idx[idx];
if (t->appended_part_size[app_idx] * 4 > 65535) {
if (img->platform_id == 0xef)
iso_lsb(se->sec_count, 0, 2);
else
iso_lsb(se->sec_count, 65535, 2);
} else {
if (t->appended_part_size[app_idx] == 0) {
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Appended partition which shall serve as boot image does not exist");
return ISO_BOOT_IMAGE_NOT_VALID;
}
iso_lsb(se->sec_count, t->appended_part_size[app_idx] * 4, 2);
}
iso_lsb(se->block, t->appended_part_start[app_idx], 4);
} else {
iso_lsb(se->sec_count, img->load_size, 2);
iso_lsb(se->block, t->bootsrc[idx]->sections[0].block, 4);
}
se->selec_criteria[0] = img->selection_crit[0]; se->selec_criteria[0] = img->selection_crit[0];
memcpy(se->vendor_sc, img->selection_crit + 1, 19); memcpy(se->vendor_sc, img->selection_crit + 1, 19);
return ISO_SUCCESS;
} }
static static
int catalog_open(IsoStream *stream) int catalog_open(IsoStream *stream)
{ {
int i, j, k, num_entries; int i, j, k, num_entries, ret;
struct catalog_stream *data; struct catalog_stream *data;
uint8_t *wpt; uint8_t *wpt;
struct el_torito_boot_catalog *cat; struct el_torito_boot_catalog *cat;
@ -873,7 +926,9 @@ int catalog_open(IsoStream *stream)
boots[0]->platform_id, boots[0]->id_string); boots[0]->platform_id, boots[0]->id_string);
/* write default entry = first boot image */ /* write default entry = first boot image */
write_section_entry(data->buffer + 32, data->target, 0); ret = write_section_entry(data->buffer + 32, data->target, 0);
if (ret < 0)
return ret;
/* IMPORTANT: The maximum number of boot images must fit into BLOCK_SIZE */ /* IMPORTANT: The maximum number of boot images must fit into BLOCK_SIZE */
wpt = data->buffer + 64; wpt = data->buffer + 64;
@ -894,7 +949,9 @@ int catalog_open(IsoStream *stream)
write_section_header(wpt, data->target, i, num_entries); write_section_header(wpt, data->target, i, num_entries);
wpt += 32; wpt += 32;
for (j = 0; j < num_entries; j++) { for (j = 0; j < num_entries; j++) {
write_section_entry(wpt, data->target, i); ret = write_section_entry(wpt, data->target, i);
if (ret < 0)
return ret;
wpt += 32; wpt += 32;
i++; i++;
} }
@ -1132,6 +1189,9 @@ int patch_boot_info_table(uint8_t *buf, Ecma119Image *t,
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0, return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Isolinux image too small. We won't patch it."); "Isolinux image too small. We won't patch it.");
} }
if (t->bootsrc[idx] == NULL)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Cannot apply ISOLINUX patching outside of ISO 9660 filesystem.");
ret = make_boot_info_table(buf, t->opts->ms_block + (uint32_t) 16, ret = make_boot_info_table(buf, t->opts->ms_block + (uint32_t) 16,
t->bootsrc[idx]->sections[0].block, t->bootsrc[idx]->sections[0].block,
(uint32_t) imgsize); (uint32_t) imgsize);
@ -1151,7 +1211,10 @@ int patch_grub2_boot_image(uint8_t *buf, Ecma119Image *t,
if (imgsize < pos + 8) if (imgsize < pos + 8)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0, return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Isolinux image too small for GRUB2. Will not patch it."); "Boot image too small for GRUB2. Will not patch it.");
if (t->bootsrc[idx] == NULL)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Cannot apply GRUB2 patching outside of ISO 9660 filesystem.");
blk = ((uint64_t) t->bootsrc[idx]->sections[0].block) * 4 + offst; blk = ((uint64_t) t->bootsrc[idx]->sections[0].block) * 4 + offst;
iso_lsb((buf + pos), blk & 0xffffffff, 4); iso_lsb((buf + pos), blk & 0xffffffff, 4);
iso_lsb((buf + pos + 4), blk >> 32, 4); iso_lsb((buf + pos + 4), blk >> 32, 4);
@ -1174,6 +1237,10 @@ int iso_patch_eltoritos(Ecma119Image *t)
for (idx = 0; idx < t->catalog->num_bootimages; idx++) { for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x201)) if (!(t->catalog->bootimages[idx]->isolinux_options & 0x201))
continue; continue;
if (t->bootsrc[idx] == NULL)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Cannot apply boot image patching outside of ISO 9660 filesystem");
original = t->bootsrc[idx]->stream; original = t->bootsrc[idx]->stream;
size = (size_t) iso_stream_get_size(original); size = (size_t) iso_stream_get_size(original);
if (size > Libisofs_elto_max_patchablE) if (size > Libisofs_elto_max_patchablE)
@ -1281,8 +1348,8 @@ int eltorito_writer_create(Ecma119Image *target)
{ {
int ret, idx, outsource_efi = 0; int ret, idx, outsource_efi = 0;
IsoImageWriter *writer; IsoImageWriter *writer;
IsoFile *bootimg; IsoFile *bootimg = NULL;
IsoFileSrc *src; IsoFileSrc *src = NULL;
writer = calloc(1, sizeof(IsoImageWriter)); writer = calloc(1, sizeof(IsoImageWriter));
if (writer == NULL) { if (writer == NULL) {
@ -1315,6 +1382,19 @@ int eltorito_writer_create(Ecma119Image *target)
if (strcmp(target->opts->efi_boot_partition, "--efi-boot-image") == 0) if (strcmp(target->opts->efi_boot_partition, "--efi-boot-image") == 0)
outsource_efi = 1; outsource_efi = 1;
for (idx = 0; idx < target->catalog->num_bootimages; idx++) { for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
target->bootsrc[idx] = NULL;
if (target->catalog->bootimages[idx]->appended_idx >= 0) {
/* Use an appended partition as boot image rather than IsoFile */
target->boot_appended_idx[idx] =
target->catalog->bootimages[idx]->appended_idx;
if (((target->system_area_options >> 2) & 0x3f) == 0 &&
(target->system_area_options & 3) == 1) {
/* ISO will not be a partition. It can span the whole image. */
target->pvd_size_is_total_size = 1;
}
continue;
}
bootimg = target->catalog->bootimages[idx]->image; bootimg = target->catalog->bootimages[idx]->image;
ret = iso_file_src_create(target, bootimg, &src); ret = iso_file_src_create(target, bootimg, &src);
if (ret < 0) { if (ret < 0) {

View File

@ -53,6 +53,9 @@ struct el_torito_boot_catalog {
struct el_torito_boot_image { struct el_torito_boot_image {
IsoFile *image; IsoFile *image;
/* Overrides .image if >= 0 : array index of appended partition */
int appended_idx;
unsigned int bootable:1; /**< If the entry is bootable. */ unsigned int bootable:1; /**< If the entry is bootable. */
/** /**
* Whether the boot image seems to contain a boot_info_table * Whether the boot image seems to contain a boot_info_table

View File

@ -3402,6 +3402,9 @@ int iso_image_get_pvd_times(IsoImage *image,
* returns an error and the image remains unmodified. * returns an error and the image remains unmodified.
* @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...
* @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:
* - Floppy emulation: Boot image file must be exactly * - Floppy emulation: Boot image file must be exactly
@ -3443,7 +3446,10 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
* The image to which the boot image shall be added. * The image to which the boot image shall be added.
* returns an error and the image remains unmodified. * returns an error and the image remains unmodified.
* @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 boot image.
>>> or --interval:appended_partition_$number...
* @param type * @param type
* The boot media type. See iso_image_set_boot_image * The boot media type. See iso_image_set_boot_image
* @param flag * @param flag
@ -3488,6 +3494,9 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
* @param imgnode * @param imgnode
* When not NULL, it will be filled with the image tree node. No extra ref * When not NULL, it will be filled with the image tree node. No extra ref
* is added, you can use iso_node_ref() to get one if you need it. * is added, you can use iso_node_ref() to get one if you need it.
>>> The returned value is NULL if the boot image source is no IsoFile.
* @param catnode * @param catnode
* When not NULL, it will be filled with the catnode tree node. No extra * When not NULL, it will be filled with the catnode tree node. No extra
* ref is added, you can use iso_node_ref() to get one if you need it. * ref is added, you can use iso_node_ref() to get one if you need it.
@ -3545,6 +3554,11 @@ int iso_image_get_bootcat(IsoImage *image, IsoBoot **catnode, uint32_t *lba,
* @param bootnodes * @param bootnodes
* Returns NULL or an allocated array of pointers to the IsoFile nodes * Returns NULL or an allocated array of pointers to the IsoFile nodes
* which bear the content of the boot images in boots. * which bear the content of the boot images in boots.
>>> An array entry is NULL if the boot image source is no IsoFile.
>>> Need getter for partition index
* @param flag * @param flag
* Bitfield for control purposes. Unused yet. Submit 0. * Bitfield for control purposes. Unused yet. Submit 0.
* @return * @return

View File

@ -37,6 +37,8 @@
#include "ecma119.h" #include "ecma119.h"
#include "eltorito.h" #include "eltorito.h"
#include "system_area.h" #include "system_area.h"
#include "image.h"
#include "messages.h"
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script /* This code stems from syslinux-3.72/utils/isohybrid, a perl script
@ -60,7 +62,7 @@ license from above stem licenses, typically from LGPL.
In case its generosity is needed, here is the 2-clause BSD license: In case its generosity is needed, here is the 2-clause BSD license:
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
and 2008-2014 Thomas Schmitt and 2008-2015 Thomas Schmitt
1. Redistributions of source code must retain the above copyright notice, 1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. this list of conditions and the following disclaimer.
@ -408,6 +410,7 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
{ {
int i, ilx_opts, j, ret, num_img; int i, ilx_opts, j, ret, num_img;
uint32_t block_count; uint32_t block_count;
uint64_t start_block;
uint8_t gpt_name[72]; 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 zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
static uint8_t basic_data_uuid[16] = { static uint8_t basic_data_uuid[16] = {
@ -430,11 +433,13 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
num_img = 0; num_img = 0;
for (i = 0; i < num_img; i++) { for (i = 0; i < num_img; i++) {
ilx_opts = t->catalog->bootimages[i]->isolinux_options; ilx_opts = t->catalog->bootimages[i]->isolinux_options;
if (((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) { if ((((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) &&
!(t->boot_appended_idx[i] >= 0 && t->opts->appended_as_gpt)) {
if (*gpt_count < 128) if (*gpt_count < 128)
gpt_idx[*gpt_count]= i; gpt_idx[*gpt_count]= i;
(*gpt_count)++; (*gpt_count)++;
if ((flag & 1) && t->bootsrc[i] != NULL) { if ((flag & 1) &&
(t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) {
/* Register GPT entry */ /* Register GPT entry */
memset(gpt_name, 0, 72); memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "ISOHybrid%d", *gpt_count); sprintf((char *) gpt_name, "ISOHybrid%d", *gpt_count);
@ -443,13 +448,21 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
uuid = hfs_uuid; uuid = hfs_uuid;
else else
uuid = basic_data_uuid; uuid = basic_data_uuid;
block_count = 0; if (t->boot_appended_idx[i] >= 0) {
for (j = 0; j < t->bootsrc[i]->nsections; j++) block_count = t->appended_part_size[
block_count += t->bootsrc[i]->sections[j].size / 2048; t->boot_appended_idx[i]];
start_block = ((uint64_t) t->appended_part_start[
t->boot_appended_idx[i]]) * 4;
} else {
block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
start_block = ((uint64_t) t->bootsrc[i]->sections[0].block)
* 4;
}
ret = iso_quick_gpt_entry( ret = iso_quick_gpt_entry(
t->gpt_req, &(t->gpt_req_count), t->gpt_req, &(t->gpt_req_count),
((uint64_t) t->bootsrc[i]->sections[0].block) * 4, start_block, ((uint64_t) block_count) * 4,
((uint64_t) block_count) * 4,
uuid, zero_uuid, gpt_flags, (uint8_t *) gpt_name); uuid, zero_uuid, gpt_flags, (uint8_t *) gpt_name);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -457,13 +470,22 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
} }
if ((ilx_opts & 256) && !(flag & 2)) { if ((ilx_opts & 256) && !(flag & 2)) {
(*apm_count)++; (*apm_count)++;
if ((flag & 1) && t->bootsrc[i] != NULL) { if ((flag & 1) &&
(t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) {
/* Register APM entry */ /* Register APM entry */
block_count = 0; if (t->boot_appended_idx[i] >= 0) {
for (j = 0; j < t->bootsrc[i]->nsections; j++) block_count = t->appended_part_size[
block_count += t->bootsrc[i]->sections[j].size / 2048; t->boot_appended_idx[i]];
start_block = t->appended_part_start[
t->boot_appended_idx[i]];
} else {
block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
start_block = t->bootsrc[i]->sections[0].block;
}
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->bootsrc[i]->sections[0].block, (uint32_t) start_block,
block_count, "EFI", "Apple_HFS"); block_count, "EFI", "Apple_HFS");
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -546,13 +568,18 @@ static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
0xfe, 0xff, 0xff, 0xfe, 0xff, 0xff,
}; };
if (t->bootsrc[gpt_idx[*gpt_cursor]] == NULL) {
(*gpt_cursor)++;
return 2;
}
wpt[0] = 0; wpt[0] = 0;
memcpy(wpt + 1, dummy_chs, 3); memcpy(wpt + 1, dummy_chs, 3);
ilx_opts = t->catalog->bootimages[gpt_idx[*gpt_cursor]]->isolinux_options; ilx_opts = t->catalog->bootimages[gpt_idx[*gpt_cursor]]->isolinux_options;
if (((ilx_opts >> 2) & 63) == 2) if (((ilx_opts >> 2) & 63) == 2)
wpt[4] = 0x00; /* HFS gets marked as "Empty" */ wpt[4] = 0x00; /* HFS gets marked as "Empty" */
else else
((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16/" */ ((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16)" */
memcpy(wpt + 5, dummy_chs, 3); memcpy(wpt + 5, dummy_chs, 3);
@ -589,6 +616,10 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
struct timeval tv; struct timeval tv;
struct timezone tz; struct timezone tz;
if (t->bootsrc[0] == NULL)
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Cannot refer by isohybrid MBR to data outside of ISO 9660 filesystem.");
if (flag & 2) { if (flag & 2) {
part_number = 1; part_number = 1;
part_offset = 1; part_offset = 1;

View File

@ -1820,6 +1820,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
/* Check for isolinux image with magic number of 3.72 and produce /* Check for isolinux image with magic number of 3.72 and produce
an MBR from our built-in template. (Deprecated since 31 Mar 2010) an MBR from our built-in template. (Deprecated since 31 Mar 2010)
*/ */
if (t->bootsrc[0] == NULL)
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Cannot refer by isohybrid MBR to data outside of ISO 9660 filesystem.");
if (img_blocks < 0x80000000) { if (img_blocks < 0x80000000) {
int_img_blocks= img_blocks; int_img_blocks= img_blocks;
} else { } else {
@ -2062,6 +2065,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
if (sa_type == 0 && (t->system_area_options & 0x4000) && !do_isohybrid) { if (sa_type == 0 && (t->system_area_options & 0x4000) && !do_isohybrid) {
/* Patch MBR for GRUB2 */ /* Patch MBR for GRUB2 */
if (t->bootsrc[0] == NULL)
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Cannot refer by GRUB2 MBR to data outside of ISO 9660 filesystem.");
blk = t->bootsrc[0]->sections[0].block * 4 + blk = t->bootsrc[0]->sections[0].block * 4 +
Libisofs_grub2_mbr_patch_offsT; Libisofs_grub2_mbr_patch_offsT;
wpt = buf + Libisofs_grub2_mbr_patch_poS; wpt = buf + Libisofs_grub2_mbr_patch_poS;