New API call iso_image_report_system_area()

This commit is contained in:
Thomas Schmitt 2014-04-11 15:39:45 +02:00
parent 1ac59bec46
commit dd27f579eb
18 changed files with 2184 additions and 108 deletions

View File

@ -580,7 +580,7 @@ Basic data partition: a2 a0 d0 eb , e5 b9 , 33 44 , 87 c0 68 b6 b7 26 99 c7
HFS+ partition : 00 53 46 48 , 00 00 , aa 11 , aa 11 00 30 65 43 ec ac HFS+ partition : 00 53 46 48 , 00 00 , aa 11 , aa 11 00 30 65 43 ec ac
EFI System partition: 28 73 2a c1 , 1f f8 , d2 11 , ba 4b 00 a0 c9 3e c9 3b EFI System partition: 28 73 2a c1 , 1f f8 , d2 11 , ba 4b 00 a0 c9 3e c9 3b
Note that the wikipedia list shows the first 32-bit word and the next two Note that the wikipedia list shows the first 32-bit word and the next two
16-bit words in little-endia interpretation. 16-bit words in little-endian interpretation.
The partition table is an array of entries. Each has a size of 128 bytes. The partition table is an array of entries. Each has a size of 128 bytes.
A partition table entry looks like: A partition table entry looks like:

View File

@ -768,8 +768,8 @@ struct ecma119_image
/* Allocation block size of HFS+ /* Allocation block size of HFS+
May be defined to 512 or 2048 before hfsplus_writer_create(). May be defined to 512 or 2048 before hfsplus_writer_create().
*/ */
int hfsp_cat_node_size; /* 2 * apm_block_size */ int hfsp_cat_node_size; /* 2 * hfsp_block_size */
int hfsp_iso_block_fac; /* 2048 / apm_block_size */ int hfsp_iso_block_fac; /* 2048 / hfsp_block_size */
/* Apple Partition Map description. To be composed during IsoImageWriter /* Apple Partition Map description. To be composed during IsoImageWriter
method ->compute_data_blocks() by calling iso_register_apm_entry(). method ->compute_data_blocks() by calling iso_register_apm_entry().

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2007 Vreixo Formoso * Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 - 2013 Thomas Schmitt * Copyright (c) 2010 - 2014 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
@ -440,6 +440,8 @@ int create_image(IsoImage *image, const char *image_path,
iso_node_ref(imgfile); /* get our ref */ 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_isohybrid_capable = 0;
boot->isolinux_options = 0; boot->isolinux_options = 0;
boot->type = boot_media_type; boot->type = boot_media_type;
boot->partition_type = partition_type; boot->partition_type = partition_type;

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2007 Vreixo Formoso * Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 Thomas Schmitt * Copyright (c) 2010 - 2014 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
@ -59,6 +59,10 @@ struct el_torito_boot_image {
*/ */
unsigned int seems_boot_info_table:1; unsigned int seems_boot_info_table:1;
unsigned int seems_grub2_boot_info:1; unsigned int seems_grub2_boot_info:1;
/**
* Whether the boot image seems to be capable of isohybrid
*/
unsigned int seems_isohybrid_capable:1;
/** /**
* isolinux options * isolinux options
* bit 0 -> whether to patch image * bit 0 -> whether to patch image

File diff suppressed because it is too large Load Diff

View File

@ -475,7 +475,8 @@ int hfsplus_tail_writer_compute_data_blocks(IsoImageWriter *writer)
t->hfsp_total_blocks = hfsp_curblock - t->hfsp_part_start; t->hfsp_total_blocks = hfsp_curblock - t->hfsp_part_start;
return iso_quick_apm_entry(t, t->hfsp_part_start / block_fac, return iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
t->hfsp_part_start / block_fac,
t->hfsp_total_blocks / block_fac + t->hfsp_total_blocks / block_fac +
!!(t->hfsp_total_blocks % block_fac), !!(t->hfsp_total_blocks % block_fac),
"HFSPLUS_Hybrid", "Apple_HFS"); "HFSPLUS_Hybrid", "Apple_HFS");

View File

@ -22,6 +22,97 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
int iso_imported_sa_new(struct iso_imported_sys_area **boots, int flag)
{
struct iso_imported_sys_area *b;
*boots = NULL;
b = calloc(1, sizeof(struct iso_imported_sys_area));
if (b == NULL)
return ISO_OUT_OF_MEM;
b->mbr_req = NULL;
b->apm_req = NULL;
b->gpt_req = NULL;
b->gpt_backup_comments = NULL;
b->mips_boot_file_paths = NULL;
b->mips_vd_entries = NULL;
b->sparc_disc_label = NULL;
b->sparc_core_node = NULL;
b->sparc_entries = NULL;
b->hppa_cmdline = NULL;
b->hppa_bootloader = NULL;
b->hppa_kernel_32 = NULL;
b->hppa_kernel_64 = NULL;
b->hppa_ramdisk = NULL;
*boots = b;
return 1;
}
int iso_imported_sa_unref(struct iso_imported_sys_area **boots, int flag)
{
int i;
struct iso_imported_sys_area *b;
b = *boots;
if (b == NULL)
return 2;
if (b->refcount > 0)
b->refcount--;
if (b->refcount > 0)
return 2;
if (b->mbr_req != NULL) {
for (i = 0; i < b->mbr_req_count; i++)
LIBISO_FREE_MEM(b->mbr_req[i]);
LIBISO_FREE_MEM(b->mbr_req);
}
if (b->apm_req != NULL) {
for (i = 0; i < b->apm_req_count; i++)
LIBISO_FREE_MEM(b->apm_req[i]);
LIBISO_FREE_MEM(b->apm_req);
}
if (b->gpt_req != NULL) {
for (i = 0; i < b->gpt_req_count; i++)
LIBISO_FREE_MEM(b->gpt_req[i]);
LIBISO_FREE_MEM(b->gpt_req);
}
LIBISO_FREE_MEM(b->gpt_backup_comments);
if (b->mips_boot_file_paths != NULL) {
for (i = 0; i < b->num_mips_boot_files; i++)
LIBISO_FREE_MEM(b->mips_boot_file_paths[i]);
LIBISO_FREE_MEM(b->mips_boot_file_paths);
}
if (b->mips_vd_entries != NULL) {
for (i = 0; i < b->num_mips_boot_files; i++)
LIBISO_FREE_MEM(b->mips_vd_entries[i]);
LIBISO_FREE_MEM(b->mips_vd_entries);
}
LIBISO_FREE_MEM(b->mipsel_boot_file_path);
LIBISO_FREE_MEM(b->sparc_disc_label);
if (b->sparc_core_node != NULL)
iso_node_unref((IsoNode *) b->sparc_core_node);
LIBISO_FREE_MEM(b->sparc_entries);
LIBISO_FREE_MEM(b->hppa_cmdline);
LIBISO_FREE_MEM(b->hppa_bootloader);
LIBISO_FREE_MEM(b->hppa_kernel_32);
LIBISO_FREE_MEM(b->hppa_kernel_64);
LIBISO_FREE_MEM(b->hppa_ramdisk);
LIBISO_FREE_MEM(b);
*boots = NULL;
return 1;
}
/** /**
* Create a new image, empty. * Create a new image, empty.
* *
@ -103,6 +194,7 @@ int iso_image_new(const char *name, IsoImage **image)
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++) for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
img->hfsplus_blessed[i] = NULL; img->hfsplus_blessed[i] = NULL;
img->collision_warnings = 0; img->collision_warnings = 0;
img->imported_sa_info = NULL;
*image = img; *image = img;
return ISO_SUCCESS; return ISO_SUCCESS;
@ -165,6 +257,7 @@ void iso_image_unref(IsoImage *image)
if (image->system_area_data != NULL) if (image->system_area_data != NULL)
free(image->system_area_data); free(image->system_area_data);
iso_image_free_checksums(image, 0); iso_image_free_checksums(image, 0);
iso_imported_sa_unref(&(image->imported_sa_info), 0);
free(image); free(image);
} }
} }

View File

@ -212,6 +212,9 @@ struct Iso_Image
/* Counts the name collisions while iso_image_import() */ /* Counts the name collisions while iso_image_import() */
size_t collision_warnings; size_t collision_warnings;
/* Contains the assessment of boot aspects of the loaded image */
struct iso_imported_sys_area *imported_sa_info;
}; };
@ -263,4 +266,125 @@ int iso_image_set_pvd_times(IsoImage *image,
char *creation_time, char *modification_time, char *creation_time, char *modification_time,
char *expiration_time, char *effective_time); char *expiration_time, char *effective_time);
/* Collects boot block information obtained from the system area of
imported images
*/
struct iso_imported_sys_area {
int refcount;
/* Whether there was some System Area data at all */
int is_not_zero;
/* Giving the error number if the assessment ended by an error */
int overall_return;
/* Size of the imported ISO image */
uint32_t image_size;
/* see libisofs.h : iso_write_opts_set_system_area() */
int system_area_options;
/* The perceived MBR partitions */
struct iso_mbr_partition_request **mbr_req;
int mbr_req_count;
/* see ecma119.h : struct ecma119_image , struct iso_write_opts */
/* Effective partition table parameter: 1 to 63, 0= disabled/default */
int partition_secs_per_head;
/* 1 to 255, 0= disabled/default */
int partition_heads_per_cyl;
/* see ecma119.h : struct iso_write_opts */
uint32_t partition_offset;
/* 2048-byte start LBA and block count of PreP partition */
uint32_t prep_part_start;
uint32_t prep_part_size;
/* see ecma119.h : struct ecma119_image */
struct iso_apm_partition_request **apm_req;
int apm_req_count;
int apm_req_flags;
/* Number of found "GapNN", "ISO9660_data" partitions in APM */
int apm_gap_count;
/* see ecma119.h : struct iso_write_opts */
int apm_block_size;
/* >>> see ecma119.h : struct iso_write_opts */
int hfsp_block_size;
/* see ecma119.h : struct ecma119_image */
struct iso_gpt_partition_request **gpt_req;
int gpt_req_count;
int gpt_req_flags;
/* see ecma119.h : struct ecma119_image */
uint8_t gpt_disk_guid[16];
/* Start of GPT entries in System Area, block size 512 */
uint64_t gpt_part_start;
uint32_t gpt_max_entries;
uint64_t gpt_first_lba;
uint64_t gpt_last_lba;
uint64_t gpt_backup_lba;
char *gpt_backup_comments;
uint32_t gpt_head_crc_found;
uint32_t gpt_head_crc_should;
uint32_t gpt_array_crc_found;
uint32_t gpt_array_crc_should;
/* see image.h : struct Iso_Image */
int num_mips_boot_files;
char **mips_boot_file_paths; /* ISO 9660 Rock Ridge Paths */
struct iso_mips_voldir_entry **mips_vd_entries;
/* see ecma119.h : struct ecma119_image */
/* Memorized ELF parameters from MIPS Little Endian boot file */
uint32_t mipsel_e_entry;
uint32_t mipsel_p_offset;
uint32_t mipsel_p_vaddr;
uint32_t mipsel_p_filesz;
uint32_t mipsel_seg_start;
char *mipsel_boot_file_path;
/* see image.h : struct Iso_Image */
char *sparc_disc_label;
int sparc_secs_per_head;
int sparc_heads_per_cyl;
struct iso_sun_disk_label_entry *sparc_entries;
int sparc_entry_count;
/* grub2-sparc-core : a node in the ISO image
published at bytes 0x228 to 0x233
*/
uint64_t sparc_grub2_core_adr;
uint32_t sparc_grub2_core_size;
IsoFile *sparc_core_node;
/* see image.h : struct Iso_Image */
int hppa_hdrversion;
char *hppa_cmdline;
uint32_t hppa_kern32_adr;
uint32_t hppa_kern32_len;
uint32_t hppa_kern64_adr;
uint32_t hppa_kern64_len;
uint32_t hppa_ramdisk_adr;
uint32_t hppa_ramdisk_len;
uint32_t hppa_bootloader_adr;
uint32_t hppa_bootloader_len;
uint32_t hppa_ipl_entry;
char *hppa_kernel_32;
char *hppa_kernel_64;
char *hppa_ramdisk;
char *hppa_bootloader;
};
int iso_imported_sa_new(struct iso_imported_sys_area **sa_info, int flag);
int iso_imported_sa_unref(struct iso_imported_sys_area **sa_info, int flag);
#endif /*LIBISO_IMAGE_H_*/ #endif /*LIBISO_IMAGE_H_*/

