Compare commits

...

13 Commits

Author SHA1 Message Date
84132ec7bf Version leap to 0.6.32 2010-05-03 14:34:36 +02:00
eb23260459 Removed most of the development remarks of 0.6.31 2010-05-01 20:38:01 +02:00
4978424328 Corrected calls of functions iso_lsb(), iso_msb(), iso_bb() which used
integer types other than uint32_t.
2010-04-30 11:36:14 +02:00
e4cf93665a Making an educated guess whether the boot images contain a boot info table.
New API call el_torito_seems_boot_info_table() publishes this guess.
2010-04-29 15:10:18 +02:00
3d9367d52a Closed memory leak about boot catalog node. 2010-04-25 20:27:17 +02:00
03b030c56d New API calls el_torito_get_isolinux_options(), el_torito_get_boot_media_type() 2010-04-25 14:11:45 +02:00
a3fe82100b Fixed a bug introduced with previous revision 655. 2010-04-23 19:00:50 +02:00
02d7a690eb New API calls el_torito_set_id_string(), el_torito_get_id_string(),
el_torito_set_selection_crit(), el_torito_get_selection_crit().
2010-04-23 18:01:27 +02:00
ace0d1ab2e Bug fix of previous revision 653:
SIGSEGV because of dereferencing NULL when writing without boot image.
2010-04-22 23:13:54 +02:00
59d143c1f0 Added support for multiple boot images.
New API calls iso_image_add_boot_image() , iso_image_get_all_boot_imgs(),
el_torito_get_boot_platform_id(), el_torito_get_load_seg(),
el_torito_get_load_size(), el_torito_get_bootable()
2010-04-22 14:04:51 +02:00
da2c0520cc Changed new API call from iso_image_set_boot_platform_id() to
el_torito_set_boot_platform_id().
Introduced new API call iso_image_set_boot_catalog_weight().
2010-04-20 16:23:17 +02:00
517f520570 New API call iso_image_set_boot_platform_id().
Downgraded ISO_WRONG_EL_TORITO and ISO_UNSUPPORTED_EL_TORITO from SORRY
to WARN and implemented the tolerance that is promised by their message
texts.
2010-04-20 11:10:00 +02:00
98d2b4c996 Version leap to 0.6.31 2010-04-17 13:23:49 +02:00
15 changed files with 1006 additions and 254 deletions

101
README
View File

