New API call iso_image_report_el_torito()

This commit is contained in:
Thomas Schmitt 2014-04-24 10:15:56 +02:00
parent dfd74d3d04
commit ad279352e3
5 changed files with 317 additions and 60 deletions

View File

@ -82,15 +82,16 @@ void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment)
{ {
if (bootimg->type != 0) if (bootimg->type != 0)
return; return;
bootimg->load_seg = segment; if (segment < 0)
bootimg->load_seg = 0x1000 + segment;
else
bootimg->load_seg = segment;
} }
/* API */ /* API */
int el_torito_get_load_seg(ElToritoBootImage *bootimg) int el_torito_get_load_seg(ElToritoBootImage *bootimg)
{ {
if (bootimg->load_seg < 0) return (int) bootimg->load_seg;
return 0xffff - bootimg->load_seg;
return bootimg->load_seg;
} }
/** /**
@ -102,15 +103,16 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors)
{ {
if (bootimg->type != 0) if (bootimg->type != 0)
return; return;
bootimg->load_size = sectors; if (sectors < 0)
bootimg->load_size = 0x10000 + sectors;
else
bootimg->load_size = sectors;
} }
/* API */ /* API */
int el_torito_get_load_size(ElToritoBootImage *bootimg) int el_torito_get_load_size(ElToritoBootImage *bootimg)
{ {
if (bootimg->load_size < 0) return (int) bootimg->load_size;
return 0xffff - bootimg->load_size;
return bootimg->load_size;
} }
/** /**

View File

@ -78,8 +78,8 @@ struct el_torito_boot_image {
unsigned int isolinux_options; unsigned int isolinux_options;
unsigned char type; /**< The type of image */ unsigned char type; /**< The type of image */
unsigned char partition_type; /**< type of partition for HD-emul images */ unsigned char partition_type; /**< type of partition for HD-emul images */
short load_seg; /**< Load segment for the initial boot image. */ uint16_t load_seg; /**< Load segment for the initial boot image. */
short load_size; /**< Number of sectors to load. */ uint16_t load_size; /**< Number of sectors to load. */
/* Byte 1 of Validation Entry or Section Header Entry: /* Byte 1 of Validation Entry or Section Header Entry:
0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */ 0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */

View File