View File

@ -2164,14 +2164,15 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* that one partition is defined which begins at the second * that one partition is defined which begins at the second
* 512-byte block of the image and ends where the image ends. * 512-byte block of the image and ends where the image ends.
* This works with and without system_area_data. * This works with and without system_area_data.
* Modern GRUB2 system areas get also treated by bit14. See below.
* bit1= Only with System area type 0 = MBR * bit1= Only with System area type 0 = MBR
* Apply isohybrid MBR patching to the system area. * Apply isohybrid MBR patching to the system area.
* This works only with system area data from SYSLINUX plus an * This works only with system area data from SYSLINUX plus an
* ISOLINUX boot image (see iso_image_set_boot_image()) and * ISOLINUX boot image as first submitted boot image
* only if not bit0 is set. * (see iso_image_set_boot_image()) and only if not bit0 is set.
* bit2-7= System area type * bit2-7= System area type
* 0= with bit0 or bit1: MBR * 0= with bit0 or bit1: MBR
* else: unspecified type which will be used unaltered. * else: type depends on bits bit10-13: System area sub type
* 1= MIPS Big Endian Volume Header * 1= MIPS Big Endian Volume Header
* @since 0.6.38 * @since 0.6.38
* Submit up to 15 MIPS Big Endian boot files by * Submit up to 15 MIPS Big Endian boot files by
@ -2216,15 +2217,17 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* @since 1.2.4 * @since 1.2.4
* With type 0 = MBR: * With type 0 = MBR:
* Gets overridden by bit0 and bit1. * Gets overridden by bit0 and bit1.
* 0 = no particular sub type * 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
* which needs to have own MBR partition entries. * which needs to have own MBR partition entries.
* 2 = generic MBR @since 1.3.8
* bit14= Only with System area type 0 = MBR * bit14= Only with System area type 0 = MBR
* GRUB2 boot provisions: * GRUB2 boot provisions:
* @since 1.3.0 * @since 1.3.0
* Patch system area at byte 92 to 99 with 512-block address + 1 * Patch system area at byte 0x1b0 to 0x1b7 with
* of the first boot image file. Little-endian 8-byte. * (512-block address + 4) of the first boot image file.
* Little-endian 8-byte.
* Should be combined with options bit0. * Should be combined with options bit0.
* Will not be in effect if options bit1 is set. * Will not be in effect if options bit1 is set.
* @param flag * @param flag
@ -3665,6 +3668,219 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
int iso_image_get_system_area(IsoImage *img, char data[32768], int iso_image_get_system_area(IsoImage *img, char data[32768],
int *options, int flag); int *options, int flag);
/**
* The maximum length of a single line in the output of function
* iso_image_report_system_area(). This number includes the trailing 0.
* @since 1.3.8
*/
#define ISO_MAX_SYSAREA_LINE_LENGTH 4096
/**
* Text which describes the output format of iso_image_report_system_area().
* 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_system_area() with flag bit0.
*/
#define ISO_SYSAREA_REPORT_DOC \
"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:", \
" System area options: hex", \
" see libisofs.h, parameter of iso_write_opts_set_system_area().", \
" System area summary: word ... word", \
" human readable interpretation of system area options and other info", \
" The words are from the set:", \
" { MBR, protective-msdos-label, isohybrid, CHRP, grub2-mbr,", \
" cyl-align-{auto,on,off,all}, PReP, MIPS-Big-Endian,", \
" MIPS-Little-Endian, SUN-SPARC-Disk-Label, HP-PA-PALO,", \
" not-recognized,", \
" GPT, APM }", \
"", \
"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", \
" conversion factor between MBR C/H/S address and LBA. 0=inconsistent.", \
" MBR partition table: N Status Type Start Blocks", \
" headline for MBR partition table.", \
" MBR partition : X hex hex decimal decimal", \
" gives partition number, status byte, type byte, start block,", \
" and number of blocks. 512 bytes per block.", \
" MBR partition path : X path", \
" the path of a file in the ISO image which begins at the partition", \
" start block of partition X.", \
" PReP boot partition: decimal decimal", \
" gives start block and size of a PReP boot partition in ISO 9660", \
" block units of 2048 bytes.", \
"", \
"GUID Partition Table can coexist with MBR:", \
" GPT : N Info", \
" headline for GPT partition table. The fields are too wide for a", \
" neat table. So they are listed with a partition number and a text.", \
" GPT CRC should be : <hex> to match first 92 GPT header block bytes", \
" GPT CRC found : <hex> matches all 512 bytes of GPT header block", \
" libisofs-1.2.4 to 1.2.8 had a bug with the GPT header CRC. So", \
" libisofs is willing to recognize GPT with the buggy CRC. These", \
" two lines inform that most partition editors will not accept it.", \
" GPT array CRC wrong: should be <hex>, found <hex>", \
" GPT entry arrays are accepted even if their CRC does not match.", \
" In this case, both CRCs are reported by this line.", \
" GPT backup problems: text", \
" reports about inconsistencies between main GPT and backup GPT.", \
" The statements are comma separated:", \
" Implausible header LBA <decimal>", \
" Cannot read header block at 2k LBA <decimal>", \
" Not a GPT 1.0 header of 92 bytes for 128 bytes per entry", \
" Head CRC <hex> wrong. Should be <hex>", \
" Head CRC <hex> wrong. Should be <hex>. Matches all 512 block bytes", \
" Disk GUID differs (<hex_digits>)", \
" Cannot read array block at 2k LBA <decimal>", \
" Array CRC <hex> wrong. Should be <hex>", \
" Entries differ for partitions <decimal> [... <decimal>]", \
" GPT disk GUID : hex_digits", \
" 32 hex digits giving the byte string of the disk's GUID", \
" GPT entry array : decimal decimal word", \
" start block of partition entry array and number of entries. 512 bytes", \
" per block. The word may be \"separated\" if partitions are disjoint,", \
" \"overlapping\" if they are not. In future there may be \"nested\"", \
" as special case where all overlapping partitions are superset and", \
" subset, and \"covering\" as special case of disjoint partitions", \
" covering the whole GPT block range for partitions.", \
" GPT lba range : decimal decimal decimal", \
" addresses of first payload block, last payload block, and of the", \
" GPT backup header block. 512 bytes per block.", \
" GPT partition name : X hex_digits", \
" up to 144 hex digits giving the UTF-16LE name byte string of", \
" partition X. Trailing 16 bit 0-characters are omitted.", \
" GPT partname local : X text", \
" the name of partition X converted to the local character set.", \
" This line may be missing if the name cannot be converted, or is", \
" empty.", \
" GPT partition GUID : X hex_digits", \
" 32 hex digits giving the byte string of the GUID of partition X.", \
" GPT type GUID : X hex_digits", \
" 32 hex digits giving the byte string of the type GUID of partition X.", \
" GPT partition flags: X hex", \
" 64 flag bits of partition X in hex representation.", \
" Known bit meanings are:", \
" bit0 = \"System Partition\" Do not alter.", \
" bit2 = Legacy BIOS bootable (MBR partition type 0x80)", \
" bit60= read-only", \
" GPT start and size : X decimal decimal", \
" start block and number of blocks of partition X. 512 bytes per block.", \
" GPT partition path : X path", \
" the path of a file in the ISO image which begins at the partition", \
" start block of partition X.", \
"", \
"Apple partition map can coexist with MBR:", \
" APM : N Info", \
" headline for human readers.", \
" APM block size : decimal", \
" block size of Apple Partition Map. 512 or 2048. This applies to", \
" start address and size of all partitions in the APM.", \
" APM gap fillers : decimal", \
" tells the number of partitions with name \"Gap[0-9[0-9]]\" and type", \
" \"ISO9660_data\".", \
" APM partition name : X text", \
" the name of partition X. Up to 32 characters.", \
" APM partition type : X text", \
" the type string of partition X. Up to 32 characters.", \
" APM start and size : X decimal decimal", \
" start block and number of blocks of partition X.", \
" APM partition path : X path", \
" the path of a file in the ISO image which begins at the partition", \
" start block of partition X.", \
"", \
"If a MIPS Big Endian Volume Header is detected, there may be:", \
" MIPS-BE volume dir : N Name Block Bytes", \
" headline for human readers.", \
" MIPS-BE boot entry : X upto8chr decimal decimal", \
" tells name, 512-byte block address, and byte count of boot entry X.", \
" MIPS-BE boot path : X path", \
" tells the path to the boot image file in the ISO image which belongs", \
" to the block address given by boot entry X.", \
"", \
"If a DEC Boot Block for MIPS Little Endian is detected, there may be:", \
" MIPS-LE boot map : LoadAddr ExecAddr SegmentSize SegmentStart", \
" headline for human readers.", \
" MIPS-LE boot params: decimal decimal decimal decimal", \
" tells four numbers which are originally derived from the ELF header", \
" of the boot file. The first two are counted in bytes, the other two", \
" are counted in blocks of 512 bytes.", \
" MIPS-LE boot path : path", \
" tells the path to the boot file in the ISO image which belongs to the", \
" address given by SegmentStart.", \
" MIPS-LE elf offset : decimal", \
" tells the relative 512-byte block offset inside the boot file:", \
" SegmentStart - FileStartBlock", \
"", \
"If a SUN SPARC Disk Label is present:", \
" SUN SPARC disklabel: text", \
" tells the disk label text.", \
" SUN SPARC secs/head: decimal", \
" tells the number of sectors per head.", \
" SUN SPARC heads/cyl: decimal", \
" tells the number of heads per cylinder.", \
" SPARC GRUB2 core : decimal decimal", \
" tells byte address and byte count of the GRUB2 SPARC core file.", \
" SPARC GRUB2 path : path", \
" tells the path to the data file in the ISO image which belongs to the", \
" address given by core.", \
"", \
"If a HP-PA PALO boot sector version 4 or 5 is present:", \
" PALO header version: decimal", \
" tells the PALO header version: 4 or 5.", \
" HP-PA cmdline : text", \
" tells the command line for the kernels.", \
" HP-PA boot files : ByteAddr ByteSize Path", \
" headline for human readers.", \
" HP-PA 32-bit kernel: decimal decimal path", \
" tells start byte, byte count, and file path of the 32-bit kernel.", \
" HP-PA 64-bit kernel: decimal decimal path", \
" tells the same for the 64-bit kernel.", \
" HP-PA ramdisk : decimal decimal path", \
" tells the same for the ramdisk file.", \
" HP-PA bootloader : decimal decimal path", \
" tells the same for the bootloader file.", \
"@END_OF_DOC@"
/**
* Obtain a text describing the detected properties of the eventually loaded
* System Area.
* The text will be NULL if no System Area was loaded. It will be empty but
* non-NULL 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.
*
* 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
* line length limit of ISO_MAX_SYSAREA_LINE_LENGTH bytes.
*
* @param image
* The image to be inquired.
* @param reply
* Will return the allocated result text or NULL. Dispose a non-NULL
* reply by free() when no longer needed.
* Be prepared for a long text with up to ISO_MAX_SYSAREA_LINE_LENGTH
* characters per line.
* @param flag
* Bitfield for control purposes
* bit0= do not report system area but rather reply a copy of
* above text ISO_SYSAREA_REPORT_DOC.
* With this bit it is permissible to submit image as NULL.
* @return
* 1 on success, 0 if no System Area was loaded, < 0 error.
* @since 1.3.8
*/
int iso_image_report_system_area(IsoImage *image, char **reply, int flag);
/** /**
* Add a MIPS boot file path to the image. * Add a MIPS boot file path to the image.
* Up to 15 such files can be written into a MIPS Big Endian Volume Header * Up to 15 such files can be written into a MIPS Big Endian Volume Header
@ -4736,8 +4952,8 @@ int iso_file_get_old_image_lba(IsoFile *file, uint32_t *lba, int flag);
* @since 0.6.8 * @since 0.6.8
*/ */
int iso_file_get_old_image_sections(IsoFile *file, int *section_count, int iso_file_get_old_image_sections(IsoFile *file, int *section_count,
struct iso_file_section **sections, struct iso_file_section **sections,
int flag); int flag);
/* /*
* Like iso_file_get_old_image_lba(), but take an IsoNode. * Like iso_file_get_old_image_lba(), but take an IsoNode.
@ -5361,7 +5577,7 @@ int iso_ring_buffer_get_status(struct burn_source *b, size_t *size,
* *
* @param queue_severity Gives the minimum limit for messages to be queued. * @param queue_severity Gives the minimum limit for messages to be queued.
* Default: "NEVER". If you queue messages then you * Default: "NEVER". If you queue messages then you
* must consume them by iso_msgs_obtain(). * must consume them by iso_obtain_msgs().
* @param print_severity Does the same for messages to be printed directly * @param print_severity Does the same for messages to be printed directly
* to stderr. * to stderr.
* @param print_id A text prefix to be printed before the message. * @param print_id A text prefix to be printed before the message.
@ -7209,13 +7425,14 @@ int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
* @param flag * @param flag
* Bitfield for control purposes. * Bitfield for control purposes.
* bit0-bit7= Name space * bit0-bit7= Name space
* 0= generic (to_charset is valid, * 0= generic (output charset is used,
* no reserved characters, no length limits) * no reserved characters, no length limits)
* 1= Rock Ridge (to_charset is valid) * 1= Rock Ridge (output charset is used)
* 2= Joliet (to_charset gets overridden by UCS-2 or UTF-16) * 2= Joliet (output charset gets overridden by UCS-2 or
* 3= ECMA-119 (to_charset gets overridden by the * UTF-16)
* 3= ECMA-119 (output charset gets overridden by the
* dull ISO 9660 subset of ASCII) * dull ISO 9660 subset of ASCII)
* 4= HFS+ (to_charset gets overridden by UTF-16BE) * 4= HFS+ (output charset gets overridden by UTF-16BE)
* bit8= Treat input text as directory name * bit8= Treat input text as directory name
* (matters for Joliet and ECMA-119) * (matters for Joliet and ECMA-119)
* bit9= Do not issue error messages * bit9= Do not issue error messages
@ -7694,6 +7911,10 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
/** HP-PA PALO command line too long (FAILURE, HIGH, -402) */ /** HP-PA PALO command line too long (FAILURE, HIGH, -402) */
#define ISO_HPPA_PALO_CMDLEN 0xE830FE6E #define ISO_HPPA_PALO_CMDLEN 0xE830FE6E
/** Problems encountered during inspection of System Area (WARN, HIG, -403) */
#define ISO_SYSAREA_PROBLEMS 0xD030FE6D
/* Internal developer note: /* Internal developer note:
Place new error codes directly above this comment. Place new error codes directly above this comment.

View File

@ -116,6 +116,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_system_area;
iso_image_set_abstract_file_id; iso_image_set_abstract_file_id;
iso_image_set_app_use; iso_image_set_app_use;
iso_image_set_application_id; iso_image_set_application_id;

View File

@ -50,7 +50,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-2012 Thomas Schmitt and 2008-2014 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.
@ -435,9 +435,10 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
for (j = 0; j < t->bootsrc[i]->nsections; j++) for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048; block_count += t->bootsrc[i]->sections[j].size / 2048;
ret = iso_quick_gpt_entry( ret = iso_quick_gpt_entry(
t, t->bootsrc[i]->sections[0].block, t->gpt_req, &(t->gpt_req_count),
block_count, uuid, zero_uuid, gpt_flags, ((uint64_t) t->bootsrc[i]->sections[0].block) * 4,
(uint8_t *) gpt_name); ((uint64_t) block_count) * 4,
uuid, zero_uuid, gpt_flags, (uint8_t *) gpt_name);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
@ -449,7 +450,8 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
block_count = 0; block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++) for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048; block_count += t->bootsrc[i]->sections[j].size / 2048;
ret = iso_quick_apm_entry(t, t->bootsrc[i]->sections[0].block, ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
t->bootsrc[i]->sections[0].block,
block_count, "EFI", "Apple_HFS"); block_count, "EFI", "Apple_HFS");
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -466,7 +468,8 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
iso_ascii_utf_16le(gpt_name); iso_ascii_utf_16le(gpt_name);
/* Let it be open ended. iso_write_gpt() will truncate it as needed. */ /* Let it be open ended. iso_write_gpt() will truncate it as needed. */
block_count = 0xffffffff; block_count = 0xffffffff;
ret = iso_quick_gpt_entry(t, (uint32_t) 0, block_count, ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
(uint64_t) 0, ((uint64_t) block_count) * 4,
basic_data_uuid, zero_uuid, gpt_flags, basic_data_uuid, zero_uuid, gpt_flags,
(uint8_t *) gpt_name); (uint8_t *) gpt_name);
if (ret < 0) if (ret < 0)

