diff --git a/libisofs/eltorito.c b/libisofs/eltorito.c index 119d4e2..0f6e2ee 100644 --- a/libisofs/eltorito.c +++ b/libisofs/eltorito.c @@ -82,15 +82,16 @@ void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment) { if (bootimg->type != 0) return; - bootimg->load_seg = segment; + if (segment < 0) + bootimg->load_seg = 0x1000 + segment; + else + bootimg->load_seg = segment; } /* API */ int el_torito_get_load_seg(ElToritoBootImage *bootimg) { - if (bootimg->load_seg < 0) - return 0xffff - bootimg->load_seg; - return bootimg->load_seg; + return (int) bootimg->load_seg; } /** @@ -102,15 +103,16 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors) { if (bootimg->type != 0) return; - bootimg->load_size = sectors; + if (sectors < 0) + bootimg->load_size = 0x10000 + sectors; + else + bootimg->load_size = sectors; } /* API */ int el_torito_get_load_size(ElToritoBootImage *bootimg) { - if (bootimg->load_size < 0) - return 0xffff - bootimg->load_size; - return bootimg->load_size; + return (int) bootimg->load_size; } /** diff --git a/libisofs/eltorito.h b/libisofs/eltorito.h index acfd43e..64ce050 100644 --- a/libisofs/eltorito.h +++ b/libisofs/eltorito.h @@ -78,8 +78,8 @@ struct el_torito_boot_image { unsigned int isolinux_options; unsigned char type; /**< The type of image */ unsigned char partition_type; /**< type of partition for HD-emul images */ - short load_seg; /**< Load segment for the initial boot image. */ - short load_size; /**< Number of sectors to load. */ + uint16_t load_seg; /**< Load segment for the initial boot image. */ + uint16_t load_size; /**< Number of sectors to load. */ /* Byte 1 of Validation Entry or Section Header Entry: 0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */ diff --git a/libisofs/fs_image.c b/libisofs/fs_image.c index 4744618..b7c3e23 100644 --- a/libisofs/fs_image.c +++ b/libisofs/fs_image.c @@ -4770,7 +4770,7 @@ int iso_impsysa_report(IsoImage *image, struct iso_impsysa_result *target, sprintf(msg, "ISO image size/512 : %.f", ((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) { sprintf(msg, "Partition offset : %d", sai->partition_offset); iso_impsysa_line(target, msg); @@ -5027,58 +5027,189 @@ ex: 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, §ion_count, + §ions, 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 */ /* @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) +static +int iso_image_report_boot_eqp(IsoImage *image, int what, + char ***result, int *line_count, int flag) { - int ret, i, count = 0; - char *buf; - static char *doc[] = {ISO_SYSAREA_REPORT_DOC}; + int ret; + char **doc; + static char *sysarea_doc[] = {ISO_SYSAREA_REPORT_DOC}; + static char *eltorito_doc[] = {ISO_ELTORITO_REPORT_DOC}; struct iso_impsysa_result *target = NULL; - if (flag & (1 << 15)) { - if (*result == NULL) - {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 << 15)) + return iso_report_result_destroy(result, 0); if (flag & 1) { - *line_count = 0; - for (i = 0; strcmp(doc[i], "@END_OF_DOC@") != 0; i++) - count += strlen(doc[i]) + 1; - *result = calloc(i, sizeof(char *)); - if (*result == NULL) - {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;} + if (what == 0) + doc = sysarea_doc; + else + doc = eltorito_doc; + return iso_report_help(doc, result, line_count, 0); } - *result = NULL; - if (image->system_area_data == NULL) - {ret = 0; goto ex;} + *result = NULL; + *line_count = 0; ret = iso_impsysa_result_new(&target, 0); if (ret < 0) goto ex; - ret = iso_impsysa_report(image, target, 0); - if (ret < 0) + if (what == 0) + ret = iso_impsysa_report(image, target, 0); + else + ret = iso_eltorito_report(image, target, 0); + if (ret <= 0) goto ex; target->buf = calloc(1, target->byte_count + 1); 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->byte_count = 0; target->line_count = 0; - ret = iso_impsysa_report(image, target, 0); - if (ret < 0) + if (what == 0) + ret = iso_impsysa_report(image, target, 0); + else + ret = iso_eltorito_report(image, target, 0); + if (ret <= 0) goto ex; /* target to result */ @@ -5103,6 +5237,16 @@ ex: 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 int iso_analyze_system_area(IsoImage *image, IsoDataSource *src, uint32_t image_size, int flag) @@ -5163,6 +5307,18 @@ ex:; 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, struct iso_read_opts *opts, IsoReadImageFeatures **features) diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 76e36c5..41efb68 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -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 * 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 */ 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 * 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 */ 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 - * 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 */ #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. */ #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", \ "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", \ " see libisofs.h, parameter of iso_write_opts_set_system_area().", \ " 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,", \ " MIPS-Little-Endian, SUN-SPARC-Disk-Label, HP-PA-PALO,", \ " 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,", \ "then there may be:", \ " Partition offset : decimal", \ " if not 0 then a second ISO 9660 superblock was found to which MBR", \ " 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", \ " conversion factor between MBR C/H/S address and LBA. 0=inconsistent.", \ " 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 * with zero line count if the System Area was loaded and contains only * 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)" * 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, 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. * @@ -4959,8 +5055,10 @@ IsoStream *iso_file_get_stream(IsoFile *file); * @param flag * Reserved for future usage, submit 0 * @return - * 1 if lba is valid (file comes from old image), 0 if file was newly - * added, i.e. it does not come from an old image, < 0 error + * 1 if lba is valid (file comes from old image and has only one section), + * 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 * diff --git a/libisofs/libisofs.ver b/libisofs/libisofs.ver index e11f953..1a8248e 100644 --- a/libisofs/libisofs.ver +++ b/libisofs/libisofs.ver @@ -117,6 +117,7 @@ iso_image_import; iso_image_new; iso_image_ref; iso_image_remove_boot_image; +iso_image_report_el_torito; iso_image_report_system_area; iso_image_set_abstract_file_id; iso_image_set_app_use;