@ -4770,7 +4770,7 @@ int iso_impsysa_report(IsoImage *image, struct iso_impsysa_result *target,
sprintf(msg, "ISO image size/512 : %.f", sprintf(msg, "ISO image size/512 : %.f",
((double) sai->image_size) * 4.0); ((double) sai->image_size) * 4.0);
iso_impsysa_line(target, msg); iso_impsysa_line(target, msg);
if (sai->mbr_req_count > 0 && sa_type == 0) { if (sai->mbr_req_count > 0 && sa_type == 0) {
sprintf(msg, "Partition offset : %d", sai->partition_offset); sprintf(msg, "Partition offset : %d", sai->partition_offset);
iso_impsysa_line(target, msg); iso_impsysa_line(target, msg);
@ -5027,58 +5027,189 @@ ex:
return ret; return ret;
} }
static
int iso_report_result_destroy(char ***result, int flag)
{
if (*result == NULL)
return ISO_SUCCESS;
if ((*result)[0] != NULL) /* points to the whole multi-line buffer */
free((*result)[0]);
free(*result);
*result = NULL;
return ISO_SUCCESS;
}
static
int iso_report_help(char **doc, char ***result, int *line_count, int flag)
{
int i, count = 0;
char *buf = NULL;
*line_count = 0;
for (i = 0; strcmp(doc[i], "@END_OF_DOC@") != 0; i++)
count += strlen(doc[i]) + 1;
if (i == 0)
return ISO_SUCCESS;
*result = calloc(i, sizeof(char *));
if (*result == NULL)
return ISO_OUT_OF_MEM;
buf = calloc(1, count);
if (buf == NULL) {
free(result);
*result = NULL;
return ISO_OUT_OF_MEM;
}
*line_count = i;
count = 0;
for (i = 0; strcmp(doc[i], "@END_OF_DOC@") != 0; i++) {
strcpy(buf + count, doc[i]);
(*result)[i] = buf + count;
count += strlen(doc[i]) + 1;
}
return ISO_SUCCESS;
}
static
int iso_eltorito_report(IsoImage *image, struct iso_impsysa_result *target,
int flag)
{
char *msg = NULL, emul_code[6], pltf[5], *path;
int i, j, ret, section_count;
uint32_t lba, *lba_mem = NULL;
struct el_torito_boot_catalog *bootcat;
IsoBoot *bootnode;
struct el_torito_boot_image *img;
struct iso_file_section *sections = NULL;
static char emul_names[5][6] = {"none", "fd1.2", "fd1.4", "fd2.8", "hd"};
static char pltf_names[3][5] = {"BIOS", "PPC", "Mac"};
static int num_emuls = 5, num_pltf = 3;
bootcat = image->bootcat;
LIBISO_ALLOC_MEM(msg, char, ISO_MAX_SYSAREA_LINE_LENGTH);
if (bootcat == NULL)
{ret= 0; goto ex;}
bootnode = image->bootcat->node;
if (bootnode == NULL)
{ret= 0; goto ex;}
sprintf(msg, "El Torito catalog : %u %u",
(unsigned int) bootnode->lba,
(unsigned int) (bootnode->size + 2047) / 2048);
iso_impsysa_line(target, msg);
path = iso_tree_get_node_path((IsoNode *) bootnode);
if (path != NULL) {
sprintf(msg, "El Torito cat path : ");
iso_impsysa_report_text(target, msg, path, 0);
free(path);
}
if (bootcat->num_bootimages > 0) {
sprintf(msg,
"El Torito images : N Pltf B Emul Ld_seg Hdpt Ldsiz THG LBA");
iso_impsysa_line(target, msg);
LIBISO_ALLOC_MEM(lba_mem, uint32_t, bootcat->num_bootimages);
}
for (i= 0; i < bootcat->num_bootimages; i++) {
img = bootcat->bootimages[i];
if (img->type < num_emuls)
strcpy(emul_code, emul_names[img->type]);
else
sprintf(emul_code, "0x%2.2x", (unsigned int) img->type);
if (img->platform_id < num_pltf)
strcpy(pltf, pltf_names[img->platform_id]);
else if(img->platform_id == 0xef)
strcpy(pltf, "UEFI");
else
sprintf(pltf, "0x%2.2x", (unsigned int) img->platform_id);
lba = 0xffffffff;
ret = iso_file_get_old_image_sections(img->image, &section_count,
&sections, 0);
if (ret > 0 && section_count > 0)
lba = sections[0].block;
lba_mem[i]= lba;
if (sections != NULL)
free(sections);
sprintf(msg,
"El Torito boot img : %3d %4s %c %5s 0x%4.4x 0x%2.2x %5u %c%c%c %10u",
i + 1, pltf, img->bootable ? 'y' : 'n', emul_code,
(unsigned int) img->load_seg, (unsigned int) img->partition_type,
(unsigned int) img->load_size,
img->seems_boot_info_table ? 't' : '-',
img->seems_isohybrid_capable ? 'h' : '-',
img->seems_grub2_boot_info ? 'g' : '-',
(unsigned int) lba);
iso_impsysa_line(target, msg);
}
for (i= 0; i < bootcat->num_bootimages; i++) {
img = bootcat->bootimages[i];
for (j = 0; j < (int) sizeof(img->id_string); j++)
if (img->id_string[j])
break;
if (j < (int) sizeof(img->id_string)) {
sprintf(msg, "El Torito id string: %3d ", i + 1);
iso_util_bin_to_hex(msg + strlen(msg),
img->id_string, 24 + 4 * (i > 0), 0);
}
for (j = 0; j < (int) sizeof(img->selection_crit); j++)
if (img->selection_crit[j])
break;
if (j < (int) sizeof(img->selection_crit) && i > 0) {
sprintf(msg, "El Torito sel crit : %3d ", i + 1);
iso_util_bin_to_hex(msg + strlen(msg),
img->selection_crit, 20, 0);
}
}
for (i= 0; i < bootcat->num_bootimages; i++) {
if (lba_mem[i] == 0xffffffff)
continue;
img = bootcat->bootimages[i];
sprintf(msg, "El Torito img path : %3d ", i + 1);
iso_impsysa_report_blockpath(image, target, msg, lba_mem[i], 0);
}
ret = ISO_SUCCESS;
ex:;
LIBISO_FREE_MEM(msg);
LIBISO_FREE_MEM(lba_mem);
return ret;
}
/* API */ /* API */
/* @param flag bit1= do not report system area but rather reply help text /* @param flag bit1= do not report system area but rather reply help text
bit15= dispose result from previous call bit15= dispose result from previous call
*/ */
int iso_image_report_system_area(IsoImage *image, static
char ***result, int *line_count, int flag) int iso_image_report_boot_eqp(IsoImage *image, int what,
char ***result, int *line_count, int flag)
{ {
int ret, i, count = 0; int ret;
char *buf; char **doc;
static char *doc[] = {ISO_SYSAREA_REPORT_DOC}; static char *sysarea_doc[] = {ISO_SYSAREA_REPORT_DOC};
static char *eltorito_doc[] = {ISO_ELTORITO_REPORT_DOC};
struct iso_impsysa_result *target = NULL; struct iso_impsysa_result *target = NULL;
if (flag & (1 << 15)) { if (flag & (1 << 15))
if (*result == NULL) return iso_report_result_destroy(result, 0);
{ret = ISO_SUCCESS; goto ex;}
if ((*result)[0] != NULL) /* target->buf */
free((*result)[0]);
free(*result);
*result = NULL;
{ret = ISO_SUCCESS; goto ex;}
}
if (flag & 1) { if (flag & 1) {
*line_count = 0; if (what == 0)
for (i = 0; strcmp(doc[i], "@END_OF_DOC@") != 0; i++) doc = sysarea_doc;
count += strlen(doc[i]) + 1; else
*result = calloc(i, sizeof(char *)); doc = eltorito_doc;
if (*result == NULL) return iso_report_help(doc, result, line_count, 0);
{ret = ISO_OUT_OF_MEM; goto ex;}
buf = calloc(1, count);
if (buf == NULL) {
free(result);
*result = NULL;
{ret = ISO_OUT_OF_MEM; goto ex;}
}
*line_count = i;
count = 0;
for (i = 0; strcmp(doc[i], "@END_OF_DOC@") != 0; i++) {
strcpy(buf + count, doc[i]);
(*result)[i] = buf + count;
count += strlen(doc[i]) + 1;
}
{ret = ISO_SUCCESS; goto ex;}
} }
*result = NULL;
if (image->system_area_data == NULL)
{ret = 0; goto ex;}
*result = NULL;
*line_count = 0;
ret = iso_impsysa_result_new(&target, 0); ret = iso_impsysa_result_new(&target, 0);
if (ret < 0) if (ret < 0)
goto ex; goto ex;
ret = iso_impsysa_report(image, target, 0); if (what == 0)
if (ret < 0) ret = iso_impsysa_report(image, target, 0);
else
ret = iso_eltorito_report(image, target, 0);
if (ret <= 0)
goto ex; goto ex;
target->buf = calloc(1, target->byte_count + 1); target->buf = calloc(1, target->byte_count + 1);
target->lines = calloc(target->line_count + 1, sizeof(char *)); target->lines = calloc(target->line_count + 1, sizeof(char *));
@ -5087,8 +5218,11 @@ int iso_image_report_system_area(IsoImage *image,
target->lines[0] = target->buf; /* even if no lines get reported */ target->lines[0] = target->buf; /* even if no lines get reported */
target->byte_count = 0; target->byte_count = 0;
target->line_count = 0; target->line_count = 0;
ret = iso_impsysa_report(image, target, 0); if (what == 0)
if (ret < 0) ret = iso_impsysa_report(image, target, 0);
else
ret = iso_eltorito_report(image, target, 0);
if (ret <= 0)
goto ex; goto ex;
/* target to result */ /* target to result */
@ -5103,6 +5237,16 @@ ex:
return ret; return ret;
} }
/* API */
/* @param flag bit1= do not report system area but rather reply help text
bit15= dispose result from previous call
*/
int iso_image_report_system_area(IsoImage *image,
char ***result, int *line_count, int flag)
{
return iso_image_report_boot_eqp(image, 0, result, line_count, flag);
}
static static
int iso_analyze_system_area(IsoImage *image, IsoDataSource *src, int iso_analyze_system_area(IsoImage *image, IsoDataSource *src,
uint32_t image_size, int flag) uint32_t image_size, int flag)
@ -5163,6 +5307,18 @@ ex:;
return ret; return ret;
} }
/* API */
/* @param flag bit1= do not report system area but rather reply help text
bit15= dispose result from previous call
*/
int iso_image_report_el_torito(IsoImage *image,
char ***reply, int *line_count, int flag)
{
return iso_image_report_boot_eqp(image, 1, reply, line_count, flag);
}
int iso_image_import(IsoImage *image, IsoDataSource *src, int iso_image_import(IsoImage *image, IsoDataSource *src,
struct iso_read_opts *opts, struct iso_read_opts *opts,
IsoReadImageFeatures **features) IsoReadImageFeatures **features)