@ -7,6 +7,39 @@ Released under GPL (see COPYING file for details).
Copyright (C) 2008 - 2010 Vreixo Formoso, Mario Danic, Thomas Schmitt
libisofs is part of the libburnia project (libburnia-project.org)
------------------------------------------------------------------------------
Download, Build and Installation
libisofs code is mantained in a Bazaar repository at Launchpad
(https://launchpad.net/libisofs/). You can download it with:
$ bzr branch lp:libisofs/for-libisoburn
Our build system is based on autotools. For preparing the build you will need
autotools of at least version 1.7. If you have download the code from the
repository, first of all you need to execute
./autogen.sh
on toplevel dir to execute autotools.
Alternatively you may unpack a release tarball for which you do not need
autotools installed. For the most recent release of libisofs see:
http://libburnia-project.org/wiki/Releases
To build libisofs it should be sufficient to go into its toplevel directory
and execute
./configure --prefix=/usr
make
To make the libraries accessible for running resp. developing applications
make install
See INSTALL file for further details.
------------------------------------------------------------------------------
libisofs is a library to create an ISO-9660 filesystem, supports extensions
@ -23,7 +56,7 @@ Features:
- Creates ISO-9660 images from local files.
- Support for RockRidge and Joliet extensions.
- Support for ISO-9660:1999 (version 2).
- Support for El-Torito bootable images.
- Support for El-Torito bootable images. Tested are: PC-BIOS and EFI.
- Support for multi-extent data files up to 400 GB (level 3).
- Full-featured edition of the image files, including: addition of new
files, removing of existent files, moving files, renaming files,
@ -67,8 +100,9 @@ Features:
Requirements:
-------------
- libburn 0.4.2 headers must be installed at compile time. It is not required
at runtime.
- iconv() functions for character set conversion must be available.
Either implicitely as in Linux or by a separate library like libiconv
on FreeBSD.
Know bugs:
----------
@ -78,12 +112,12 @@ Multisession and image growing can lead to undesired results in several cases:
a) Images with unsupported features, such as:
- UDF.
- HSF/HFS+ or other Mac extensions.
- El-Torito with multiple entries.
- ECMA-119 with extended attributes.
- ECMA-119 Extended attributes.
- Non El-Torito boot info.
- ...
In all these cases, the resulting new image (or new session) could lack some
features of the original image.
features of the original image. Nevertheless, the ECMA-119 System Area with
an eventual Master Boot Record gets preserved by default.
In some cases libisofs will issue warning messages, or even refuse to grow
or modify the image. Others remain undetected. Images created with libisofs
do not have this problems.
@ -93,16 +127,19 @@ b) Bootable El-Torito images may have several problems, that result in a new
cases it is recommended to add boot info again in the new session.
- isolinux images won't be bootable after a modify. This is because
isolinux images need to have hardcoded the root dir lba. libisofs cannot
know whether an image is an isolinux image or not, so the user is
responsible to tell libisofs that it must patch the image, with the
el_torito_patch_isolinux_image() function. This problem could also exists
on other boot images.
- Most boot images are highly dependent of the image contents, so if the
user moves or removes some files on image it is possible they won't boot
anymore.
- There is no safer way to modify hidden boot images, as the size of the
boot image can't be figured out.
isolinux images need to have hardcoded the root dir lba in their boot
information table.
libisofs makes an educated guess at load time whether a boot image
contains such a table. Its outcome can be inquired by call
el_torito_seems_boot_info_table().
If one knows to have isolinux or GRUB El-Torito-bootable images, or if
a boot information table seems to exist, it is advised to apply the
el_torito_patch_isolinux_image() function.
Most boot images are highly dependent of the image contents, so if the
user moves or removes some files on image it is possible they won't boot
anymore.
- There is no safe way to modify hidden boot images, as the size of the
boot image can't be figured out.
c) Generated images could have different ECMA-119 low level names, due to
different way to mangle names, to new files added that force old files to
@ -113,38 +150,6 @@ c) Generated images could have different ECMA-119 low level names, due to
relaxed contraints), otherwise libisofs might arbitrarily change the names.
------------------------------------------------------------------------------
Download, Build and Installation
libisofs code is mantained in a Bazaar repository at Launchpad
(https://launchpad.net/libisofs/). You can download it with:
$ bzr branch lp:libisofs
Our build system is based on autotools. For preparing the build you will need
autotools of at least version 1.7. If you have download the code from the
repository, first of all you need to execute
./autogen.sh
on toplevel dir to execute autotools.
Alternatively you may unpack a release tarball for which you do not need
autotools installed.
To build libisofs it should be sufficient to go into its toplevel directory
and execute
./configure --prefix=/usr
make
To make the libraries accessible for running resp. developing applications
make install
See INSTALL file for further details.
------------------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [0.6.30], [http://libburnia-project.org])
AC_INIT([libisofs], [0.6.32], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -46,7 +46,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=0
LIBISOFS_MINOR_VERSION=6
LIBISOFS_MICRO_VERSION=30
LIBISOFS_MICRO_VERSION=32
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -56,10 +56,10 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2010.04.17 development jump has not yet happened
# SONAME = 32 - 26 = 6 . Library name = libisofs.6.26.0
LT_CURRENT=32
LT_AGE=26
# 2010.05.03 development jump has not yet happened
# SONAME = 34 - 28 = 6 . Library name = libisofs.6.28.0
LT_CURRENT=34
LT_AGE=28
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`

View File

@ -20,7 +20,7 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
#ifndef PATH_MAX
#define PATH_MAX Libisofs_default_path_maX
@ -100,7 +100,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoNode *new;
IsoFilesystem *fs;
char *name;
unsigned char *aa_string;
unsigned char *aa_string = NULL;
char *a_text = NULL, *d_text = NULL;
if (builder == NULL || src == NULL || node == NULL) {
@ -217,6 +217,9 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
}
iso_aa_get_acl_text(aa_string, info.st_mode, &a_text, &d_text,
1 << 15); /* free ACL texts */
if(aa_string != NULL)
free(aa_string);
aa_string = NULL;
}
/* Obtain ownership of eventual AAIP string */
@ -227,6 +230,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
if (ret < 0)
return ret;
} else if(aa_string != NULL) {
free(aa_string);
}
*node = new;

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2010 Thomas Schmitt
*
* 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
@ -72,7 +72,8 @@ void ecma119_image_free(Ecma119Image *t)
free(t->input_charset);
if (t->output_charset != NULL)
free(t->output_charset);
if (t->bootsrc != NULL)
free(t->bootsrc);
if (t->system_area_data != NULL)
free(t->system_area_data);
@ -342,7 +343,7 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
}
rec->flags[0] = ((node->type == ECMA119_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
iso_bb(rec->vol_seq_number, 1, 2);
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
rec->len_fi[0] = len_fi;
/*
@ -420,9 +421,9 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
strncpy_pad((char*)vol.system_id, system_id, 32);
strncpy_pad((char*)vol.volume_id, vol_id, 32);
iso_bb(vol.vol_space_size, t->vol_space_size, 4);
iso_bb(vol.vol_set_size, 1, 2);
iso_bb(vol.vol_seq_number, 1, 2);
iso_bb(vol.block_size, BLOCK_SIZE, 2);
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
iso_bb(vol.path_table_size, t->path_table_size, 4);
iso_lsb(vol.l_path_table_pos, t->l_path_table_pos, 4);
iso_msb(vol.m_path_table_pos, t->m_path_table_pos, 4);
@ -1166,6 +1167,20 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
/* el-torito? */
target->eltorito = (src->bootcat == NULL ? 0 : 1);
target->catalog = src->bootcat;
if (target->catalog != NULL) {
target->num_bootsrc = target->catalog->num_bootimages;
target->bootsrc = calloc(target->num_bootsrc + 1,
sizeof(IsoFileSrc *));
if (target->bootsrc == NULL) {
ret = ISO_OUT_OF_MEM;
goto target_cleanup;
}
for (i= 0; i < target->num_bootsrc; i++)
target->bootsrc[i] = NULL;
} else {
target->num_bootsrc = 0;
target->bootsrc = NULL;
}
if (opts->system_area_data != NULL) {
system_area = opts->system_area_data;

View File

@ -454,7 +454,9 @@ struct ecma119_image
*/
struct el_torito_boot_catalog *catalog;
IsoFileSrc *cat; /**< location of the boot catalog in the new image */
IsoFileSrc *bootimg; /**< location of the boot image in the new image */
int num_bootsrc;
IsoFileSrc **bootsrc; /* location of the boot images in the new image */
/*
* System Area related information

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 Thomas Schmitt
*
* 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
@ -17,9 +18,10 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/**
* This table should be written with accuracy values at offset
* This table should be written with the actual values at offset
* 8 of boot image, when used ISOLINUX boot loader
*/
struct boot_info_table {
@ -55,6 +57,19 @@ struct hard_disc_mbr {
uint8_t sign2;
};
/* API */
int el_torito_set_boot_platform_id(ElToritoBootImage *bootimg, uint8_t id)
{
bootimg->platform_id = id;
return 1;
}
/* API */
int el_torito_get_boot_platform_id(ElToritoBootImage *bootimg)
{
return bootimg->platform_id;
}
/**
* 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.
@ -66,6 +81,14 @@ void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment)
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;
}
/**
* Sets the number of sectors (512b) to be load at load segment during
* the initial boot procedure. This is only for no emulation boot images,
@ -78,6 +101,14 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors)
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;
}
/**
* Marks the specified boot image as not bootable
*/
@ -86,8 +117,50 @@ void el_torito_set_no_bootable(ElToritoBootImage *bootimg)
bootimg->bootable = 0;
}
/* API */
int el_torito_get_bootable(ElToritoBootImage *bootimg)
{
return !!bootimg->bootable;
}
/* API */
int el_torito_set_id_string(ElToritoBootImage *bootimg, uint8_t id_string[28])
{
memcpy(bootimg->id_string, id_string, 28);
return 1;
}
/* API */
int el_torito_get_id_string(ElToritoBootImage *bootimg, uint8_t id_string[28])
{
memcpy(id_string, bootimg->id_string, 28);
return 1;
}
/* API */
int el_torito_set_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20])
{
memcpy(bootimg->selection_crit, crit, 20);
return 1;
}
/* API */
int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20])
{
memcpy(crit, bootimg->selection_crit, 20);
return 1;
}
/* API */
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag)
{
return bootimg->seems_boot_info_table;
}
/**
* Specifies that this image needs to be patched. This involves the writting
* Specifies that this image needs to be patched. This involves the writing
* of a 56 bytes boot information table at offset 8 of the boot image file.
* The original boot image file won't be modified.
* This is needed for isolinux boot images.
@ -106,7 +179,7 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg)
* bitmask style flag. The following values are defined:
*
* bit 0 -> 1 to path the image, 0 to not
* Patching the image involves the writting of a 56 bytes
* Patching the image involves the writing of a 56 bytes
* boot information table at offset 8 of the boot image file.
* The original boot image file won't be modified. This is needed
* to allow isolinux images to be bootable.
@ -124,31 +197,36 @@ int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int
return ISO_SUCCESS;
}
/* TODO getter for boot image properties should be exposed
* useful when reading discs */
int el_torito_get_boot_media_type(const ElToritoBootImage *bootimg)
/* API */
int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag)
{
return bootimg->isolinux_options & 0x03;
}
/* API */
int el_torito_get_boot_media_type(ElToritoBootImage *bootimg,
enum eltorito_boot_media_type *media_type)
{
if (bootimg) {
switch (bootimg->type) {
case 1:
case 2:
case 3:
return ELTORITO_FLOPPY_EMUL;
break;
*media_type = ELTORITO_FLOPPY_EMUL;
return 1;
case 4:
return ELTORITO_HARD_DISC_EMUL;
break;
*media_type = ELTORITO_HARD_DISC_EMUL;
return 1;
case 0:
return ELTORITO_NO_EMUL;
break;
*media_type = ELTORITO_NO_EMUL;
return 1;
default:
/* should never happen */
return ISO_ASSERT_FAILURE;
break;
}
} else {
return ISO_WRONG_ARG_VALUE;
}
return ISO_WRONG_ARG_VALUE;
}
static
@ -333,12 +411,15 @@ int create_image(IsoImage *image, const char *image_path,
boot->image = (IsoFile*)imgfile;
iso_node_ref(imgfile); /* get our ref */
boot->bootable = 1;
boot->seems_boot_info_table = 0;
boot->isolinux_options = 0;
boot->type = boot_media_type;
boot->partition_type = partition_type;
boot->load_seg = 0;
boot->load_size = load_sectors;
boot->platform_id = 0; /* 80x86 */
memset(boot->id_string, 0, sizeof(boot->id_string));
memset(boot->selection_crit, 0, sizeof(boot->selection_crit));
if (bootimg) {
*bootimg = boot;
}
@ -351,7 +432,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
const char *catalog_path,
ElToritoBootImage **boot)
{
int ret;
int ret, i;
struct el_torito_boot_catalog *catalog;
ElToritoBootImage *boot_image= NULL;
IsoBoot *cat_node= NULL;
@ -415,8 +496,12 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
ret = ISO_OUT_OF_MEM;
goto boot_image_cleanup;
}
catalog->image = boot_image;
catalog->num_bootimages = 1;
catalog->bootimages[0] = boot_image;
for (i = 1; i < Libisofs_max_boot_imageS; i++)
catalog->bootimages[i] = NULL;
catalog->node = cat_node;
catalog->sort_weight = 1000; /* slightly high */
iso_node_ref((IsoNode*)cat_node);
image->bootcat = catalog;
@ -439,7 +524,7 @@ boot_image_cleanup:;
}
/**
* Get El-Torito boot image of an ISO image, if any.
* Get the boot catalog and the El-Torito default boot image of an ISO image.
*
* This can be useful, for example, to check if a volume read from a previous
* session or an existing image is bootable. It can also be useful to get
@ -483,10 +568,10 @@ int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
/* ok, image is bootable */
if (boot) {
*boot = image->bootcat->image;
*boot = image->bootcat->bootimages[0];
}
if (imgnode) {
*imgnode = image->bootcat->image->image;
*imgnode = image->bootcat->bootimages[0]->image;
}
if (catnode) {
*catnode = image->bootcat->node;
@ -494,6 +579,40 @@ int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
return ISO_SUCCESS;
}
int iso_image_get_all_boot_imgs(IsoImage *image, int *num_boots,
ElToritoBootImage ***boots, IsoFile ***bootnodes, int flag)
{
int i;
struct el_torito_boot_catalog *cat;
if (image == NULL)
return ISO_NULL_POINTER;
if (image->bootcat == NULL)
return 0;
cat = image->bootcat;
*num_boots = cat->num_bootimages;
*boots = NULL;
*bootnodes = NULL;
if (*num_boots <= 0)
return 0;
*boots = calloc(*num_boots, sizeof(ElToritoBootImage *));
*bootnodes = calloc(*num_boots, sizeof(IsoFile *));
if(*boots == NULL || *bootnodes == NULL) {
if (*boots != NULL)
free(*boots);
if (*bootnodes != NULL)
free(*bootnodes);
*boots = NULL;
*bootnodes = NULL;
return ISO_OUT_OF_MEM;
}
for (i = 0; i < *num_boots; i++) {
(*boots)[i] = cat->bootimages[i];
(*bootnodes)[i] = image->bootcat->bootimages[i]->image;
}
return 1;
}
/**
* Removes the El-Torito bootable image.
*
@ -508,28 +627,68 @@ void iso_image_remove_boot_image(IsoImage *image)
return;
/*
* remove catalog node from its parent
* (the reference will be disposed next)
* remove catalog node from its parent and dispose it
* (another reference is with the catalog)
*/
iso_node_take((IsoNode*)image->bootcat->node);
if (iso_node_get_parent((IsoNode*) image->bootcat->node) != NULL) {
iso_node_take((IsoNode*) image->bootcat->node);
iso_node_unref((IsoNode*) image->bootcat->node);
}
/* free boot catalog and image, including references to nodes */
el_torito_boot_catalog_free(image->bootcat);
image->bootcat = NULL;
}
/* API */
int iso_image_add_boot_image(IsoImage *image, const char *image_path,
enum eltorito_boot_media_type type, int flag,
ElToritoBootImage **boot)
{
int ret;
struct el_torito_boot_catalog *catalog = image->bootcat;
ElToritoBootImage *boot_img;
if (catalog->num_bootimages >= Libisofs_max_boot_imageS)
return ISO_BOOT_IMAGE_OVERFLOW;
ret = create_image(image, image_path, type, &boot_img);
if (ret < 0)
return ret;
catalog->bootimages[catalog->num_bootimages] = boot_img;
catalog->num_bootimages++;
if (boot != NULL)
*boot = boot_img;
return 1;
}
/* API */
int iso_image_set_boot_catalog_weight(IsoImage *image, int sort_weight)
{
if (image->bootcat == NULL)
return 0;
image->bootcat->sort_weight = sort_weight;
return 1;
}
void el_torito_boot_catalog_free(struct el_torito_boot_catalog *cat)
{
struct el_torito_boot_image *image;
int i;
if (cat == NULL) {
return;
}
image = cat->image;
iso_node_unref((IsoNode*)image->image);
free(image);
iso_node_unref((IsoNode*)cat->node);
for (i = 0; i < Libisofs_max_boot_imageS; i++) {
image = cat->bootimages[i];
if (image == NULL)
continue;
if ((IsoNode*)image->image != NULL)
iso_node_unref((IsoNode*)image->image);
free(image);
}
if ((IsoNode*)cat->node != NULL)
iso_node_unref((IsoNode*)cat->node);
free(cat);
}
@ -540,11 +699,12 @@ struct catalog_stream
{
Ecma119Image *target;
uint8_t buffer[BLOCK_SIZE];
int offset; /* -1 if stream is not openned */
int offset; /* -1 if stream is not opened */
};
static void
write_validation_entry(uint8_t *buf)
write_validation_entry(uint8_t *buf, uint8_t platform_id,
uint8_t id_string[24])
{
size_t i;
int checksum;
@ -552,10 +712,10 @@ write_validation_entry(uint8_t *buf)
struct el_torito_validation_entry *ve =
(struct el_torito_validation_entry*)buf;
ve->header_id[0] = 1;
ve->platform_id[0] = 0; /* 0: 80x86, 1: PowerPC, 2: Mac */
ve->platform_id[0] = platform_id;
memcpy(ve->id_string, id_string, sizeof(ve->id_string));
ve->key_byte1[0] = 0x55;
ve->key_byte2[0] = 0xAA;
/* calculate the checksum, to ensure sum of all words is 0 */
checksum = 0;
for (i = 0; i < sizeof(struct el_torito_validation_entry); i += 2) {
@ -564,35 +724,64 @@ write_validation_entry(uint8_t *buf)
iso_lsb(ve->checksum, checksum, 2);
}
static void
write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
{
int pi;
char *id_string;
struct el_torito_section_header *e =
(struct el_torito_section_header *) buf;
/* 0x90 = more section headers follow , 0x91 = final section */
e->header_indicator[0] = 0x90 + (idx == t->catalog->num_bootimages - 1);
pi= e->platform_id[0] = t->catalog->bootimages[idx]->platform_id;
e->num_entries[0] = num_entries & 0xff;
e->num_entries[1] = (num_entries >> 8) & 0xff;;
id_string = (char *) e->id_string;
memcpy(id_string, t->catalog->bootimages[idx]->id_string,
sizeof(e->id_string));
}
/**
* Write one section entry.
* Currently this is used only for default image (the only supported just now)
* Usable for the Default Entry
* and for Section Entries with Selection criteria type == 0
*/
static void
write_section_entry(uint8_t *buf, Ecma119Image *t)
write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
{
struct el_torito_boot_image *img;
struct el_torito_section_entry *se =
(struct el_torito_section_entry*)buf;
img = t->catalog->image;
img = t->catalog->bootimages[idx];
se->boot_indicator[0] = img->bootable ? 0x88 : 0x00;
se->boot_media_type[0] = img->type;
iso_lsb(se->load_seg, img->load_seg, 2);
se->system_type[0] = img->partition_type;
iso_lsb(se->sec_count, img->load_size, 2);
iso_lsb(se->block, t->bootimg->sections[0].block, 4);
iso_lsb(se->block, t->bootsrc[idx]->sections[0].block, 4);
se->selec_criteria[0] = img->selection_crit[0];
memcpy(se->vendor_sc, img->selection_crit + 1, 19);
}
static
int catalog_open(IsoStream *stream)
{
int i, j, k, num_entries;
struct catalog_stream *data;
uint8_t *wpt;
struct el_torito_boot_catalog *cat;
struct el_torito_boot_image **boots;
if (stream == NULL) {
return ISO_NULL_POINTER;
}
data = stream->data;
cat = data->target->catalog;
boots = cat->bootimages;
if (data->offset != -1) {
return ISO_FILE_ALREADY_OPENED;
@ -601,11 +790,36 @@ int catalog_open(IsoStream *stream)
memset(data->buffer, 0, BLOCK_SIZE);
/* fill the buffer with the catalog contents */
write_validation_entry(data->buffer);
write_validation_entry(data->buffer,
boots[0]->platform_id, boots[0]->id_string);
/* write default entry */
write_section_entry(data->buffer + 32, data->target);
/* write default entry = first boot image */
write_section_entry(data->buffer + 32, data->target, 0);
/* IMPORTANT: The maximum number of boot images must fit into BLOCK_SIZE */
wpt = data->buffer + 64;
for (i = 1; i < cat->num_bootimages; ) {
/* Look ahead and put images of same platform_id and id_string
into the same section */
for (j = i + 1; j < cat->num_bootimages; j++) {
if (boots[i]->platform_id != boots[j]->platform_id)
break;
for (k = 0; k < sizeof(boots[i]->id_string); k++)
if (boots[i]->id_string[k] != boots[j]->id_string[k])
break;
if (k < sizeof(boots[i]->id_string))
break;
}
num_entries = j - i;
write_section_header(wpt, data->target, i, num_entries);
wpt += 32;
for (j = 0; j < num_entries; j++) {
write_section_entry(wpt, data->target, i);
wpt += 32;
i++;
}
}
data->offset = 0;
return ISO_SUCCESS;
}
@ -759,7 +973,7 @@ int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src)
file->checksum_index = 0;
file->nsections = 1;
file->sections = calloc(1, sizeof(struct iso_file_section));
file->sort_weight = 1000; /* slightly high */
file->sort_weight = target->catalog->sort_weight;
file->stream = stream;
ret = iso_file_src_add(target, file, src);
@ -775,27 +989,26 @@ int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src)
/******************* EL-TORITO WRITER *******************************/
/**
* Patch an isolinux boot image.
* Insert boot info table content into buf.
*
* @return
* 1 on success, 0 error (but continue), < 0 error
*/
static
int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize)
int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
uint32_t boot_lba, uint32_t imgsize)
{
struct boot_info_table *info;
uint32_t checksum;
size_t offset;
uint32_t offset;
if (imgsize < 64) {
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Isolinux image too small. We won't patch it.");
}
info = (struct boot_info_table *) (buf + 8);
if (imgsize < 64)
return ISO_ISOLINUX_CANT_PATCH;
/* compute checksum, as the the sum of all 32 bit words in boot image
* from offset 64 */
checksum = 0;
offset = (size_t) 64;
offset = 64;
while (offset <= imgsize - 4) {
checksum += iso_read_lsb(buf + offset, 4);
@ -810,16 +1023,36 @@ int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize)
checksum += iso_read_lsb(buf + offset, imgsize - offset);
}
/* patch boot info table */
info = (struct boot_info_table*)(buf + 8);
/*memset(info, 0, sizeof(struct boot_info_table));*/
iso_lsb(info->bi_pvd, t->ms_block + 16, 4);
iso_lsb(info->bi_file, t->bootimg->sections[0].block, 4);
iso_lsb(info->bi_pvd, pvd_lba, 4);
iso_lsb(info->bi_file, boot_lba, 4);
iso_lsb(info->bi_length, imgsize, 4);
iso_lsb(info->bi_csum, checksum, 4);
memset(buf + 24, 0, 40);
return ISO_SUCCESS;
}
/**
* Patch an isolinux boot image.
*
* @return
* 1 on success, 0 error (but continue), < 0 error
*/
static
int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize, int idx)
{
int ret;
if (imgsize < 64) {
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Isolinux image too small. We won't patch it.");
}
ret = make_boot_info_table(buf, t->ms_block + (uint32_t) 16,
t->bootsrc[idx]->sections[0].block,
(uint32_t) imgsize);
return ret;
}
static
int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
{
@ -828,7 +1061,11 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
* this is a good place to do so.
*/
Ecma119Image *t;
int ret;
int ret, idx;
size_t size;
uint8_t *buf;
IsoStream *new = NULL;
IsoStream *original = NULL;
if (writer == NULL) {
return ISO_NULL_POINTER;
@ -836,13 +1073,16 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
t = writer->target;
if (t->catalog->image->isolinux_options & 0x01) {
/* we need to patch the image */
size_t size;
uint8_t *buf;
IsoStream *new = NULL;
IsoStream *original = t->bootimg->stream;
/* Patch the boot image info tables if indicated */
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x01))
continue;
original = t->bootsrc[idx]->stream;
size = (size_t) iso_stream_get_size(original);
/* >>> BOOT ts B00428 :
check whether size is not too large for buffering */;
buf = calloc(1, size);
if (buf == NULL) {
return ISO_OUT_OF_MEM;
@ -858,7 +1098,7 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
}
/* ok, patch the read buffer */
ret = patch_boot_image(buf, t, size);
ret = patch_boot_image(buf, t, size, idx);
if (ret < 0) {
return ret;
}
@ -869,7 +1109,7 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
if (ret < 0) {
return ret;
}
t->bootimg->stream = new;
t->bootsrc[idx]->stream = new;
iso_stream_unref(original);
}
return ISO_SUCCESS;
@ -920,7 +1160,7 @@ int eltorito_writer_free_data(IsoImageWriter *writer)
int eltorito_writer_create(Ecma119Image *target)
{
int ret;
int ret, idx;
IsoImageWriter *writer;
IsoFile *bootimg;
IsoFileSrc *src;
@ -951,16 +1191,19 @@ int eltorito_writer_create(Ecma119Image *target)
return ret;
}
}
bootimg = target->catalog->image->image;
ret = iso_file_src_create(target, bootimg, &src);
if (ret < 0) {
return ret;
}
target->bootimg = src;
/* if we have selected to patch the image, it needs to be copied always */
if (target->catalog->image->isolinux_options & 0x01) {
src->prev_img = 0;
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
bootimg = target->catalog->bootimages[idx]->image;
ret = iso_file_src_create(target, bootimg, &src);
if (ret < 0) {
return ret;
}
target->bootsrc[idx] = src;
/* For patching an image, it needs to be copied always */
if (target->catalog->bootimages[idx]->isolinux_options & 0x01) {
src->prev_img = 0;
}
}
/* we need the bootable volume descriptor */

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 Thomas Schmitt
*
* 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
@ -27,15 +28,28 @@ struct Iso_Boot
IsoNode node;
};
/* Not more than 32 so that all entries fit into 2048 bytes */
#define Libisofs_max_boot_imageS 32
struct el_torito_boot_catalog {
IsoBoot *node; /* node of the catalog */
struct el_torito_boot_image *image; /* default boot image */
int num_bootimages;
struct el_torito_boot_image *bootimages[Libisofs_max_boot_imageS];
/* [0]= default boot image */
/* Weight value for image sorting */
int sort_weight;
};
struct el_torito_boot_image {
IsoFile *image;
unsigned int bootable:1; /**< If the entry is bootable. */
/**
* Whether the boot image seems to contain a boot_info_table
*/
unsigned int seems_boot_info_table:1;
/**
* isolinux options
* bit 0 -> whether to patch image
@ -47,6 +61,12 @@ struct el_torito_boot_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. */
/* Byte 1 of Validation Entry or Section Header Entry:
0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */
uint8_t platform_id;
uint8_t id_string[28];
uint8_t selection_crit[20];
};
/** El-Torito, 2.1 */
@ -76,8 +96,8 @@ struct el_torito_default_entry {
struct el_torito_section_header {
uint8_t header_indicator BP(1, 1);
uint8_t platform_id BP(2, 2);
uint8_t number BP(3, 4);
uint8_t character BP(5, 32);
uint8_t num_entries BP(3, 4);
uint8_t id_string BP(5, 32);
};
/** El-Torito, 2.4 */
@ -107,4 +127,14 @@ int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src);
*/
int eltorito_writer_create(Ecma119Image *target);
/**
* Insert boot info table content into buf.
*
* @return
* 1 on success, 0 error (but continue), < 0 error
*/
int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
uint32_t boot_lba, uint32_t imgsize);
#endif /* LIBISO_ELTORITO_H */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2010 Thomas Schmitt
*
* 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
@ -279,12 +279,20 @@ typedef struct
/* el-torito information */
unsigned int eltorito : 1; /* is el-torito available */
unsigned int bootable:1; /**< If the entry is bootable. */
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. */
uint32_t imgblock; /**< Block for El-Torito boot image */
int num_bootimgs;
unsigned char platform_ids[Libisofs_max_boot_imageS];
unsigned char id_strings[Libisofs_max_boot_imageS][28];
unsigned char selection_crits[Libisofs_max_boot_imageS][20];
unsigned char boot_flags[Libisofs_max_boot_imageS]; /* bit0= bootable */
unsigned char media_types[Libisofs_max_boot_imageS];
unsigned char partition_types[Libisofs_max_boot_imageS];
short load_segs[Libisofs_max_boot_imageS];
short load_sizes[Libisofs_max_boot_imageS];
/** Block addresses of for El-Torito boot images.
Needed to recognize them when the get read from the directory tree.
*/
uint32_t bootblocks[Libisofs_max_boot_imageS];
uint32_t catblock; /**< Block for El-Torito catalog */
/* Whether inode numbers from PX entries shall be discarded */
@ -2112,19 +2120,15 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
}
static
int read_pvm(_ImageFsData *data, uint32_t block)
int read_pvd_block(IsoDataSource *src, uint32_t block, uint8_t *buffer,
uint32_t *image_size)
{
int ret;
struct ecma119_pri_vol_desc *pvm;
struct ecma119_dir_record *rootdr;
uint8_t buffer[BLOCK_SIZE];
/* read PVM */
ret = data->src->read_block(data->src, block, buffer);
if (ret < 0) {
ret = src->read_block(src, block, buffer);
if (ret < 0)
return ret;
}
pvm = (struct ecma119_pri_vol_desc *)buffer;
/* sanity checks */
@ -2134,8 +2138,24 @@ int read_pvm(_ImageFsData *data, uint32_t block)
return ISO_WRONG_PVD;
}
if (image_size != NULL)
*image_size = iso_read_bb(pvm->vol_space_size, 4, NULL);
return ISO_SUCCESS;
}
static
int read_pvm(_ImageFsData *data, uint32_t block)
{
int ret;
struct ecma119_pri_vol_desc *pvm;
struct ecma119_dir_record *rootdr;
uint8_t buffer[BLOCK_SIZE];
ret = read_pvd_block(data->src, block, buffer, NULL);
if (ret < 0)
return ret;
/* ok, it is a valid PVD */
pvm = (struct ecma119_pri_vol_desc *)buffer;
/* fill volume attributes */
/* TODO take care of input charset */
@ -2191,11 +2211,13 @@ int read_pvm(_ImageFsData *data, uint32_t block)
static
int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
{
int ret;
int ret, i, rx, last_done, idx;
struct el_torito_validation_entry *ve;
struct el_torito_default_entry *entry;
struct el_torito_section_header *sh;
struct el_torito_section_entry *entry; /* also usable as default_entry */
unsigned char buffer[BLOCK_SIZE];
data->num_bootimgs = 0;
ret = data->src->read_block(data->src, block, buffer);
if (ret < 0) {
return ret;
@ -2206,34 +2228,70 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
/* check if it is a valid catalog (TODO: check also the checksum)*/
if ( (ve->header_id[0] != 1) || (ve->key_byte1[0] != 0x55)
|| (ve->key_byte2[0] != 0xAA) ) {
return iso_msg_submit(data->msgid, ISO_WRONG_EL_TORITO, 0,
iso_msg_submit(data->msgid, ISO_WRONG_EL_TORITO, 0,
"Wrong or damaged El-Torito Catalog. El-Torito info "
"will be ignored.");
return ISO_WRONG_EL_TORITO;
}
/* check for a valid platform */
if (ve->platform_id[0] != 0) {
return iso_msg_submit(data->msgid, ISO_UNSUPPORTED_EL_TORITO, 0,
"Unsupported El-Torito platform. Only 80x86 is "
if (ve->platform_id[0] != 0 && ve->platform_id[0] != 0xef) {
iso_msg_submit(data->msgid, ISO_UNSUPPORTED_EL_TORITO, 0,
"Unsupported El-Torito platform. Only 80x86 and EFI are "
"supported. El-Torito info will be ignored.");
return ISO_UNSUPPORTED_EL_TORITO;
}
/* ok, once we are here we assume it is a valid catalog */
/* parse the default entry */
entry = (struct el_torito_default_entry *)(buffer + 32);
entry = (struct el_torito_section_entry *)(buffer + 32);
data->eltorito = 1;
data->bootable = entry->boot_indicator[0] ? 1 : 0;
data->type = entry->boot_media_type[0];
data->partition_type = entry->system_type[0];
data->load_seg = iso_read_lsb(entry->load_seg, 2);
data->load_size = iso_read_lsb(entry->sec_count, 2);
data->imgblock = iso_read_lsb(entry->block, 4);
/* TODO #00018 : check if there are more entries in the boot catalog */
/* The Default Entry is declared mandatory */
data->num_bootimgs = 1;
data->platform_ids[0] = ve->platform_id[0];
memcpy(data->id_strings[0], ve->id_string, 24);
memset(data->id_strings[0] + 24, 0, 4);
data->boot_flags[0] = entry->boot_indicator[0] ? 1 : 0;
data->media_types[0] = entry->boot_media_type[0];
data->partition_types[0] = entry->system_type[0];
data->load_segs[0] = iso_read_lsb(entry->load_seg, 2);
data->load_sizes[0] = iso_read_lsb(entry->sec_count, 2);
data->bootblocks[0] = iso_read_lsb(entry->block, 4);
/* The Default Entry has no selection criterion */
memset(data->selection_crits[0], 0, 20);
/* Read eventual more entries from the boot catalog */
last_done = 0;
for (rx = 64; (buffer[rx] & 0xfe) == 0x90 && !last_done; rx += 32) {
last_done = buffer[rx] & 1;
/* Read Section Header */
sh = (struct el_torito_section_header *) (buffer + rx);
for (i = 0; i < sh->num_entries[0]; i++) {
rx += 32;
if (data->num_bootimgs >= Libisofs_max_boot_imageS) {
ret = iso_msg_submit(data->msgid, ISO_EL_TORITO_WARN, 0,
"Too many boot images found. List truncated.");
goto after_bootblocks;
}
/* Read bootblock from section entry */
entry = (struct el_torito_section_entry *)(buffer + rx);
idx = data->num_bootimgs;
data->platform_ids[idx] = sh->platform_id[0];
memcpy(data->id_strings[idx], sh->id_string, 28);
data->boot_flags[idx] = entry->boot_indicator[0] ? 1 : 0;
data->media_types[idx] = entry->boot_media_type[0];
data->partition_types[idx] = entry->system_type[0];
data->load_segs[idx] = iso_read_lsb(entry->load_seg, 2);
data->load_sizes[idx] = iso_read_lsb(entry->sec_count, 2);
data->bootblocks[idx] = iso_read_lsb(entry->block, 4);
data->selection_crits[idx][0] = entry->selec_criteria[0];
memcpy(data->selection_crits[idx] + 1, entry->vendor_sc, 19);
data->num_bootimgs++;
}
}
after_bootblocks:;
return ISO_SUCCESS;
}
@ -2317,7 +2375,7 @@ ex:
int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
int msgid, IsoImageFilesystem **fs)
{
int ret;
int ret, i;
uint32_t block;
IsoImageFilesystem *ifs;
_ImageFsData *data;
@ -2356,9 +2414,13 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
data->md5_load = !opts->nomd5;
data->aaip_version = -1;
data->make_new_ino = opts->make_new_ino;
data->num_bootimgs = 0;
for (i = 0; i < Libisofs_max_boot_imageS; i++)
data->bootblocks[i] = 0;
data->inode_counter = 0;
data->px_ino_status = 0;
data->local_charset = strdup(iso_get_local_charset(0));
if (data->local_charset == NULL) {
ret = ISO_OUT_OF_MEM;
@ -2425,21 +2487,18 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|| vol->vol_desc_version[0] != 1
|| strncmp((char*)vol->boot_sys_id,
"EL TORITO SPECIFICATION", 23)) {
ret = iso_msg_submit(data->msgid,
iso_msg_submit(data->msgid,
ISO_UNSUPPORTED_EL_TORITO, 0,
"Unsupported Boot Vol. Desc. Only El-Torito "
"Specification, Version 1.0 Volume "
"Descriptors are supported. Ignoring boot info");
if (ret < 0) {
} else {
data->catblock = iso_read_lsb(vol->boot_catalog, 4);
ret = read_el_torito_boot_catalog(data, data->catblock);
if (ret < 0 && ret != ISO_UNSUPPORTED_EL_TORITO &&
ret != ISO_WRONG_EL_TORITO) {
goto fs_cleanup;
}
break;
}
data->catblock = iso_read_lsb(vol->boot_catalog, 4);
ret = read_el_torito_boot_catalog(data, data->catblock);
if (ret < 0) {
goto fs_cleanup;
}
}
break;
@ -2489,11 +2548,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
*/
break;
default:
ret = iso_msg_submit(data->msgid, ISO_UNSUPPORTED_VD, 0,
"Ignoring Volume descriptor %x.", buffer[0]);
if (ret < 0) {
goto fs_cleanup;
}
iso_msg_submit(data->msgid, ISO_UNSUPPORTED_VD, 0,
"Ignoring Volume descriptor %x.", buffer[0]);
break;
}
block++;
@ -2613,7 +2669,7 @@ static
int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoFileSource *src, IsoNode **node)
{
int ret;
int ret, idx;
struct stat info;
IsoNode *new;
char *name;
@ -2725,11 +2781,16 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
new = (IsoNode*) file;
new->refcount = 0;
if (fsdata->eltorito && data->sections[0].block == fsdata->imgblock) {
for (idx = 0; idx < fsdata->num_bootimgs; idx++)
if (fsdata->eltorito && data->sections[0].block ==
fsdata->bootblocks[idx])
break;
if (idx < fsdata->num_bootimgs) {
/* it is boot image node */
if (image->bootcat->image->image != NULL) {
if (image->bootcat->bootimages[idx]->image != NULL) {
ret = iso_msg_submit(image->id, ISO_EL_TORITO_WARN, 0,
"More than one image node has been found.");
"More than one ISO node has been found for the same boot image.");
if (ret < 0) {
free(name);
iso_stream_unref(stream);
@ -2737,7 +2798,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
}
} else {
/* and set the image node */
image->bootcat->image->image = file;
image->bootcat->bootimages[idx]->image = file;
new->refcount++;
}
}
@ -2877,7 +2938,7 @@ int iso_image_builder_new(IsoNodeBuilder *old, IsoNodeBuilder **builder)
* accessible from the ISO filesystem.
*/
static
int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoImage *image,
int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoImage *image, int idx,
IsoFileSource **src)
{
int ret;
@ -2934,8 +2995,7 @@ int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoImage *image,
ifsdata->parent = NULL;
ifsdata->info = atts;
ifsdata->name = NULL;
ifsdata->sections[0].block = fsdata->imgblock;
ifsdata->sections[0].block = fsdata->bootblocks[idx];
ifsdata->sections[0].size = BLOCK_SIZE;
ifsdata->nsections = 1;
@ -2952,12 +3012,112 @@ boot_fs_cleanup: ;
return ret;
}
/** ??? >>> ts B00428 : should the max size become public ? */
#define Libisofs_boot_image_max_sizE (4096*1024)
/** Guess which of the loaded boot images contain boot information tables.
Set boot->seems_boot_info_table accordingly.
*/
static
int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
IsoDataSource *src, uint32_t iso_image_size, int flag)
{
int i, ret, section_count, todo, chunk;
uint32_t img_lba, img_size, boot_pvd_found, image_pvd, alleged_size;
struct iso_file_section *sections = NULL;
struct el_torito_boot_image *boot;
uint8_t *boot_image_buf = NULL, boot_info_found[16], buf[BLOCK_SIZE];
IsoStream *stream = NULL;
IsoFile *boot_file;
if (image->bootcat == NULL)
return ISO_SUCCESS;
for (i = 0; i < image->bootcat->num_bootimages; i++) {
boot = image->bootcat->bootimages[i];
boot_file = boot->image;
boot->seems_boot_info_table = 0;
img_size = iso_file_get_size(boot_file);
if (img_size > Libisofs_boot_image_max_sizE || img_size < 64)
continue;
img_lba = 0;
sections = NULL;
ret = iso_file_get_old_image_sections(boot_file,
&section_count, &sections, 0);
if (ret == 1 && section_count > 0)
img_lba = sections[0].block;
if (sections != NULL) {
free(sections);
sections = NULL;
}
if(img_lba == 0)
continue;
boot_image_buf = calloc(1, img_size);
if (boot_image_buf == NULL) {
ret = ISO_OUT_OF_MEM;
goto ex;
}
stream = iso_file_get_stream(boot_file);
ret = iso_stream_open(stream);
if (ret < 0) {
stream = NULL;
goto ex;
}
for (todo = img_size; todo > 0; ) {
if (todo > BLOCK_SIZE)
chunk = BLOCK_SIZE;
else
chunk = todo;
ret = iso_stream_read(stream, boot_image_buf + (img_size - todo),
chunk);
if (ret != chunk) {
ret = (ret < 0) ? ret : ISO_FILE_READ_ERROR;
goto ex;
}
todo -= chunk;
}
iso_stream_close(stream);
stream = NULL;
memcpy(boot_info_found, boot_image_buf + 8, 16);
boot_pvd_found = iso_read_lsb(boot_info_found, 4);
image_pvd = (uint32_t) (opts->block + 16);
/* Accomodate to eventually relocated superblock */
if (image_pvd != boot_pvd_found &&
image_pvd == 16 && boot_pvd_found < iso_image_size) {
/* Check whether there is a PVD at boot_pvd_found
and whether it bears the same image size
*/
ret = read_pvd_block(src, boot_pvd_found, buf, &alleged_size);
if (ret == 1 &&
alleged_size + boot_pvd_found == iso_image_size + image_pvd)
image_pvd = boot_pvd_found;
}
ret = make_boot_info_table(boot_image_buf, image_pvd,
img_lba, img_size);
if (ret < 0)
goto ex;
if (memcmp(boot_image_buf + 8, boot_info_found, 16) == 0)
boot->seems_boot_info_table = 1;
free(boot_image_buf);
boot_image_buf = NULL;
}
ret = 1;
ex:;
if (boot_image_buf != NULL)
free(boot_image_buf);
if (stream != NULL)
iso_stream_close(stream);
return ret;
}
int iso_image_import(IsoImage *image, IsoDataSource *src,
struct iso_read_opts *opts,
IsoReadImageFeatures **features)
{
int ret, hflag, i;
int ret, hflag, i, idx;
IsoImageFilesystem *fs;
IsoFilesystem *fsback;
IsoNodeBuilder *blback;
@ -2966,6 +3126,8 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
_ImageFsData *data;
struct el_torito_boot_catalog *oldbootcat;
uint8_t *rpt;
IsoFileSource *boot_src;
IsoNode *node;
#ifdef Libisofs_with_checksumS
uint32_t old_checksum_start_lba;
@ -3071,23 +3233,34 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
struct el_torito_boot_catalog *catalog;
ElToritoBootImage *boot_image= NULL;
boot_image = calloc(1, sizeof(ElToritoBootImage));
if (boot_image == NULL) {
ret = ISO_OUT_OF_MEM;
goto import_revert;
}
boot_image->bootable = data->bootable;
boot_image->type = data->type;
boot_image->partition_type = data->partition_type;
boot_image->load_seg = data->load_seg;
boot_image->load_size = data->load_size;
catalog = calloc(1, sizeof(struct el_torito_boot_catalog));
if (catalog == NULL) {
ret = ISO_OUT_OF_MEM;
goto import_revert;
}
catalog->image = boot_image;
catalog->num_bootimages = 0;
for (idx = 0; idx < data->num_bootimgs; idx++) {
boot_image = calloc(1, sizeof(ElToritoBootImage));
if (boot_image == NULL) {
ret = ISO_OUT_OF_MEM;
goto import_revert;
}
boot_image->image = NULL;
boot_image->bootable = data->boot_flags[idx] & 1;
boot_image->type = data->media_types[idx];
boot_image->partition_type = data->partition_types[idx];
boot_image->load_seg = data->load_segs[idx];
boot_image->load_size = data->load_sizes[idx];
boot_image->platform_id = data->platform_ids[idx];
memcpy(boot_image->id_string, data->id_strings[idx], 28);
memcpy(boot_image->selection_crit, data->selection_crits, 20);
catalog->bootimages[catalog->num_bootimages] = boot_image;
catalog->num_bootimages++;
}
for ( ; idx < Libisofs_max_boot_imageS; idx++)
catalog->bootimages[idx] = NULL;
image->bootcat = catalog;
}
@ -3121,21 +3294,23 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
}
if (data->eltorito) {
/* if catalog and image nodes were not filled, we create them here */
if (image->bootcat->image->image == NULL) {
IsoFileSource *src;
IsoNode *node;
ret = create_boot_img_filesrc(fs, image, &src);
/* if catalog and boot image nodes were not filled,
we create them here */
for (idx = 0; idx < image->bootcat->num_bootimages; idx++) {
if (image->bootcat->bootimages[idx]->image != NULL)
continue;
ret = create_boot_img_filesrc(fs, image, idx, &boot_src);
if (ret < 0) {
iso_node_builder_unref(image->builder);
goto import_revert;
}
ret = image_builder_create_node(image->builder, image, src, &node);
ret = image_builder_create_node(image->builder, image, boot_src,
&node);
if (ret < 0) {
iso_node_builder_unref(image->builder);
goto import_revert;
}
image->bootcat->image->image = (IsoFile*)node;
image->bootcat->bootimages[idx]->image = (IsoFile*)node;
/* warn about hidden images */
iso_msg_submit(image->id, ISO_EL_TORITO_HIDDEN, 0,
@ -3244,6 +3419,10 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
#endif /* Libisofs_with_checksumS */
ret = iso_image_eval_boot_info_table(image, opts, src, data->nblocks, 0);
if (ret < 0)
goto import_revert;
ret = ISO_SUCCESS;
goto import_cleanup;

View File

@ -712,7 +712,7 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
iso_bb(rec->length, len, 4);
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
rec->flags[0] = ((node->type == ISO1999_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
iso_bb(rec->vol_seq_number, 1, 2);
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
rec->len_fi[0] = len_fi;
}
@ -763,9 +763,9 @@ int iso1999_writer_write_vol_desc(IsoImageWriter *writer)
strncpy_pad((char*)vol.volume_id, vol_id, 32);
iso_bb(vol.vol_space_size, t->vol_space_size, 4);
iso_bb(vol.vol_set_size, 1, 2);
iso_bb(vol.vol_seq_number, 1, 2);
iso_bb(vol.block_size, BLOCK_SIZE, 2);
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
iso_bb(vol.path_table_size, t->iso1999_path_table_size, 4);
iso_lsb(vol.l_path_table_pos, t->iso1999_l_path_table_pos, 4);
iso_msb(vol.m_path_table_pos, t->iso1999_m_path_table_pos, 4);

View File

@ -758,7 +758,7 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
iso_bb(rec->length, len, 4);
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
rec->flags[0] = ((node->type == JOLIET_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
iso_bb(rec->vol_seq_number, 1, 2);
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
rec->len_fi[0] = len_fi;
}
@ -833,9 +833,9 @@ int joliet_writer_write_vol_desc(IsoImageWriter *writer)
memcpy(vol.esc_sequences, "%/E", 3);
iso_bb(vol.vol_space_size, t->vol_space_size, 4);
iso_bb(vol.vol_set_size, 1, 2);
iso_bb(vol.vol_seq_number, 1, 2);
iso_bb(vol.block_size, BLOCK_SIZE, 2);
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
iso_bb(vol.path_table_size, t->joliet_path_table_size, 4);
iso_lsb(vol.l_path_table_pos, t->joliet_l_path_table_pos, 4);
iso_msb(vol.m_path_table_pos, t->joliet_m_path_table_pos, 4);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009-2010 Thomas Schmitt
*
* 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
@ -1091,7 +1091,7 @@ int iso_lib_is_compatible(int major, int minor, int micro);
*/
#define iso_lib_header_version_major 0
#define iso_lib_header_version_minor 6
#define iso_lib_header_version_micro 30
#define iso_lib_header_version_micro 32
/**
* Usage discussion:
@ -2283,16 +2283,15 @@ void iso_image_set_biblio_file_id(IsoImage *image, const char *biblio_file_id);
const char *iso_image_get_biblio_file_id(const IsoImage *image);
/**
* Create a bootable image by adding a El-Torito boot image.
*
* This also add a catalog boot node to the image filesystem tree.
* Create a new set of El-Torito bootable images by adding a boot catalog
* and the default boot image.
* Further boot images may then be added by iso_image_add_boot_image().
*
* @param image
* The image to make bootable. If it was already bootable this function
* returns an error and the image remains unmodified.
* @param image_path
* The absolute path on the image tree of a regular file to use as
* default boot image.
* The absolute path of a IsoFile to be used as default boot image.
* @param type
* The boot media type. This can be one of 3 types:
* - Floppy emulation: Boot image file must be exactly
@ -2325,10 +2324,36 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
const char *catalog_path,
ElToritoBootImage **boot);
/**
* Add a further boot image to the set of El-Torito bootable images.
* This set has already to be created by iso_image_set_boot_image().
* Up to 31 further boot images may be added.
*
* @param image
* The image to which the boot image shall be added.
* returns an error and the image remains unmodified.
* @param image_path
* The absolute path of a IsoFile to be used as default boot image.
* @param type
* The boot media type. See iso_image_set_boot_image
* @param flag
* Bitfield for control purposes. Unused yet. Submit 0.
* @param boot
* Location where a pointer to the added boot image will be stored.
* See iso_image_set_boot_image
* @return
* 1 on success, < 0 on error
*
* @since 0.6.32
*/
int iso_image_add_boot_image(IsoImage *image, const char *image_path,
enum eltorito_boot_media_type type, int flag,
ElToritoBootImage **boot);
/* TODO #00026 : add support for "hidden" bootable images. */
/**
* Get El-Torito boot image of an ISO image, if any.
* Get the El-Torito boot catalog and the default boot image of an ISO image.
*
* This can be useful, for example, to check if a volume read from a previous
* session or an existing image is bootable. It can also be useful to get
@ -2366,7 +2391,35 @@ int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
IsoFile **imgnode, IsoBoot **catnode);
/**
* Removes the El-Torito bootable image.
* Get all El-Torito boot images of an ISO image.
*
* The first of these boot images is the same as returned by
* iso_image_get_boot_image(). The others are alternative boot images.
*
* @param image
* The image from which to get the boot images.
* @param num_boots
* The number of available array elements in boots and bootnodes.
* @param boots
* Returns NULL or an allocated array of pointers to boot images.
* Apply system call free(boots) to dispose it.
* @param bootnodes
* Returns NULL or an allocated array of pointers to the IsoFile nodes
* which bear the content of the boot images in boots.
* @param flag
* Bitfield for control purposes. Unused yet. Submit 0.
* @return
* 1 on success, 0 no El-Torito catalog and boot image attached,
* < 0 error.
*
* @since 0.6.32
*/
int iso_image_get_all_boot_imgs(IsoImage *image, int *num_boots,
ElToritoBootImage ***boots, IsoFile ***bootnodes, int flag);
/**
* Removes all El-Torito boot images from the ISO image.
*
* The IsoBoot node that acts as placeholder for the catalog is also removed
* for the image tree, if there.
@ -2377,6 +2430,74 @@ int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
*/
void iso_image_remove_boot_image(IsoImage *image);
/**
* Sets the sort weight of the boot catalog that is attached to an IsoImage.
*
* For the meaning of sort weights see iso_node_set_sort_weight().
* That function cannot be applied to the emerging boot catalog because
* it is not represented by an IsoFile.
*
* @param image
* The image to manipulate.
* @param sort_weight
* The larger this value, the lower will be the block address of the
* boot catalog record.
* @return
* 0= no boot catalog attached , 1= ok , <0 = error
*
* @since 0.6.32
*/
int iso_image_set_boot_catalog_weight(IsoImage *image, int sort_weight);
/**
* Get the boot media type as of parameter "type" of iso_image_set_boot_image()
* resp. iso_image_add_boot_image().
*
* @param bootimg
* The image to inquire
* @param media_type
* Returns the media type
* @return
* 1 = ok , < 0 = error
*
* @since 0.6.32
*/
int el_torito_get_boot_media_type(ElToritoBootImage *bootimg,
enum eltorito_boot_media_type *media_type);
/**
* Sets the platform ID of the boot image.
*
* The Platform ID gets written into the boot catalog at byte 1 of the
* Validation Entry, or at byte 1 of a Section Header Entry.
* If Platform ID and ID String of two consequtive bootimages are the same
*
* @param bootimg
* The image to manipulate.
* @param id
* A Platform ID as of
* El Torito 1.0 : 0x00= 80x86, 0x01= PowerPC, 0x02= Mac
* Others : 0xef= EFI
* @return
* 1 ok , <=0 error
*
* @since 0.6.32
*/
int el_torito_set_boot_platform_id(ElToritoBootImage *bootimg, uint8_t id);
/**
* Get the platform ID value. See el_torito_set_boot_platform_id().
*
* @param bootimg
* The image to inquire
* @return
* 0 - 255 : The platform ID
* < 0 : error
*
* @since 0.6.32
*/
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.
@ -2385,6 +2506,19 @@ void iso_image_remove_boot_image(IsoImage *image);
*/
void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment);
/**
* Get the load segment value. See el_torito_set_load_seg().
*
* @param bootimg
* The image to inquire
* @return
* 0 - 65535 : The load segment value
* < 0 : error
*
* @since 0.6.32
*/
int el_torito_get_load_seg(ElToritoBootImage *bootimg);
/**
* Sets the number of sectors (512b) to be load at load segment during
* the initial boot procedure. This is only for
@ -2394,6 +2528,19 @@ void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment);
*/
void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors);
/**
* Get the load size. See el_torito_set_load_size().
*
* @param bootimg
* The image to inquire
* @return
* 0 - 65535 : The load size value
* < 0 : error
*
* @since 0.6.32
*/
int el_torito_get_load_size(ElToritoBootImage *bootimg);
/**
* Marks the specified boot image as not bootable
*
@ -2402,15 +2549,103 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors);
void el_torito_set_no_bootable(ElToritoBootImage *bootimg);
/**
* Specifies that this image needs to be patched. This involves the writing
* of a 56 bytes boot information table at offset 8 of the boot image file.
* The original boot image file won't be modified.
* This is needed for isolinux boot images.
* Get the bootability flag. See el_torito_set_no_bootable().
*
* @since 0.6.2
* @deprecated Use el_torito_set_isolinux_options() instead
* @param bootimg
* The image to inquire
* @return
* 0 = not bootable, 1 = bootable , <0 = error
*
* @since 0.6.32
*/
void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
int el_torito_get_bootable(ElToritoBootImage *bootimg);
/**
* Set the id_string of the Validation Entry resp. Sector Header Entry which
* will govern the boot image Section Entry in the El Torito Catalog.
*
* @param bootimg
* The image to manipulate.
* @param id_string
* The first boot image puts 24 bytes of ID string into the Validation
* Entry, where they shall "identify the manufacturer/developer of
* the CD-ROM".
* Further boot images put 28 bytes into their Section Header.
* El Torito 1.0 states that "If the BIOS understands the ID string, it
* may choose to boot the * system using one of these entries in place
* of the INITIAL/DEFAULT entry." (The INITIAL/DEFAULT entry points to the
* first boot image.)
* @return
* 1 = ok , <0 = error
*
* @since 0.6.32
*/
int el_torito_set_id_string(ElToritoBootImage *bootimg, uint8_t id_string[28]);
/**
* Get the id_string as of el_torito_set_id_string().
*
* @param bootimg
* The image to inquire
* @param id_string
* Returns 28 bytes of id string
* @return
* 1 = ok , <0 = error
*
* @since 0.6.32
*/
int el_torito_get_id_string(ElToritoBootImage *bootimg, uint8_t id_string[28]);
/**
* Set the Selection Criteria of a boot image.
*
* @param bootimg
* The image to manipulate.
* @param crit
* The first boot image has no selection criteria. They will be ignored.
* Further boot images put 1 byte of Selection Criteria Type and 19
* bytes of data into their Section Entry.
* El Torito 1.0 states that "The format of the selection criteria is
* a function of the BIOS vendor. In the case of a foreign language
* BIOS three bytes would be used to identify the language".
* Type byte == 0 means "no criteria",
* type byte == 1 means "Language and Version Information (IBM)".
* @return
* 1 = ok , <0 = error
*
* @since 0.6.32
*/
int el_torito_set_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20]);
/**
* Get the Selection Criteria bytes as of el_torito_set_selection_crit().
*
* @param bootimg
* The image to inquire
* @param id_string
* Returns 20 bytes of type and data
* @return
* 1 = ok , <0 = error
*
* @since 0.6.32
*/
int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20]);
/**
* Makes a guess whether the boot image was patched by a boot information
* table. It is advisable to patch such boot images if their content gets
* copied to a new location. See el_torito_set_isolinux_options().
* Note: The reply can be positive only if the boot image was imported
* from an existing ISO image.
*
* @param bootimg
* The image to inquire
* @return
* 1 = seems to contain oot info table , 0 = quite surely not
* @since 0.6.32
*/
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
/**
* Specifies options for ISOLINUX or GRUB boot images. This should only be used
@ -2421,11 +2656,16 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
*
* bit 0 -> 1 to patch the boot info table of the boot image.
* 1 does the same as mkisofs option -boot-info-table.
* Needed for ISOLINUX and for GRUB rescue boot images.
* Needed for ISOLINUX or GRUB boot images with platform ID 0.
* The table is located at byte 8 of the boot image file.
* Its size is 56 bytes.
* The original boot image file on disk will not be modified.
*
* One may use el_torito_seems_boot_info_table() for a
* qualified guess whether a boot info table is present in
* the boot image. If the result is 1 then it should get bit0
* set if its content gets copied to a new LBA.
*
* bit 1 -> 1 to generate a ISOLINUX isohybrid image with MBR.
* ----------------------------------------------------------
* @deprecated since 31 Mar 2010:
@ -2444,7 +2684,33 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
* 1 success, < 0 on error
* @since 0.6.12
*/
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag);
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg,
int options, int flag);
/**
* Get the options as of el_torito_set_isolinux_options().
*
* @param bootimg
* The image to inquire
* @param flag
* Reserved for future usage, set to 0.
* @return
* >= 0 returned option bits , <0 = error
*
* @since 0.6.32
*/
int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag);
/** Deprecated:
* Specifies that this image needs to be patched. This involves the writing
* of a 16 bytes boot information table at offset 8 of the boot image file.
* The original boot image file won't be modified.
* This is needed for isolinux boot images.
*
* @since 0.6.2
* @deprecated Use el_torito_set_isolinux_options() instead
*/
void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
/**
* Obtain a copy of the eventually loaded first 32768 bytes of the imported
@ -3152,8 +3418,8 @@ const char *iso_symlink_get_dest(const IsoSymlink *link);
int iso_symlink_set_dest(IsoSymlink *link, const char *dest);
/**
* Sets the order in which a node will be written on image. High weihted files
* will be written first, so in a disc them will be written near the center.
* Sets the order in which a node will be written on image. The data content
* of files with high weight will be written to low block addresses.
*
* @param node
* The node which weight will be changed. If it's a dir, this function
@ -3162,6 +3428,7 @@ int iso_symlink_set_dest(IsoSymlink *link, const char *dest);
* @param w
* The weight as a integer number, the greater this value is, the
* closer from the begining of image the file will be written.
* Default value at IsoNode creation is 0.
*
* @since 0.6.2
*/
@ -5440,6 +5707,9 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
/** Trying to use an invalid file as boot image (FAILURE,HIGH, -68) */
#define ISO_BOOT_IMAGE_NOT_VALID 0xE830FFBB
/** Too many boot images (FAILURE,HIGH, -69) */
#define ISO_BOOT_IMAGE_OVERFLOW 0xE830FFBA
/**
* Error on file operation (FAILURE,HIGH, -128)
* (take a look at more specified error codes below)
@ -5541,11 +5811,11 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
/** Unsupported ECMA-119 feature (FAILURE,HIGH, -324) */
#define ISO_UNSUPPORTED_ECMA119 0xE830FEBC
/** Wrong or damaged El-Torito catalog (SORRY,HIGH, -325) */
#define ISO_WRONG_EL_TORITO 0xE030FEBB
/** Wrong or damaged El-Torito catalog (WARN,HIGH, -325) */
#define ISO_WRONG_EL_TORITO 0xD030FEBB
/** Unsupported El-Torito feature (SORRY,HIGH, -326) */
#define ISO_UNSUPPORTED_EL_TORITO 0xE030FEBA
/** Unsupported El-Torito feature (WARN,HIGH, -326) */
#define ISO_UNSUPPORTED_EL_TORITO 0xD030FEBA
/** Can't patch an isolinux boot image (SORRY,HIGH, -327) */
#define ISO_ISOLINUX_CANT_PATCH 0xE030FEB9

View File

@ -153,6 +153,8 @@ const char *iso_error_to_msg(int errcode)
return "Try to set the boot image of an already bootable image";
case ISO_BOOT_IMAGE_NOT_VALID:
return "Trying to use an invalid file as boot image";
case ISO_BOOT_IMAGE_OVERFLOW:
return "Too many boot images added";
case ISO_FILE_ERROR:
return "Error on file operation";
case ISO_FILE_ALREADY_OPENED:

View File

@ -1284,6 +1284,7 @@ int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
new->node.type = LIBISO_FILE;
new->node.name = name;
new->node.mode = S_IFREG;
new->sort_weight = 0;
new->stream = stream;
*file = new;

View File

@ -109,12 +109,12 @@ int rrip_add_PX(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
PX[2] = 36;
}
PX[3] = 1;
iso_bb(&PX[4], px_get_mode(t, n), 4);
iso_bb(&PX[12], n->nlink, 4);
iso_bb(&PX[20], px_get_uid(t, n), 4);
iso_bb(&PX[28], px_get_gid(t, n), 4);
iso_bb(&PX[4], (uint32_t) px_get_mode(t, n), 4);
iso_bb(&PX[12], (uint32_t) n->nlink, 4);
iso_bb(&PX[20], (uint32_t) px_get_uid(t, n), 4);
iso_bb(&PX[28], (uint32_t) px_get_gid(t, n), 4);
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10) {
iso_bb(&PX[36], n->ino, 4);
iso_bb(&PX[36], (uint32_t) n->ino, 4);
}
return susp_append(t, susp, PX);
@ -243,10 +243,10 @@ int rrip_add_PN(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
*/
if (sizeof(node->dev) > 4) {
high_shift = 32;
iso_bb(&PN[4], node->dev >> high_shift, 4);
iso_bb(&PN[4], (uint32_t) (node->dev >> high_shift), 4);
} else
iso_bb(&PN[4], 0, 4);
iso_bb(&PN[12], node->dev & 0xffffffff, 4);
iso_bb(&PN[12], (uint32_t) (node->dev & 0xffffffff), 4);
return susp_append(t, susp, PN);
}
@ -695,7 +695,7 @@ int susp_add_CE(Ecma119Image *t, size_t ce_len, struct susp_info *susp)
CE[3] = 1;
iso_bb(&CE[4], susp->ce_block, 4);
iso_bb(&CE[12], susp->ce_len, 4);
iso_bb(&CE[20], ce_len, 4);
iso_bb(&CE[20], (uint32_t) ce_len, 4);
return susp_append(t, susp, CE);
}

View File

@ -134,11 +134,11 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
memcpy(buf, t->system_area_data, 16 * BLOCK_SIZE);
} else if (t->catalog != NULL &&
(t->catalog->image->isolinux_options & 0x0a) == 0x02) {
(t->catalog->bootimages[0]->isolinux_options & 0x0a) == 0x02) {
/* Check for isolinux image with magic number of 3.72 and produce
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
*/
ret = make_isohybrid_mbr(t->bootimg->sections[0].block,
ret = make_isohybrid_mbr(t->bootsrc[0]->sections[0].block,
&img_blocks, (char*)buf, 0);
if (ret != 1) {
/* error, it should never happen */
@ -159,7 +159,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
*/
return ISO_ISOLINUX_CANT_PATCH;
}
ret = make_isolinux_mbr(&img_blocks, t->bootimg->sections[0].block,
ret = make_isolinux_mbr(&img_blocks, t->bootsrc[0]->sections[0].block,
(uint32_t) 0, 64, 32, 0, 1, 0x17, buf, 1);
if (ret != 1)
return ret;