View File

@ -515,6 +515,8 @@ const char *iso_error_to_msg(int errcode)
return "HP-PA PALO file is not a data file"; return "HP-PA PALO file is not a data file";
case ISO_HPPA_PALO_CMDLEN: case ISO_HPPA_PALO_CMDLEN:
return "HP-PA PALO command line too long"; return "HP-PA PALO command line too long";
case ISO_SYSAREA_PROBLEMS:
return "Problems encountered during inspection of System Area";
default: default:
return "Unknown error"; return "Unknown error";
} }

View File

@ -902,8 +902,10 @@ static int make_hppa_palo_sector(Ecma119Image *t, uint8_t *buf, int hdrversion,
/* Convenience frontend for iso_register_apm_entry(). /* Convenience frontend for iso_register_apm_entry().
name and type are 0-terminated strings. name and type are 0-terminated strings.
*/ */
int iso_quick_apm_entry(Ecma119Image *t, int iso_quick_apm_entry(struct iso_apm_partition_request **req_array,
uint32_t start_block, uint32_t block_count, char *name, char *type) int *apm_req_count,
uint32_t start_block, uint32_t block_count,
char *name, char *type)
{ {
int ret; int ret;
struct iso_apm_partition_request *entry; struct iso_apm_partition_request *entry;
@ -915,7 +917,7 @@ int iso_quick_apm_entry(Ecma119Image *t,
entry->block_count = block_count; entry->block_count = block_count;
strncpy((char *) entry->name, name, 32); strncpy((char *) entry->name, name, 32);
strncpy((char *) entry->type, type, 32); strncpy((char *) entry->type, type, 32);
ret = iso_register_apm_entry(t, entry, 0); ret = iso_register_apm_entry(req_array, apm_req_count, entry, 0);
free(entry); free(entry);
return ret; return ret;
} }
@ -924,8 +926,9 @@ int iso_quick_apm_entry(Ecma119Image *t,
/* Convenience frontend for iso_register_gpt_entry(). /* Convenience frontend for iso_register_gpt_entry().
name has to be already encoded as UTF-16LE. name has to be already encoded as UTF-16LE.
*/ */
int iso_quick_gpt_entry(Ecma119Image *t, int iso_quick_gpt_entry(struct iso_gpt_partition_request **req_array,
uint32_t start_block, uint32_t block_count, int *gpt_req_count,
uint64_t start_block, uint64_t block_count,
uint8_t type_guid[16], uint8_t partition_guid[16], uint8_t type_guid[16], uint8_t partition_guid[16],
uint64_t flags, uint8_t name[72]) uint64_t flags, uint8_t name[72])
{ {
@ -941,13 +944,14 @@ int iso_quick_gpt_entry(Ecma119Image *t,
memcpy(entry->partition_guid, partition_guid, 16); memcpy(entry->partition_guid, partition_guid, 16);
entry->flags = flags; entry->flags = flags;
memcpy(entry->name, name, 72); memcpy(entry->name, name, 72);
ret = iso_register_gpt_entry(t, entry, 0); ret = iso_register_gpt_entry(req_array, gpt_req_count, entry, 0);
free(entry); free(entry);
return ret; return ret;
} }
int iso_quick_mbr_entry(Ecma119Image *t, int iso_quick_mbr_entry(struct iso_mbr_partition_request **req_array,
int *mbr_req_count,
uint64_t start_block, uint64_t block_count, uint64_t start_block, uint64_t block_count,
uint8_t type_byte, uint8_t status_byte, uint8_t type_byte, uint8_t status_byte,
int desired_slot) int desired_slot)
@ -955,7 +959,7 @@ int iso_quick_mbr_entry(Ecma119Image *t,
int ret; int ret;
struct iso_mbr_partition_request *entry; struct iso_mbr_partition_request *entry;
ret = iso_mbr_entry_slot_is_free(t, desired_slot); ret = iso_mbr_entry_slot_is_free(req_array, *mbr_req_count, desired_slot);
if (ret < 0) if (ret < 0)
desired_slot = 0; desired_slot = 0;
else if (ret == 0) else if (ret == 0)
@ -969,13 +973,14 @@ int iso_quick_mbr_entry(Ecma119Image *t,
entry->type_byte = type_byte; entry->type_byte = type_byte;
entry->status_byte = status_byte; entry->status_byte = status_byte;
entry->desired_slot = desired_slot; entry->desired_slot = desired_slot;
ret = iso_register_mbr_entry(t, entry, 0); ret = iso_register_mbr_entry(req_array, mbr_req_count, entry, 0);
free(entry); free(entry);
return ret; return ret;
} }
int iso_mbr_entry_slot_is_free(Ecma119Image *t, int slot) int iso_mbr_entry_slot_is_free(struct iso_mbr_partition_request **req_array,
int mbr_req_count, int slot)
{ {
int i; int i;
@ -983,8 +988,8 @@ int iso_mbr_entry_slot_is_free(Ecma119Image *t, int slot)
return -1; return -1;
if (slot == 0) if (slot == 0)
return 1; return 1;
for (i = 0; i < t->mbr_req_count; i++) for (i = 0; i < mbr_req_count; i++)
if (t->mbr_req[i]->desired_slot == slot) if (req_array[i]->desired_slot == slot)
return 0; return 0;
return 1; return 1;
} }
@ -997,8 +1002,8 @@ static
int cmp_partition_request(const void *f1, const void *f2) int cmp_partition_request(const void *f1, const void *f2)
{ {
struct iso_partition_request { struct iso_partition_request {
uint32_t start_block; uint64_t start_block;
uint32_t block_count; uint64_t block_count;
} *r1, *r2; } *r1, *r2;
r1 = *((struct iso_partition_request **) f1); r1 = *((struct iso_partition_request **) f1);
@ -1046,10 +1051,10 @@ static int iso_write_apm_entry(Ecma119Image *t, int apm_block_size,
iso_msb(wpt, (uint32_t) map_entries, 4); iso_msb(wpt, (uint32_t) map_entries, 4);
wpt += 4; wpt += 4;
/* Physical block start of partition */ /* Physical block start of partition */
iso_msb(wpt, req->start_block * block_fac, 4); iso_msb(wpt, (uint32_t) (req->start_block * block_fac), 4);
wpt += 4; wpt += 4;
/* Physical block count of partition */ /* Physical block count of partition */
iso_msb(wpt, req->block_count * block_fac, 4); iso_msb(wpt, (uint32_t) (req->block_count * block_fac), 4);
wpt += 4; wpt += 4;
/* Partition name */ /* Partition name */
memcpy(wpt, req->name, 32); memcpy(wpt, req->name, 32);
@ -1058,10 +1063,10 @@ static int iso_write_apm_entry(Ecma119Image *t, int apm_block_size,
memcpy(wpt, req->type, 32); memcpy(wpt, req->type, 32);
wpt += 32; wpt += 32;
/* Logical block start */ /* Logical block start */
iso_msb(wpt, 0, 4); iso_msb(wpt, (uint32_t) 0, 4);
wpt += 4; wpt += 4;
/* Logical block count */ /* Logical block count */
iso_msb(wpt, req->block_count * block_fac, 4); iso_msb(wpt, (uint32_t) (req->block_count * block_fac), 4);
wpt += 4; wpt += 4;
/* Status flags : bit0= entry is valid , bit1= entry is allocated /* Status flags : bit0= entry is valid , bit1= entry is allocated
bit4= partition is readable , bit5= partition is writable bit4= partition is readable , bit5= partition is writable
@ -1103,7 +1108,8 @@ static int fill_apm_gaps(Ecma119Image *t, uint32_t img_blocks)
break; break;
} }
if (i >= t->apm_req_count) { if (i >= t->apm_req_count) {
ret = iso_quick_apm_entry(t, 1, 0, "Apple", "Apple_partition_map"); ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
1, 0, "Apple", "Apple_partition_map");
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
@ -1115,7 +1121,7 @@ static int fill_apm_gaps(Ecma119Image *t, uint32_t img_blocks)
up_to = t->apm_req_count + 1; up_to = t->apm_req_count + 1;
for (i = 1; i < up_to; i++) { for (i = 1; i < up_to; i++) {
if (i < up_to - 1) if (i < up_to - 1)
goal = t->apm_req[i]->start_block; goal = (uint32_t) t->apm_req[i]->start_block;
else else
goal = img_blocks * block_fac; goal = img_blocks * block_fac;
if (i == 1) { if (i == 1) {
@ -1141,7 +1147,8 @@ static int fill_apm_gaps(Ecma119Image *t, uint32_t img_blocks)
if (part_end < goal || i == up_to - 1) { /* Always add a final entry */ if (part_end < goal || i == up_to - 1) { /* Always add a final entry */
sprintf(gap_name, "Gap%d", gap_counter); sprintf(gap_name, "Gap%d", gap_counter);
gap_counter++; gap_counter++;
ret = iso_quick_apm_entry(t, part_end, goal - part_end, ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
part_end, goal - part_end,
gap_name, "ISO9660_data"); gap_name, "ISO9660_data");
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -1167,15 +1174,18 @@ static int rectify_apm(Ecma119Image *t)
/* <<< ts B20526 : Dummy mock-up */ /* <<< ts B20526 : Dummy mock-up */
if (t->apm_req_count <= 0) { if (t->apm_req_count <= 0) {
/* /*
ret = iso_quick_apm_entry(t, 16, 20, "Test1_name_16_20", "Test1_type"); ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
16, 20, "Test1_name_16_20", "Test1_type");
/ * >>> Caution: Size 90 causes intentional partition overlap error * / / * >>> Caution: Size 90 causes intentional partition overlap error * /
ret = iso_quick_apm_entry(t, 30, 90, "BAD_30_90_BAD", "Test1_type"); ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
30, 90, "BAD_30_90_BAD", "Test1_type");
*/ */
ret = iso_quick_apm_entry(t, 30, 20, "Test1_name_30_20", "Test1_type"); ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
30, 20, "Test1_name_30_20", "Test1_type");
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = iso_quick_apm_entry(t, 100, 400, "Test2_name_100_400", ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
"Test2_type"); 100, 400, "Test2_name_100_400", "Test2_type");
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
@ -1280,10 +1290,12 @@ static int iso_write_mbr(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
/* <<< Dummy mock-up */ /* <<< Dummy mock-up */
if (t->mbr_req_count <= 0) { if (t->mbr_req_count <= 0) {
ret = iso_quick_mbr_entry(t, (uint64_t) 0, (uint64_t) 0, 0xee, 0, 0); ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count),
(uint64_t) 0, (uint64_t) 0, 0xee, 0, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = iso_quick_mbr_entry(t, ((uint64_t) 100) * 4, (uint64_t) 0, ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count),
((uint64_t) 100) * 4, (uint64_t) 0,
0x0c, 0x80, 1); 0x0c, 0x80, 1);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -1491,8 +1503,8 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7
}; };
uint32_t p_arr_crc = 0, part_end, goal, next_end; uint32_t p_arr_crc = 0;
uint64_t start_lba, end_lba; uint64_t start_lba, end_lba, goal, part_end, next_end, backup_end_lba;
int ret, i, gap_counter = 0, up_to; int ret, i, gap_counter = 0, up_to;
struct iso_gpt_partition_request *req; struct iso_gpt_partition_request *req;
uint8_t gpt_name[72]; uint8_t gpt_name[72];
@ -1513,12 +1525,12 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
if (i < up_to - 1) { if (i < up_to - 1) {
goal = t->gpt_req[i]->start_block; goal = t->gpt_req[i]->start_block;
} else { } else {
goal = img_blocks; goal = ((uint64_t) img_blocks) * 4;
} }
if (i == 0) { if (i == 0) {
if (goal <= 16) if (goal <= 16 * 4)
continue; continue;
next_end = 16; next_end = 16 * 4;
} else { } else {
next_end = t->gpt_req[i - 1]->start_block + next_end = t->gpt_req[i - 1]->start_block +
t->gpt_req[i - 1]->block_count; t->gpt_req[i - 1]->block_count;
@ -1528,8 +1540,8 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
if (part_end > goal) { if (part_end > goal) {
if (!(t->gpt_req_flags & 1)) { if (!(t->gpt_req_flags & 1)) {
iso_msg_submit(t->image->id, ISO_BOOT_GPT_OVERLAP, 0, iso_msg_submit(t->image->id, ISO_BOOT_GPT_OVERLAP, 0,
"Program error: GPT partitions %d and %d overlap by %lu blocks", "Program error: GPT partitions %d and %d overlap by %.f blocks",
i - 1, i, part_end - goal); i - 1, i, (double) (part_end - goal));
return ISO_BOOT_GPT_OVERLAP; return ISO_BOOT_GPT_OVERLAP;
} }
} else if (part_end < goal) { } else if (part_end < goal) {
@ -1537,7 +1549,8 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
sprintf((char *) gpt_name, "Gap%d", gap_counter); sprintf((char *) gpt_name, "Gap%d", gap_counter);
iso_ascii_utf_16le(gpt_name); iso_ascii_utf_16le(gpt_name);
gap_counter++; gap_counter++;
ret = iso_quick_gpt_entry(t, part_end, goal - part_end, ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
part_end, goal - part_end,
basic_data_uuid, zero_uuid, basic_data_uuid, zero_uuid,
gpt_flags, gpt_name); gpt_flags, gpt_name);
if (ret < 0) if (ret < 0)
@ -1554,11 +1567,13 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
/* Write the GPT entries to buf */ /* Write the GPT entries to buf */
for (i = 0; i < t->gpt_req_count; i++) { for (i = 0; i < t->gpt_req_count; i++) {
req = t->gpt_req[i]; req = t->gpt_req[i];
start_lba = ((uint64_t) req->start_block) * 4; start_lba = req->start_block;
end_lba = ((uint64_t) req->start_block) + req->block_count; end_lba = req->start_block + req->block_count;
if (end_lba > t->gpt_backup_end - t->gpt_backup_size) backup_end_lba = ((uint64_t) t->gpt_backup_end - t->gpt_backup_size) *
end_lba = t->gpt_backup_end - t->gpt_backup_size; 4;
end_lba = end_lba * 4 - 1; if (end_lba > backup_end_lba)
end_lba = backup_end_lba;
end_lba = end_lba - 1;
iso_write_gpt_entry(t, buf + 512 * t->gpt_part_start + 128 * i, iso_write_gpt_entry(t, buf + 512 * t->gpt_part_start + 128 * i,
req->type_guid, req->partition_guid, req->type_guid, req->partition_guid,
start_lba, end_lba, req->flags, req->name); start_lba, end_lba, req->flags, req->name);
@ -1929,56 +1944,58 @@ ex:;
} }
int iso_register_apm_entry(Ecma119Image *t, int iso_register_apm_entry(struct iso_apm_partition_request **req_array,
int *apm_req_count,
struct iso_apm_partition_request *req, int flag) struct iso_apm_partition_request *req, int flag)
{ {
struct iso_apm_partition_request *entry; struct iso_apm_partition_request *entry;
if (t->apm_req_count >= ISO_APM_ENTRIES_MAX) if (*apm_req_count >= ISO_APM_ENTRIES_MAX)
return ISO_BOOT_TOO_MANY_APM; return ISO_BOOT_TOO_MANY_APM;
entry = calloc(1, sizeof(struct iso_apm_partition_request)); entry = calloc(1, sizeof(struct iso_apm_partition_request));
if (entry == NULL) if (entry == NULL)
return ISO_OUT_OF_MEM; return ISO_OUT_OF_MEM;
memcpy(entry, req, sizeof(struct iso_apm_partition_request)); memcpy(entry, req, sizeof(struct iso_apm_partition_request));
t->apm_req[t->apm_req_count] = entry; req_array[*apm_req_count] = entry;
t->apm_req_count++; (*apm_req_count)++;
return ISO_SUCCESS; return ISO_SUCCESS;
} }
int iso_register_mbr_entry(Ecma119Image *t, int iso_register_mbr_entry(struct iso_mbr_partition_request **req_array,
int *mbr_req_count,
struct iso_mbr_partition_request *req, int flag) struct iso_mbr_partition_request *req, int flag)
{ {
struct iso_mbr_partition_request *entry; struct iso_mbr_partition_request *entry;
if (t->mbr_req_count >= ISO_MBR_ENTRIES_MAX) if (*mbr_req_count >= ISO_MBR_ENTRIES_MAX)
return ISO_BOOT_TOO_MANY_MBR; return ISO_BOOT_TOO_MANY_MBR;
entry = calloc(1, sizeof(struct iso_mbr_partition_request)); entry = calloc(1, sizeof(struct iso_mbr_partition_request));
if (entry == NULL) if (entry == NULL)
return ISO_OUT_OF_MEM; return ISO_OUT_OF_MEM;
memcpy(entry, req, sizeof(struct iso_mbr_partition_request)); memcpy(entry, req, sizeof(struct iso_mbr_partition_request));
t->mbr_req[t->mbr_req_count] = entry; req_array[*mbr_req_count] = entry;
t->mbr_req_count++; (*mbr_req_count)++;
return ISO_SUCCESS; return ISO_SUCCESS;
} }
int iso_register_gpt_entry(struct iso_gpt_partition_request **req_array,
int iso_register_gpt_entry(Ecma119Image *t, int *gpt_req_count,
struct iso_gpt_partition_request *req, int flag) struct iso_gpt_partition_request *req, int flag)
{ {
struct iso_gpt_partition_request *entry; struct iso_gpt_partition_request *entry;
if (t->gpt_req_count >= ISO_GPT_ENTRIES_MAX) if (*gpt_req_count >= ISO_GPT_ENTRIES_MAX)
return ISO_BOOT_TOO_MANY_GPT; return ISO_BOOT_TOO_MANY_GPT;
entry = calloc(1, sizeof(struct iso_gpt_partition_request)); entry = calloc(1, sizeof(struct iso_gpt_partition_request));
if (entry == NULL) if (entry == NULL)
return ISO_OUT_OF_MEM; return ISO_OUT_OF_MEM;
memcpy(entry, req, sizeof(struct iso_gpt_partition_request)); memcpy(entry, req, sizeof(struct iso_gpt_partition_request));
t->gpt_req[t->gpt_req_count] = entry; req_array[*gpt_req_count] = entry;
t->gpt_req_count++; (*gpt_req_count)++;
return ISO_SUCCESS; return ISO_SUCCESS;
} }
@ -2185,19 +2202,26 @@ static int precompute_gpt(Ecma119Image *t)
strcpy((char *) gpt_name, "GPT Test 1"); strcpy((char *) gpt_name, "GPT Test 1");
iso_ascii_utf_16le(gpt_name); iso_ascii_utf_16le(gpt_name);
/* /*
ret = iso_quick_gpt_entry(t, 16, 20, hfs_uuid, zero_uuid, ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
gpt_flags, gpt_name); (uint64_t) (16 * 4), (uint64_t) (20 * 4),
hfs_uuid, zero_uuid, gpt_flags, gpt_name);
/ * Caution: Size 90 causes intentional partition overlap error * / / * Caution: Size 90 causes intentional partition overlap error * /
ret = iso_quick_gpt_entry(t, 30, 90, hfs_uuid, zero_uuid, ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
(uint64_t) (30 * 4), (uint64_t) (90 * 4),
hfs_uuid, zero_uuid,
gpt_flags, gpt_name); gpt_flags, gpt_name);
*/ */
ret = iso_quick_gpt_entry(t, 30, 40, hfs_uuid, zero_uuid, ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
(uint64_t) (30 * 4), (uint64_t) (40 * 4),
hfs_uuid, zero_uuid,
gpt_flags, gpt_name); gpt_flags, gpt_name);
if (ret < 0) if (ret < 0)
return ret; return ret;
strcpy((char *) gpt_name, "GPT Test 2"); strcpy((char *) gpt_name, "GPT Test 2");
iso_ascii_utf_16le(gpt_name); iso_ascii_utf_16le(gpt_name);
ret = iso_quick_gpt_entry(t, 110, 60, basic_data_uuid, zero_uuid, ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
(uint64_t) (110 * 4), (uint64_t) (60 * 4),
basic_data_uuid, zero_uuid,
gpt_flags, gpt_name); gpt_flags, gpt_name);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -2406,7 +2430,9 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
memset(gpt_name, 0, 72); memset(gpt_name, 0, 72);
strcpy((char *) gpt_name, "EFI boot partition"); strcpy((char *) gpt_name, "EFI boot partition");
iso_ascii_utf_16le(gpt_name); iso_ascii_utf_16le(gpt_name);
ret = iso_quick_gpt_entry(t, t->curblock, t->efi_boot_part_size, ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
((uint64_t) t->curblock) * 4,
((uint64_t) t->efi_boot_part_size) * 4,
efi_sys_uuid, zero_uuid, gpt_flags, gpt_name); efi_sys_uuid, zero_uuid, gpt_flags, gpt_name);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -2418,8 +2444,8 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
if (t->opts->prep_partition != NULL || t->opts->fat || will_have_gpt || if (t->opts->prep_partition != NULL || t->opts->fat || will_have_gpt ||
t->mbr_req_count > 0) t->mbr_req_count > 0)
return ISO_BOOT_MBR_OVERLAP; return ISO_BOOT_MBR_OVERLAP;
ret = iso_quick_mbr_entry(t, (uint64_t) 0, (uint64_t) 0, ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count),
0x96, 0x80, 0); (uint64_t) 0, (uint64_t) 0, 0x96, 0x80, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
return ISO_SUCCESS; return ISO_SUCCESS;
@ -2433,7 +2459,8 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
} }
if (t->prep_part_size > 0 || t->opts->fat || will_have_gpt) { if (t->prep_part_size > 0 || t->opts->fat || will_have_gpt) {
/* Protecting MBR entry for ISO start or whole ISO */ /* Protecting MBR entry for ISO start or whole ISO */
ret = iso_quick_mbr_entry(t, will_have_gpt ? (uint64_t) 1 : ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count),
will_have_gpt ? (uint64_t) 1 :
((uint64_t) t->opts->partition_offset) * 4, ((uint64_t) t->opts->partition_offset) * 4,
(uint64_t) 0, (uint64_t) 0,
will_have_gpt ? 0xee : 0xcd, 0, 0); will_have_gpt ? 0xee : 0xcd, 0, 0);
@ -2441,7 +2468,8 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
return ret; return ret;
} }
if (t->prep_part_size > 0) { if (t->prep_part_size > 0) {
ret = iso_quick_mbr_entry(t, ((uint64_t) t->curblock) * 4, ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count),
((uint64_t) t->curblock) * 4,
((uint64_t) t->prep_part_size) * 4, ((uint64_t) t->prep_part_size) * 4,
0x41, 0, 0); 0x41, 0, 0);
if (ret < 0) if (ret < 0)
@ -2450,8 +2478,8 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
} }
if (t->prep_part_size > 0 || t->opts->fat) { if (t->prep_part_size > 0 || t->opts->fat) {
/* FAT partition or protecting MBR entry for ISO end */ /* FAT partition or protecting MBR entry for ISO end */
ret = iso_quick_mbr_entry(t, ((uint64_t) t->curblock) * 4, ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count),
(uint64_t) 0, ((uint64_t) t->curblock) * 4, (uint64_t) 0,
t->opts->fat ? 0x0c : 0xcd, 0, 0); t->opts->fat ? 0x0c : 0xcd, 0, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;

View File

@ -108,13 +108,15 @@ struct iso_mbr_partition_request {
I.e. after the call the submitted storage of req can be disposed or re-used. I.e. after the call the submitted storage of req can be disposed or re-used.
Submit 0 as value flag. Submit 0 as value flag.
*/ */
int iso_register_mbr_entry(Ecma119Image *t, int iso_register_mbr_entry(struct iso_mbr_partition_request **req_array,
int *mbr_req_count,
struct iso_mbr_partition_request *req, int flag); struct iso_mbr_partition_request *req, int flag);
/* Convenience frontend for iso_register_mbr_entry(). /* Convenience frontend for iso_register_mbr_entry().
name and type are 0-terminated strings, which may get silently truncated. name and type are 0-terminated strings, which may get silently truncated.
*/ */
int iso_quick_mbr_entry(Ecma119Image *t, int iso_quick_mbr_entry(struct iso_mbr_partition_request **req_array,
int *mbr_req_count,
uint64_t start_block, uint64_t block_count, uint64_t start_block, uint64_t block_count,
uint8_t type_byte, uint8_t status_byte, uint8_t type_byte, uint8_t status_byte,
int desired_slot); int desired_slot);
@ -125,12 +127,13 @@ int iso_quick_mbr_entry(Ecma119Image *t,
Return value is 0 if occupied, 1 if free, and -1 if the slot number is Return value is 0 if occupied, 1 if free, and -1 if the slot number is
out of range. out of range.
*/ */
int iso_mbr_entry_slot_is_free(Ecma119Image *t, int slot); int iso_mbr_entry_slot_is_free(struct iso_mbr_partition_request **req_array,
int mbr_req_count, int slot);
/* The parameter struct for production of a single Apple Partition Map entry. /* The parameter struct for production of a single Apple Partition Map entry.
See also the partial APM description in doc/boot_sectors.txt. See also the partial APM description in doc/boot_sectors.txt.
The list of entries is stored in Ecma119Image.apm_req. The list of entries is stored e.g. in Ecma119Image.apm_req, .apm_req_count.
The size of a block can be chosen by setting Ecma119Image.apm_block_size. The size of a block can be chosen by setting Ecma119Image.apm_block_size.
If an entry has start_block <=1, then its block_count will be adjusted If an entry has start_block <=1, then its block_count will be adjusted
to the final size of the partition map. to the final size of the partition map.
@ -144,8 +147,8 @@ struct iso_apm_partition_request {
/* Given in blocks of 2 KiB unless (Ecma119Image.apm_req_flags & 4). /* Given in blocks of 2 KiB unless (Ecma119Image.apm_req_flags & 4).
Written to the ISO image according to Ecma119Image.apm_block_size. Written to the ISO image according to Ecma119Image.apm_block_size.
*/ */
uint32_t start_block; uint64_t start_block;
uint32_t block_count; uint64_t block_count;
/* All 32 bytes get copied to the system area. /* All 32 bytes get copied to the system area.
Take care to pad up short strings by 0. Take care to pad up short strings by 0.
@ -158,14 +161,17 @@ struct iso_apm_partition_request {
I.e. after the call the submitted storage of req can be disposed or re-used. I.e. after the call the submitted storage of req can be disposed or re-used.
Submit 0 as value flag. Submit 0 as value flag.
*/ */
int iso_register_apm_entry(Ecma119Image *t, int iso_register_apm_entry(struct iso_apm_partition_request **req_array,
int *apm_req_count,
struct iso_apm_partition_request *req, int flag); struct iso_apm_partition_request *req, int flag);
/* Convenience frontend for iso_register_apm_entry(). /* Convenience frontend for iso_register_apm_entry().
name and type are 0-terminated strings, which may get silently truncated. name and type are 0-terminated strings, which may get silently truncated.
*/ */
int iso_quick_apm_entry(Ecma119Image *t, int iso_quick_apm_entry(struct iso_apm_partition_request **req_array,
uint32_t start_block, uint32_t block_count, char *name, char *type); int *apm_req_count,
uint32_t start_block, uint32_t block_count,
char *name, char *type);
/* CRC-32 as of GPT and Ethernet. /* CRC-32 as of GPT and Ethernet.
@ -206,11 +212,10 @@ void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16]);
*/ */
struct iso_gpt_partition_request { struct iso_gpt_partition_request {
/* Always given in blocks of 2 KiB. /* Always given in blocks of 512 bytes.
Written to the ISO image in blocks of 512.
*/ */
uint32_t start_block; uint64_t start_block;
uint32_t block_count; uint64_t block_count;
/* The registered GUID which defines the partition type */ /* The registered GUID which defines the partition type */
uint8_t type_guid[16]; uint8_t type_guid[16];
@ -231,20 +236,26 @@ struct iso_gpt_partition_request {
Take care to pad up short strings by 0. Take care to pad up short strings by 0.
*/ */
uint8_t name[72]; uint8_t name[72];
/* Only if read from imported image: Table index of partition (first = 1)
*/
uint32_t idx;
}; };
/* Copies the content of req and registers it in t.gpt_req[]. /* Copies the content of req and registers it in t.gpt_req[].
I.e. after the call the submitted storage of req can be disposed or re-used. I.e. after the call the submitted storage of req can be disposed or re-used.
Submit 0 as value flag. Submit 0 as value flag.
*/ */
int iso_register_gpt_entry(Ecma119Image *t, int iso_register_gpt_entry(struct iso_gpt_partition_request **req_array,
int *gpt_req_count,
struct iso_gpt_partition_request *req, int flag); struct iso_gpt_partition_request *req, int flag);
/* Convenience frontend for iso_register_gpt_entry(). /* Convenience frontend for iso_register_gpt_entry().
name has to be already encoded as UTF-16LE. name has to be already encoded as UTF-16LE.
*/ */
int iso_quick_gpt_entry(Ecma119Image *t, int iso_quick_gpt_entry(struct iso_gpt_partition_request **req_array,
uint32_t start_block, uint32_t block_count, int *gpt_req_count,
uint64_t start_block, uint64_t block_count,
uint8_t type_guid[16], uint8_t partition_guid[16], uint8_t type_guid[16], uint8_t partition_guid[16],
uint64_t flags, uint8_t name[72]); uint64_t flags, uint8_t name[72]);
@ -255,6 +266,23 @@ int iso_write_gpt_header_block(Ecma119Image *t, uint32_t img_blocks,
uint8_t *buf, uint32_t max_entries, uint8_t *buf, uint32_t max_entries,
uint32_t part_start, uint32_t p_arr_crc); uint32_t part_start, uint32_t p_arr_crc);
/* The description of a loaded MIPS Big Endian Volume Directory Entry
*/
struct iso_mips_voldir_entry {
char name[9];
uint32_t boot_block;
uint32_t boot_bytes;
};
/* The description of a loaded SUN Disk Label partition */
struct iso_sun_disk_label_entry {
int idx;
uint16_t id_tag;
uint16_t permissions;
uint32_t start_cyl;
uint32_t num_blocks;
};
/* Creates the Partition Prepend writer. /* Creates the Partition Prepend writer.
*/ */
int partprepend_writer_create(Ecma119Image *target); int partprepend_writer_create(Ecma119Image *target);

View File

@ -1187,6 +1187,55 @@ ex:;
return path; return path;
} }
/* Note: No reference is taken to the found node.
@param flag bit0= recursion
*/
int iso_tree_get_node_of_block(IsoImage *image, IsoDir *dir, uint32_t block,
IsoNode **found, int flag)
{
int ret, section_count, i;
IsoDirIter *iter = NULL;
IsoNode *node;
IsoDir *subdir;
IsoFile *file;
struct iso_file_section *sections = NULL;
if (dir == NULL)
dir = image->root;
ret = iso_dir_get_children(dir, &iter);
while (iso_dir_iter_next(iter, &node) == 1 ) {
if (ISO_NODE_IS_FILE(node)) {
file = (IsoFile *) node;
ret = iso_file_get_old_image_sections(file, &section_count,
&sections, 0);
if (ret <= 0)
continue;
for (i = 0; i < section_count; i++) {
if (sections[i].block <= block &&
block - sections[i].block <
(((off_t) sections[i].size) + 2047) / 2048) {
*found = node;
ret = 1; goto ex;
}
}
free(sections); sections = NULL;
} else if (ISO_NODE_IS_DIR(node)) {
subdir = (IsoDir *) node;
ret = iso_tree_get_node_of_block(image, subdir, block, found, 1);
if (ret != 0)
goto ex;
}
}
ret = 0;
ex:
if (sections != NULL)
free(sections);
return ret;
}
/* ------------------------- tree cloning ------------------------------ */ /* ------------------------- tree cloning ------------------------------ */
static static

View File

@ -19,4 +19,9 @@
*/ */
int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir); int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir);
int iso_tree_get_node_of_block(IsoImage *image, IsoDir *dir, uint32_t block,
IsoNode **found, int flag);
#endif /*LIBISO_IMAGE_TREE_H_*/ #endif /*LIBISO_IMAGE_TREE_H_*/