View File

@ -3395,6 +3395,14 @@ int el_torito_get_boot_platform_id(ElToritoBootImage *bootimg);
* Sets the load segment for the initial boot image. This is only for * Sets the load segment for the initial boot image. This is only for
* no emulation boot images, and is a NOP for other image types. * no emulation boot images, and is a NOP for other image types.
* *
* @param bootimg
* The image to to manipulate
* @param segment
* Load segment address.
* The data type of this parameter is not fully suitable. You may submit
* negative numbers in the range ((short) 0x8000) to ((short) 0xffff)
* in order to express the non-negative numbers 0x8000 to 0xffff.
*
* @since 0.6.2 * @since 0.6.2
*/ */
void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment); void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment);
@ -3417,6 +3425,14 @@ int el_torito_get_load_seg(ElToritoBootImage *bootimg);
* the initial boot procedure. This is only for * the initial boot procedure. This is only for
* no emulation boot images, and is a NOP for other image types. * no emulation boot images, and is a NOP for other image types.
* *
* @param bootimg
* The image to to manipulate
* @param sectors
* Number of 512-byte blocks to be loaded by the BIOS.
* The data type of this parameter is not fully suitable. You may submit
* negative numbers in the range ((short) 0x8000) to ((short) 0xffff)
* in order to express the non-negative numbers 0x8000 to 0xffff.
*
* @since 0.6.2 * @since 0.6.2
*/ */
void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors); void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors);
@ -3670,7 +3686,8 @@ int iso_image_get_system_area(IsoImage *img, char data[32768],
/** /**
* The maximum length of a single line in the output of function * The maximum length of a single line in the output of function
* iso_image_report_system_area(). This number includes the trailing 0. * iso_image_report_system_area() and iso_image_report_el_torito().
* This number includes the trailing 0.
* @since 1.3.8 * @since 1.3.8
*/ */
#define ISO_MAX_SYSAREA_LINE_LENGTH 4096 #define ISO_MAX_SYSAREA_LINE_LENGTH 4096
@ -3682,11 +3699,11 @@ int iso_image_get_system_area(IsoImage *img, char data[32768],
* iso_image_report_system_area() with flag bit0. * iso_image_report_system_area() with flag bit0.
*/ */
#define ISO_SYSAREA_REPORT_DOC \ #define ISO_SYSAREA_REPORT_DOC \
"Report format for recognized System Area data:", \ "Report format for recognized System Area data.", \
"", \ "", \
"No text will be reported if no System Area was loaded or if it was", \ "No text will be reported if no System Area was loaded or if it was", \
"entirely filled with 0-bytes.", \ "entirely filled with 0-bytes.", \
"Else there will be at least these two lines:", \ "Else there will be at least these three lines:", \
" System area options: hex", \ " System area options: hex", \
" see libisofs.h, parameter of iso_write_opts_set_system_area().", \ " see libisofs.h, parameter of iso_write_opts_set_system_area().", \
" System area summary: word ... word", \ " System area summary: word ... word", \
@ -3696,14 +3713,14 @@ int iso_image_get_system_area(IsoImage *img, char data[32768],
" cyl-align-{auto,on,off,all}, PReP, MIPS-Big-Endian,", \ " cyl-align-{auto,on,off,all}, PReP, MIPS-Big-Endian,", \
" MIPS-Little-Endian, SUN-SPARC-Disk-Label, HP-PA-PALO,", \ " MIPS-Little-Endian, SUN-SPARC-Disk-Label, HP-PA-PALO,", \
" not-recognized, GPT, APM }", \ " not-recognized, GPT, APM }", \
" ISO image size/512 : decimal", \
" size of ISO image in block units of 512 bytes.", \
"", \ "", \
"If an MBR is detected, with at least one partition entry of non-zero size,", \ "If an MBR is detected, with at least one partition entry of non-zero size,", \
"then there may be:", \ "then there may be:", \
" Partition offset : decimal", \ " Partition offset : decimal", \
" if not 0 then a second ISO 9660 superblock was found to which MBR", \ " if not 0 then a second ISO 9660 superblock was found to which MBR", \
" partition 1 is pointing.", \ " partition 1 is pointing.", \
" ISO image size/512 : decimal", \
" size of ISO image in MBR block units of 512 bytes.", \
" MBR heads per cyl : decimal", \ " MBR heads per cyl : decimal", \
" conversion factor between MBR C/H/S address and LBA. 0=inconsistent.", \ " conversion factor between MBR C/H/S address and LBA. 0=inconsistent.", \
" MBR secs per head : decimal", \ " MBR secs per head : decimal", \
@ -3857,7 +3874,7 @@ int iso_image_get_system_area(IsoImage *img, char data[32768],
* The array will be NULL if no System Area was loaded. It will be non-NULL * The array will be NULL if no System Area was loaded. It will be non-NULL
* with zero line count if the System Area was loaded and contains only * with zero line count if the System Area was loaded and contains only
* 0-bytes. * 0-bytes.
* Else it will consist of lines as descibed in ISO_SYSAREA_REPORT_DOC above. * Else it will consist of lines as described in ISO_SYSAREA_REPORT_DOC above.
* *
* File paths and other long texts are reported as "(too long to show here)" * File paths and other long texts are reported as "(too long to show here)"
* if their length plus preceeding text plus trailing 0-byte exceeds the * if their length plus preceeding text plus trailing 0-byte exceeds the
@ -3889,6 +3906,85 @@ int iso_image_get_system_area(IsoImage *img, char data[32768],
int iso_image_report_system_area(IsoImage *image, int iso_image_report_system_area(IsoImage *image,
char ***reply, int *line_count, int flag); char ***reply, int *line_count, int flag);
/**
* Text which describes the output format of iso_image_report_el_torito().
* It is publicly defined here only as part of the API description.
* Do not use it as macro in your application but rather call
* iso_image_report_el_torito() with flag bit0.
*/
#define ISO_ELTORITO_REPORT_DOC \
"Report format for recognized El Torito boot information.", \
"", \
"No text will be reported if no El Torito information was found.", \
"Else there will be at least these three lines", \
" El Torito catalog : decimal decimal", \
" tells the block address and number of 2048-blocks of the boot catalog.", \
" El Torito images : N Pltf B Emul Ld_seg Hdpt Ldsiz THG LBA", \
" is the headline of the boot image list.", \
" El Torito boot img : X word char word hex hex decimal word decimal", \
" tells about boot image number X:", \
" - Platform Id: \"BIOS\", \"PPC\", \"Mac\", \"UEFI\" or a hex number.", \
" - Bootability: either \"y\" or \"n\".", \
" - Emulation: \"none\", \"fd1.2\", \"fd1.4\", \"fd2.8\", \"hd\"", \
" for no emulation, three floppy MB sizes, hard disk.", \
" - Load Segment: start offset in boot image. 0x0000 means 0x07c0.", \
" - Hard disk emulation partition type: MBR partition type code.", \
" - Load size: number of 512-blocks to load with emulation mode \"none\".", \
" - THG: word of three characters tells the presence of extra features:", \
" \"t\"=boot info table, \"h\"=suitable for isohybrid,", \
" \"g\"=GRUB2 boot info, \"-\"=feature not present", \
" - LBA: start block number in ISO filesystem (2048-block).", \
"", \
"The following lines may be omitted from the report:", \
" El Torito cat path : iso_rr_path", \
" tells the path to the data file in the ISO image which belongs to", \
" the block address where the boot catalog starts.", \
" (This line is not reported if no path points to that block.)", \
" El Torito id string: X hex_digits", \
" tells the id string of the catalog section which hosts boot image X.", \
" (This line is not reported if the id string is all zero.)", \
" El Torito sel crit : X hex_digits", \
" tells the selection criterion of boot image X.", \
" (This line is not reported if the criterion is all zero.)", \
" El Torito img path : X iso_rr_path", \
" tells the path to the data file in the ISO image which belongs to", \
" the block address given by LBA of boot image X.", \
" (This line is not reported if no path points to that block.)", \
"@END_OF_DOC@"
/**
* Obtain an array of texts describing the detected properties of the
* eventually loaded El Torito boot information.
* The array will be NULL if no El Torito info was loaded.
* Else it will consist of lines as described in ISO_ELTORITO_REPORT_DOC above.
*
* The lines have the same length restrictions and whitespace rules as the ones
* returned by iso_image_report_system_area().
*
* @param image
* The image to be inquired.
* @param reply
* Will return an array of pointers to the result text lines or NULL.
* Dispose a non-NULL reply by a call to iso_image_report_el_torito()
* with flag bit15, when no longer needed.
* Be prepared for a long text with up to ISO_MAX_SYSAREA_LINE_LENGTH
* characters per line.
* @param line_count
* Will return the number of valid pointers in reply.
* @param flag
* Bitfield for control purposes
* bit0= do not report system area but rather reply a copy of
* above text line array ISO_ELTORITO_REPORT_DOC.
* With this bit it is permissible to submit image as NULL.
* bit15= dispose result from previous call.
* @return
* 1 on success, 0 if no El Torito information was loaded, < 0 error.
* @since 1.3.8
*/
int iso_image_report_el_torito(IsoImage *image,
char ***reply, int *line_count, int flag);
/** /**
* Compute a CRC number as expected in the GPT main and backup header blocks. * Compute a CRC number as expected in the GPT main and backup header blocks.
* *
@ -4959,8 +5055,10 @@ IsoStream *iso_file_get_stream(IsoFile *file);
* @param flag * @param flag
* Reserved for future usage, submit 0 * Reserved for future usage, submit 0
* @return * @return
* 1 if lba is valid (file comes from old image), 0 if file was newly * 1 if lba is valid (file comes from old image and has only one section),
* added, i.e. it does not come from an old image, < 0 error * 0 if file was newly added, i.e. it does not come from an old image,
* < 0 error, especially ISO_WRONG_ARG_VALUE if the file has more than
* one file section.
* *
* @since 0.6.4 * @since 0.6.4
* *

View File

@ -117,6 +117,7 @@ iso_image_import;
iso_image_new; iso_image_new;
iso_image_ref; iso_image_ref;
iso_image_remove_boot_image; iso_image_remove_boot_image;
iso_image_report_el_torito;
iso_image_report_system_area; iso_image_report_system_area;
iso_image_set_abstract_file_id; iso_image_set_abstract_file_id;
iso_image_set_app_use; iso_image_set_app_use;