View File

@ -1534,6 +1534,26 @@ uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error)
return v1; return v1;
} }
uint64_t iso_read_lsb64(const uint8_t *buf)
{
int i;
uint64_t ret = 0;
for (i=0; i < 8; i++)
ret += ((uint64_t) buf[i]) << (i * 8);
return ret;
}
uint64_t iso_read_msb64(const uint8_t *buf)
{
int i;
uint64_t ret = 0;
for (i=0; i < 8; i++)
ret += ((uint64_t) buf[7 - i]) << (i * 8);
return ret;
}
void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt) void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt)
{ {
static int tzsetup = 0; static int tzsetup = 0;
@ -2011,6 +2031,17 @@ int iso_util_dec_to_uint32(char *dec, uint32_t *value, int flag)
} }
int iso_util_bin_to_hex(char *target, uint8_t *bytes, int num_bytes, int flag)
{
int i;
for (i = 0; i < num_bytes; i++)
sprintf(target + 2 * i, "%-2.2x", bytes[i]);
target[2 * num_bytes] = 0;
return 1;
}
int iso_util_hex_to_bin(char *hex, char *bin, int bin_size, int *bin_count, int iso_util_hex_to_bin(char *hex, char *bin, int bin_size, int *bin_count,
int flag) int flag)
{ {

View File

@ -273,6 +273,9 @@ uint32_t iso_read_msb(const uint8_t *buf, int bytes);
*/ */
uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error); uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error);
uint64_t iso_read_lsb64(const uint8_t *buf);
uint64_t iso_read_msb64(const uint8_t *buf);
/** /**
* Records the date/time into a 7 byte buffer (ECMA-119, 9.1.5) * Records the date/time into a 7 byte buffer (ECMA-119, 9.1.5)
* *
@ -544,6 +547,12 @@ int iso_util_eval_md5_tag(char *block, int desired, uint32_t lba,
int iso_util_tag_magic(int tag_type, char **tag_magic, int *len, int flag); int iso_util_tag_magic(int tag_type, char **tag_magic, int *len, int flag);
int iso_util_bin_to_hex(char *target, uint8_t *bytes, int num_bytes, int flag);
int iso_util_hex_to_bin(char *hex, char *bin, int bin_size, int *bin_count,
int flag);
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* In md5.h these function prototypes would be neighbors of (Ecma119Image *) /* In md5.h these function prototypes would be neighbors of (Ecma119Image *)