Compare commits
27 Commits
release-0.
...
release-0.
Author | SHA1 | Date | |
---|---|---|---|
84132ec7bf | |||
eb23260459 | |||
4978424328 | |||
e4cf93665a | |||
3d9367d52a | |||
03b030c56d | |||
a3fe82100b | |||
02d7a690eb | |||
ace0d1ab2e | |||
59d143c1f0 | |||
da2c0520cc | |||
517f520570 | |||
98d2b4c996 | |||
481d425580 | |||
99e988d652 | |||
38a7b4a5b1 | |||
9dc894584d | |||
1a7ab679cd | |||
016baf9984 | |||
b089f2e978 | |||
c3d5ab7bc7 | |||
f13167335a | |||
f0f378c38f | |||
907b44c556 | |||
00011036dd | |||
55497d3931 | |||
c47f206fe3 |
101
README
101
README
@ -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
|
||||
|
54
acinclude.m4
54
acinclude.m4
@ -50,8 +50,9 @@ dnl From Bruno Haible.
|
||||
dnl
|
||||
AC_DEFUN([LIBBURNIA_CHECK_ICONV],
|
||||
[
|
||||
|
||||
dnl Check whether it is allowed to link with -liconv
|
||||
AC_MSG_CHECKING([for separate -liconv ])
|
||||
AC_MSG_CHECKING([for iconv() in separate -liconv ])
|
||||
libburnia_liconv="no"
|
||||
libburnia_save_LIBS="$LIBS"
|
||||
LIBS="$LIBS -liconv"
|
||||
@ -65,6 +66,13 @@ AC_DEFUN([LIBBURNIA_CHECK_ICONV],
|
||||
)
|
||||
AC_MSG_RESULT([$libburnia_liconv])
|
||||
|
||||
if test x"$libburnia_save_LIBS" = x"$LIBS"
|
||||
then
|
||||
dnl GNU iconv has no function iconv() but libiconv() and a macro iconv()
|
||||
dnl It is not tested whether this is detected by above macro.
|
||||
AC_CHECK_LIB(iconv, libiconv, , )
|
||||
fi
|
||||
|
||||
dnl Check for iconv(..., const char **inbuf, ...)
|
||||
AC_MSG_CHECKING([for const qualifier with iconv() ])
|
||||
AC_TRY_COMPILE([
|
||||
@ -79,6 +87,50 @@ size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, si
|
||||
])
|
||||
|
||||
|
||||
dnl LIBBURNIA_ASSERT_ICONV is by Thomas Schmitt, libburnia project
|
||||
dnl
|
||||
AC_DEFUN([LIBBURNIA_ASSERT_ICONV],
|
||||
[
|
||||
if test x$LIBISOFS_ASSUME_ICONV = x
|
||||
then
|
||||
dnl Check for the essential gestures of libisofs/util.c
|
||||
AC_MSG_CHECKING([for iconv() to be accessible now ])
|
||||
AC_TRY_LINK([
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <iconv.h>
|
||||
#include <locale.h>
|
||||
#include <langinfo.h>
|
||||
#include <unistd.h>],
|
||||
[iconv_t cd = iconv_open("","");
|
||||
iconv(cd,NULL,NULL,NULL,NULL);
|
||||
iconv_close(cd);
|
||||
], [iconv_test="yes"], [iconv_test="no"]
|
||||
)
|
||||
AC_MSG_RESULT([$iconv_test])
|
||||
if test x$iconv_test = xno
|
||||
then
|
||||
echo >&2
|
||||
echo "Cannot get function iconv() to work. Configuration aborted." >&2
|
||||
echo "Check whether your system needs a separate libiconv installed." >&2
|
||||
echo "If it is installed but not found, try something like" >&2
|
||||
echo ' export LDFLAGS="$LDFLAGS -L/usr/local/lib"' >&2
|
||||
echo ' export CPPFLAGS="$CPPFLAGS -I/usr/local/include"' >&2
|
||||
echo ' export LIBS="$LIBS -liconv"' >&2
|
||||
echo "You may override this test by exporting variable" >&2
|
||||
echo " LIBISOFS_ASSUME_ICONV=yes" >&2
|
||||
echo >&2
|
||||
(exit 1); exit 1;
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file.
|
||||
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
||||
dnl
|
||||
|
15
configure.ac
15
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([libisofs], [0.6.28], [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=28
|
||||
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.02.10 development jump has not yet happened
|
||||
# SONAME = 30 - 24 = 6 . Library name = libisofs.6.24.0
|
||||
LT_CURRENT=30
|
||||
LT_AGE=24
|
||||
# 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`
|
||||
|
||||
@ -91,6 +91,9 @@ dnl If iconv(3) is in an extra lib, then it gets added to variable LIBS.
|
||||
dnl If not, then no -liconv will be added.
|
||||
LIBBURNIA_CHECK_ICONV
|
||||
|
||||
dnl To abort configuration if iconv() still cannot be compiled
|
||||
LIBBURNIA_ASSERT_ICONV
|
||||
|
||||
|
||||
AC_PROG_LIBTOOL
|
||||
AC_SUBST(LIBTOOL_DEPS)
|
||||
|
@ -305,3 +305,16 @@ The size of the volume is 2456606865 bytes, which have a MD5 sum of
|
||||
The checksum of "2_2 B00109.143415 2456606865 485bbef110870c45754d7adcc844a72c"
|
||||
is c2355d5ea3c94d792ff5893dfe0d6d7b.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This text is under
|
||||
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||
It shall only be modified in sync with libisofs and other software which
|
||||
makes use of libisofs checksums. Please mail change requests to mailing list
|
||||
<libburn-hackers@pykix.org> or to the copyright holder in private.
|
||||
Only if you cannot reach the copyright holder for at least one month it is
|
||||
permissible to modify this text under the same license as the affected
|
||||
copy of libisofs.
|
||||
If you do so, you commit yourself to taking reasonable effort to stay in
|
||||
sync with the other interested users of this text.
|
||||
|
||||
|
@ -443,3 +443,14 @@ Program mkisofs emits entry XA
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This text is under
|
||||
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||
It shall only be modified in sync with libisofs and other software which
|
||||
makes use of AAIP. Please mail change requests to mailing list
|
||||
<libburn-hackers@pykix.org> or to the copyright holder in private.
|
||||
Only if you cannot reach the copyright holder for at least one month it is
|
||||
permissible to modify this text under the same license as the affected
|
||||
copy of libisofs.
|
||||
If you do so, you commit yourself to taking reasonable effort to stay in
|
||||
sync with the other interested users of this text.
|
||||
|
||||
|
@ -149,3 +149,14 @@ Registered:
|
||||
-------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This text is under
|
||||
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||
It shall only be modified in sync with libisofs and other software which
|
||||
makes use of AAIP. Please mail change requests to mailing list
|
||||
<libburn-hackers@pykix.org> or to the copyright holder in private.
|
||||
Only if you cannot reach the copyright holder for at least one month it is
|
||||
permissible to modify this text under the same license as the affected
|
||||
copy of libisofs.
|
||||
If you do so, you commit yourself to taking reasonable effort to stay in
|
||||
sync with the other interested users of this text.
|
||||
|
||||
|
@ -141,3 +141,14 @@ SUSP 1.12
|
||||
RRIP 1.12
|
||||
ftp://ftp.ymi.com/pub/rockridge/rrip112.ps
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This text is under
|
||||
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||
It shall reflect the effective technical specifications as implemented in
|
||||
zisofs-tools and the Linux kernel. So please contact mailing list
|
||||
<libburn-hackers@pykix.org> or to the copyright holder in private, if you
|
||||
want to make changes.
|
||||
Only if you cannot reach the copyright holder for at least one month it is
|
||||
permissible to modify and distribute this text under the license "BSD revised".
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
To be included by aaip_0_2.c
|
||||
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
||||
|
||||
*/
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
aaip-os-freebsd.c
|
||||
Arbitrary Attribute Interchange Protocol , system adapter for getting and
|
||||
setting of ACLs and ixattr.
|
||||
setting of ACLs and xattr.
|
||||
|
||||
To be included by aaip_0_2.c
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
To be included by aaip_0_2.c
|
||||
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
||||
|
||||
*/
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
See test/aaip_0_2.h
|
||||
http://libburnia-project.org/wiki/AAIP
|
||||
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
||||
|
||||
*/
|
||||
|
||||
@ -567,7 +567,7 @@ ex:;
|
||||
}
|
||||
|
||||
|
||||
/* Linux man 5 acl says:
|
||||
/* GNU/Linux man 5 acl says:
|
||||
The permissions defined by ACLs are a superset of the permissions speci-
|
||||
fied by the file permission bits. The permissions defined for the file
|
||||
owner correspond to the permissions of the ACL_USER_OBJ entry. The per-
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
test/aaip_0_2.h - Public declarations
|
||||
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
||||
|
||||
*/
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,6 +72,10 @@ 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);
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
if (t->checksum_ctx != NULL) { /* dispose checksum context */
|
||||
@ -93,7 +97,7 @@ void ecma119_image_free(Ecma119Image *t)
|
||||
static
|
||||
int need_version_number(Ecma119Image *t, Ecma119Node *n)
|
||||
{
|
||||
if (t->omit_version_numbers) {
|
||||
if (t->omit_version_numbers & 1) {
|
||||
return 0;
|
||||
}
|
||||
if (n->type == ECMA119_DIR || n->type == ECMA119_PLACEHOLDER) {
|
||||
@ -339,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;
|
||||
|
||||
/*
|
||||
@ -380,7 +384,7 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
IsoImage *image;
|
||||
Ecma119Image *t;
|
||||
struct ecma119_pri_vol_desc vol;
|
||||
|
||||
int i;
|
||||
char *vol_id, *pub_id, *data_id, *volset_id;
|
||||
char *system_id, *application_id, *copyright_file_id;
|
||||
char *abstract_file_id, *biblio_file_id;
|
||||
@ -417,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);
|
||||
@ -435,9 +439,44 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
strncpy_pad((char*)vol.abstract_file_id, abstract_file_id, 37);
|
||||
strncpy_pad((char*)vol.bibliographic_file_id, biblio_file_id, 37);
|
||||
|
||||
iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt);
|
||||
iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt);
|
||||
iso_datetime_17(vol.vol_effective_time, t->now, t->always_gmt);
|
||||
if (t->vol_uuid[0]) {
|
||||
for(i = 0; i < 16; i++)
|
||||
if(t->vol_uuid[i] < '0' || t->vol_uuid[i] > '9')
|
||||
break;
|
||||
else
|
||||
vol.vol_creation_time[i] = t->vol_uuid[i];
|
||||
for(; i < 16; i++)
|
||||
vol.vol_creation_time[i] = '1';
|
||||
vol.vol_creation_time[16] = 0;
|
||||
} else if (t->vol_creation_time > 0)
|
||||
iso_datetime_17(vol.vol_creation_time, t->vol_creation_time,
|
||||
t->always_gmt);
|
||||
else
|
||||
iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt);
|
||||
|
||||
if (t->vol_uuid[0]) {
|
||||
for(i = 0; i < 16; i++)
|
||||
if(t->vol_uuid[i] < '0' || t->vol_uuid[i] > '9')
|
||||
break;
|
||||
else
|
||||
vol.vol_modification_time[i] = t->vol_uuid[i];
|
||||
for(; i < 16; i++)
|
||||
vol.vol_modification_time[i] = '1';
|
||||
vol.vol_modification_time[16] = 0;
|
||||
} else if (t->vol_modification_time > 0)
|
||||
iso_datetime_17(vol.vol_modification_time, t->vol_modification_time,
|
||||
t->always_gmt);
|
||||
else
|
||||
iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt);
|
||||
|
||||
if (t->vol_expiration_time > 0)
|
||||
iso_datetime_17(vol.vol_expiration_time, t->vol_expiration_time,
|
||||
t->always_gmt);
|
||||
|
||||
if (t->vol_effective_time > 0)
|
||||
iso_datetime_17(vol.vol_effective_time, t->vol_effective_time,
|
||||
t->always_gmt);
|
||||
|
||||
vol.file_structure_version[0] = 1;
|
||||
|
||||
free(vol_id);
|
||||
@ -1065,7 +1104,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
{
|
||||
int ret, i, voldesc_size, nwriters, image_checksums_mad = 0, tag_pos;
|
||||
Ecma119Image *target;
|
||||
int el_torito_writer_index = -1, file_src_writer_index= -1;
|
||||
int el_torito_writer_index = -1, file_src_writer_index = -1;
|
||||
int system_area_options = 0;
|
||||
char *system_area = NULL;
|
||||
|
||||
/* 1. Allocate target and copy opts there */
|
||||
target = calloc(1, sizeof(Ecma119Image));
|
||||
@ -1126,6 +1167,44 @@ 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;
|
||||
system_area_options = opts->system_area_options;
|
||||
} else if (src->system_area_data != NULL) {
|
||||
system_area = src->system_area_data;
|
||||
system_area_options = src->system_area_options;
|
||||
}
|
||||
target->system_area_data = NULL;
|
||||
if (system_area != NULL) {
|
||||
target->system_area_data = calloc(32768, 1);
|
||||
if (target->system_area_data == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto target_cleanup;
|
||||
}
|
||||
memcpy(target->system_area_data, system_area, 32768);
|
||||
}
|
||||
target->system_area_options = system_area_options;
|
||||
|
||||
target->vol_creation_time = opts->vol_creation_time;
|
||||
target->vol_modification_time = opts->vol_modification_time;
|
||||
target->vol_expiration_time = opts->vol_expiration_time;
|
||||
target->vol_effective_time = opts->vol_effective_time;
|
||||
strcpy(target->vol_uuid, opts->vol_uuid);
|
||||
|
||||
target->input_charset = strdup(iso_get_local_charset(0));
|
||||
if (target->input_charset == NULL) {
|
||||
@ -1689,6 +1768,14 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
||||
wopts->fifo_size = 1024; /* 2 MB buffer */
|
||||
wopts->sort_files = 1; /* file sorting is always good */
|
||||
|
||||
wopts->system_area_data = NULL;
|
||||
wopts->system_area_options = 0;
|
||||
wopts->vol_creation_time = 0;
|
||||
wopts->vol_modification_time = 0;
|
||||
wopts->vol_expiration_time = 0;
|
||||
wopts->vol_effective_time = 0;
|
||||
wopts->vol_uuid[0]= 0;
|
||||
|
||||
*opts = wopts;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
@ -1700,6 +1787,8 @@ void iso_write_opts_free(IsoWriteOpts *opts)
|
||||
}
|
||||
|
||||
free(opts->output_charset);
|
||||
if(opts->system_area_data != NULL)
|
||||
free(opts->system_area_data);
|
||||
free(opts);
|
||||
}
|
||||
|
||||
@ -1765,7 +1854,7 @@ int iso_write_opts_set_omit_version_numbers(IsoWriteOpts *opts, int omit)
|
||||
if (opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
opts->omit_version_numbers = omit ? 1 : 0;
|
||||
opts->omit_version_numbers = omit & 3;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1801,7 +1890,7 @@ int iso_write_opts_set_no_force_dots(IsoWriteOpts *opts, int no)
|
||||
if (opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
opts->no_force_dots = no ? 1 : 0;
|
||||
opts->no_force_dots = no & 3;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2085,3 +2174,43 @@ int iso_write_opts_get_data_start(IsoWriteOpts *opts, uint32_t *data_start,
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @param data Either NULL or 32 kB of data. Do not submit less bytes !
|
||||
* @param options bit0 = apply GRUB protective msdos label
|
||||
* @param flag bit0 = invalidate any attached system area data
|
||||
* same as data == NULL
|
||||
*/
|
||||
int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
|
||||
int options, int flag)
|
||||
{
|
||||
if (data == NULL || (flag & 1)) { /* Disable */
|
||||
if (opts->system_area_data != NULL)
|
||||
free(opts->system_area_data);
|
||||
opts->system_area_data = NULL;
|
||||
} else if (!(flag & 2)) {
|
||||
if (opts->system_area_data == NULL) {
|
||||
opts->system_area_data = calloc(32768, 1);
|
||||
if (opts->system_area_data == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
memcpy(opts->system_area_data, data, 32768);
|
||||
}
|
||||
if (!(flag & 4))
|
||||
opts->system_area_options = options & 3;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_pvd_times(IsoWriteOpts *opts,
|
||||
time_t vol_creation_time, time_t vol_modification_time,
|
||||
time_t vol_expiration_time, time_t vol_effective_time,
|
||||
char *vol_uuid)
|
||||
{
|
||||
opts->vol_creation_time = vol_creation_time;
|
||||
opts->vol_modification_time = vol_modification_time;
|
||||
opts->vol_expiration_time = vol_expiration_time;
|
||||
opts->vol_effective_time = vol_effective_time;
|
||||
strncpy(opts->vol_uuid, vol_uuid, 16);
|
||||
opts->vol_uuid[16] = 0;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -57,8 +57,10 @@ struct iso_write_opts {
|
||||
/**
|
||||
* Omit the version number (";1") at the end of the ISO-9660 identifiers.
|
||||
* Version numbers are usually not used.
|
||||
* bit0= ECMA-119 and Joliet (for historical reasons)
|
||||
* bit1= Joliet
|
||||
*/
|
||||
unsigned int omit_version_numbers :1;
|
||||
unsigned int omit_version_numbers :2;
|
||||
|
||||
/**
|
||||
* Allow ISO-9660 directory hierarchy to be deeper than 8 levels.
|
||||
@ -82,8 +84,10 @@ struct iso_write_opts {
|
||||
* ISO-9660 forces filenames to have a ".", that separates file name from
|
||||
* extension. libisofs adds it if original filename doesn't has one. Set
|
||||
* this to 1 to prevent this behavior
|
||||
* bit0= ECMA-119
|
||||
* bit1= Joliet
|
||||
*/
|
||||
unsigned int no_force_dots :1;
|
||||
unsigned int no_force_dots :2;
|
||||
|
||||
/**
|
||||
* Allow lowercase characters in ISO-9660 filenames. By default, only
|
||||
@ -298,6 +302,22 @@ struct iso_write_opts {
|
||||
*/
|
||||
char *scdbackup_tag_written;
|
||||
|
||||
/*
|
||||
* See ecma119_image : System Area related information
|
||||
*/
|
||||
char *system_area_data;
|
||||
int system_area_options;
|
||||
|
||||
/* User settable PVD time stamps */
|
||||
time_t vol_creation_time;
|
||||
time_t vol_modification_time;
|
||||
time_t vol_expiration_time;
|
||||
time_t vol_effective_time;
|
||||
/* To eventually override vol_creation_time and vol_modification_time
|
||||
* by unconverted string with timezone 0
|
||||
*/
|
||||
char vol_uuid[17];
|
||||
|
||||
};
|
||||
|
||||
typedef struct ecma119_image Ecma119Image;
|
||||
@ -328,11 +348,11 @@ struct ecma119_image
|
||||
unsigned int always_gmt :1;
|
||||
|
||||
/* relaxed constraints */
|
||||
unsigned int omit_version_numbers :1;
|
||||
unsigned int omit_version_numbers :2;
|
||||
unsigned int allow_deep_paths :1;
|
||||
unsigned int allow_longer_paths :1;
|
||||
unsigned int max_37_char_filenames :1;
|
||||
unsigned int no_force_dots :1;
|
||||
unsigned int no_force_dots :2;
|
||||
unsigned int allow_lowercase :1;
|
||||
unsigned int allow_full_ascii :1;
|
||||
|
||||
@ -434,7 +454,28 @@ 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
|
||||
*/
|
||||
/* Content of an embedded boot image. Valid if not NULL.
|
||||
* In that case it must point to a memory buffer at least 32 kB.
|
||||
*/
|
||||
char *system_area_data;
|
||||
/*
|
||||
* bit0= make bytes 446 - 512 of the system area a partition
|
||||
* table which reserves partition 1 from byte 63*512 to the
|
||||
* end of the ISO image. Assumed are 63 secs/hed, 255 head/cyl.
|
||||
* (GRUB protective msdos label.)
|
||||
* This works with and without system_area_data.
|
||||
* bit1= apply isohybrid MBR patching to the system area.
|
||||
* This works only with system_area_data plus ISOLINUX boot image
|
||||
* and only if not bit0 is set.
|
||||
*/
|
||||
int system_area_options;
|
||||
|
||||
/*
|
||||
* Number of pad blocks that we need to write. Padding blocks are blocks
|
||||
@ -492,6 +533,16 @@ struct ecma119_image
|
||||
/* writer thread descriptor */
|
||||
pthread_t wthread;
|
||||
pthread_attr_t th_attr;
|
||||
|
||||
/* User settable PVD time stamps */
|
||||
time_t vol_creation_time;
|
||||
time_t vol_modification_time;
|
||||
time_t vol_expiration_time;
|
||||
time_t vol_effective_time;
|
||||
/* To eventually override vol_creation_time and vol_modification_time
|
||||
* by unconverted string with timezone 0
|
||||
*/
|
||||
char vol_uuid[17];
|
||||
};
|
||||
|
||||
#define BP(a,b) [(b) - (a) + 1]
|
||||
|
@ -64,18 +64,18 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
||||
} else {
|
||||
if (img->max_37_char_filenames) {
|
||||
isoname = iso_r_fileid(ascii_name, 36, relaxed,
|
||||
img->no_force_dots ? 0 : 1);
|
||||
(img->no_force_dots & 1) ? 0 : 1);
|
||||
} else if (img->iso_level == 1) {
|
||||
if (relaxed) {
|
||||
isoname = iso_r_fileid(ascii_name, 11, relaxed,
|
||||
img->no_force_dots ? 0 : 1);
|
||||
(img->no_force_dots & 1) ? 0 : 1);
|
||||
} else {
|
||||
isoname = iso_1_fileid(ascii_name);
|
||||
}
|
||||
} else {
|
||||
if (relaxed) {
|
||||
isoname = iso_r_fileid(ascii_name, 30, relaxed,
|
||||
img->no_force_dots ? 0 : 1);
|
||||
(img->no_force_dots & 1) ? 0 : 1);
|
||||
} else {
|
||||
isoname = iso_2_fileid(ascii_name);
|
||||
}
|
||||
|
@ -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,10 +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->load_size = load_sectors;
|
||||
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;
|
||||
}
|
||||
@ -349,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;
|
||||
@ -413,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;
|
||||
|
||||
@ -437,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
|
||||
@ -481,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;
|
||||
@ -492,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.
|
||||
*
|
||||
@ -506,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);
|
||||
}
|
||||
|
||||
@ -538,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;
|
||||
@ -550,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) {
|
||||
@ -562,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;
|
||||
@ -599,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;
|
||||
}
|
||||
@ -757,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);
|
||||
@ -773,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);
|
||||
@ -808,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)
|
||||
{
|
||||
@ -826,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;
|
||||
@ -834,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;
|
||||
@ -856,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;
|
||||
}
|
||||
@ -867,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;
|
||||
@ -918,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;
|
||||
@ -949,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 */
|
||||
|
@ -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,25 +28,45 @@ 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
|
||||
* bit 1 -> whether to create isolinux image
|
||||
* bit 1 -> whether to put built-in isolinux 3.72 isohybrid-MBR into image
|
||||
* System Area (deprecated)
|
||||
*/
|
||||
unsigned int isolinux_options:2;
|
||||
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. */
|
||||
|
||||
/* 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 */
|
||||
@ -75,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 */
|
||||
@ -106,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 */
|
||||
|
@ -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
|
||||
@ -102,6 +102,12 @@ struct iso_read_opts
|
||||
*/
|
||||
int auto_input_charset;
|
||||
|
||||
|
||||
/**
|
||||
* Enable or disable loading of the first 32768 bytes of the session and
|
||||
* submission by iso_write_opts_set_system_area(data, 0).
|
||||
*/
|
||||
int load_system_area;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -273,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 */
|
||||
@ -2106,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 */
|
||||
@ -2128,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 */
|
||||
@ -2185,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;
|
||||
@ -2200,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;
|
||||
}
|
||||
|
||||
@ -2311,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;
|
||||
@ -2350,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;
|
||||
@ -2419,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;
|
||||
@ -2483,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++;
|
||||
@ -2607,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;
|
||||
@ -2719,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);
|
||||
@ -2731,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++;
|
||||
}
|
||||
}
|
||||
@ -2871,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;
|
||||
@ -2928,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;
|
||||
|
||||
@ -2946,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,
|
||||
§ion_count, §ions, 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;
|
||||
int ret, hflag, i, idx;
|
||||
IsoImageFilesystem *fs;
|
||||
IsoFilesystem *fsback;
|
||||
IsoNodeBuilder *blback;
|
||||
@ -2959,9 +3125,11 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
IsoFileSource *newroot;
|
||||
_ImageFsData *data;
|
||||
struct el_torito_boot_catalog *oldbootcat;
|
||||
uint8_t *rpt;
|
||||
IsoFileSource *boot_src;
|
||||
IsoNode *node;
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
int i;
|
||||
uint32_t old_checksum_start_lba;
|
||||
uint32_t old_checksum_end_lba;
|
||||
uint32_t old_checksum_idx_count;
|
||||
@ -2969,7 +3137,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
char checksum_type[81];
|
||||
uint32_t checksum_size;
|
||||
size_t size;
|
||||
uint8_t *rpt;
|
||||
void *ctx = NULL;
|
||||
char md5[16];
|
||||
#endif
|
||||
@ -2978,12 +3145,30 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
|
||||
ret = iso_image_filesystem_new(src, opts, image->id, &fs);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
data = fs->data;
|
||||
|
||||
|
||||
if (opts->load_system_area) {
|
||||
if (image->system_area_data != NULL)
|
||||
free(image->system_area_data);
|
||||
image->system_area_data = calloc(32768, 1);
|
||||
if (image->system_area_data == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
image->system_area_options = 0;
|
||||
/* Read 32768 bytes */
|
||||
for (i = 0; i < 16; i++) {
|
||||
rpt = (uint8_t *) (image->system_area_data + i * 2048);
|
||||
ret = src->read_block(src, opts->block + i, rpt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* get root from filesystem */
|
||||
ret = fs->get_root(fs, &newroot);
|
||||
if (ret < 0) {
|
||||
@ -3048,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;
|
||||
}
|
||||
|
||||
@ -3098,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,
|
||||
@ -3221,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;
|
||||
|
||||
@ -3332,8 +3534,9 @@ int iso_read_opts_new(IsoReadOpts **opts, int profile)
|
||||
|
||||
ropts->file_mode = 0444;
|
||||
ropts->dir_mode = 0555;
|
||||
ropts->noaaip= 1;
|
||||
ropts->nomd5= 1;
|
||||
ropts->noaaip = 1;
|
||||
ropts->nomd5 = 1;
|
||||
ropts->load_system_area = 0;
|
||||
|
||||
*opts = ropts;
|
||||
return ISO_SUCCESS;
|
||||
@ -3469,6 +3672,15 @@ int iso_read_opts_auto_input_charset(IsoReadOpts *opts, int mode)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_read_opts_load_system_area(IsoReadOpts *opts, int mode)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
opts->load_system_area = mode & 1;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy an IsoReadImageFeatures object obtained with iso_image_import.
|
||||
*/
|
||||
|
@ -74,6 +74,8 @@ int iso_image_new(const char *name, IsoImage **image)
|
||||
img->volset_id = strdup(name);
|
||||
img->volume_id = strdup(name);
|
||||
}
|
||||
img->system_area_data = NULL;
|
||||
img->system_area_options = 0;
|
||||
img->builder_ignore_acl = 1;
|
||||
img->builder_ignore_ea = 1;
|
||||
img->inode_counter = 0;
|
||||
@ -331,6 +333,16 @@ int iso_image_get_msg_id(IsoImage *image)
|
||||
return image->id;
|
||||
}
|
||||
|
||||
int iso_image_get_system_area(IsoImage *img, char system_area_data[32768],
|
||||
int *options, int flag)
|
||||
{
|
||||
*options = img->system_area_options;
|
||||
if (img->system_area_data == NULL)
|
||||
return 0;
|
||||
memcpy(system_area_data, img->system_area_data, 32768);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int dir_update_size(IsoImage *image, IsoDir *dir)
|
||||
{
|
||||
|
@ -53,6 +53,11 @@ struct Iso_Image
|
||||
/* el-torito boot catalog */
|
||||
struct el_torito_boot_catalog *bootcat;
|
||||
|
||||
/* Eventually loaded system area data, or NULL */
|
||||
char *system_area_data;
|
||||
/* Prescribed/detected options, see iso_write_opts_set_system_area() */
|
||||
int system_area_options;
|
||||
|
||||
/* image identifier, for message origin identifier */
|
||||
int id;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -43,7 +43,7 @@ int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
|
||||
if (iso->type == LIBISO_DIR) {
|
||||
jname = iso_j_dir_id(ucs_name);
|
||||
} else {
|
||||
jname = iso_j_file_id(ucs_name);
|
||||
jname = iso_j_file_id(ucs_name, !!(t->no_force_dots & 2));
|
||||
}
|
||||
free(ucs_name);
|
||||
if (jname != NULL) {
|
||||
@ -574,7 +574,7 @@ size_t calc_dirent_len(Ecma119Image *t, JolietNode *n)
|
||||
{
|
||||
/* note than name len is always even, so we always need the pad byte */
|
||||
int ret = n->name ? ucslen(n->name) * 2 + 34 : 34;
|
||||
if (n->type == JOLIET_FILE && !t->omit_version_numbers) {
|
||||
if (n->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
|
||||
/* take into account version numbers */
|
||||
ret += 4;
|
||||
}
|
||||
@ -722,7 +722,7 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
|
||||
|
||||
memcpy(rec->file_id, name, len_fi);
|
||||
|
||||
if (node->type == JOLIET_FILE && !t->omit_version_numbers) {
|
||||
if (node->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
|
||||
len_dr += 4;
|
||||
rec->file_id[len_fi++] = 0;
|
||||
rec->file_id[len_fi++] = ';';
|
||||
@ -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);
|
||||
@ -899,7 +899,7 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
|
||||
/* compute len of directory entry */
|
||||
fi_len = ucslen(child->name) * 2;
|
||||
len = fi_len + 34;
|
||||
if (child->type == JOLIET_FILE && !t->omit_version_numbers) {
|
||||
if (child->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
|
||||
len += 4;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* Applications must use 64 bit off_t, e.g. on 32-bit Linux by defining
|
||||
* Applications must use 64 bit off_t, e.g. on 32-bit GNU/Linux by defining
|
||||
* #define _LARGEFILE_SOURCE
|
||||
* #define _FILE_OFFSET_BITS 64
|
||||
* or take special precautions to interface with the library by 64 bit integers
|
||||
@ -374,7 +374,7 @@ extern unsigned int iso_fs_global_id;
|
||||
* access and read file contents. Note that this doesn't need to be tied
|
||||
* to the disc filesystem used in the partition being accessed. For example,
|
||||
* we have an IsoFilesystem implementation to access any mounted filesystem,
|
||||
* using standard Linux functions. It is also legal, of course, to implement
|
||||
* using standard POSIX functions. It is also legal, of course, to implement
|
||||
* an IsoFilesystem to deal with a specific filesystem over raw partitions.
|
||||
* That is what we do, for example, to access an ISO Image.
|
||||
*
|
||||
@ -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 28
|
||||
#define iso_lib_header_version_micro 32
|
||||
|
||||
/**
|
||||
* Usage discussion:
|
||||
@ -1286,7 +1286,9 @@ int iso_write_opts_set_aaip(IsoWriteOpts *opts, int enable);
|
||||
* Omit the version number (";1") at the end of the ISO-9660 identifiers.
|
||||
* This breaks ECMA-119 specification, but version numbers are usually not
|
||||
* used, so it should work on most systems. Use with caution.
|
||||
*
|
||||
* @param omit
|
||||
* bit0= omit version number with ECMA-119 and Joliet
|
||||
* bit1= omit version number with Joliet alone (@since 0.6.30)
|
||||
* @since 0.6.2
|
||||
*/
|
||||
int iso_write_opts_set_omit_version_numbers(IsoWriteOpts *opts, int omit);
|
||||
@ -1324,6 +1326,9 @@ int iso_write_opts_set_max_37_char_filenames(IsoWriteOpts *opts, int allow);
|
||||
* extension. libisofs adds it if original filename doesn't has one. Set
|
||||
* this to 1 to prevent this behavior.
|
||||
* This breaks ECMA-119 specification. Use with caution.
|
||||
* @param no
|
||||
* bit0= no forced dot with ECMA-119
|
||||
* bit1= no forced dot with Joliet (@since 0.6.30)
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
@ -1680,6 +1685,75 @@ int iso_write_opts_set_overwrite_buf(IsoWriteOpts *opts, uint8_t *overwrite);
|
||||
*/
|
||||
int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
|
||||
|
||||
/*
|
||||
* Attach 32 kB of binary data which shall get written to the first 32 kB
|
||||
* of the ISO image, the ECMA-119 System Area. This space is intended for
|
||||
* system dependent boot software, e.g. a Master Boot Record which allows to
|
||||
* boot from USB sticks or hard disks. ECMA-119 makes no own assumptions or
|
||||
* prescriptions about the byte content.
|
||||
*
|
||||
* If system area data are given or options bit0 is set, then bit1 of
|
||||
* el_torito_set_isolinux_options() is automatically disabled.
|
||||
* @param data
|
||||
* Either NULL or 32 kB of data. Do not submit less bytes !
|
||||
* @param options
|
||||
* Can cause manipulations of submitted data before they get written:
|
||||
* bit0= apply a --protective-msdos-label as of grub-mkisofs.
|
||||
* This means to patch bytes 446 to 512 of the system area so
|
||||
* that one partition is defined which begins at the second
|
||||
* 512-byte block of the image and ends where the image ends.
|
||||
* This works with and without system_area_data.
|
||||
* bit1= apply isohybrid MBR patching to the system area.
|
||||
* This works only with system area data from SYSLINUX plus an
|
||||
* ISOLINUX boot image (see iso_image_set_boot_image()) and
|
||||
* only if not bit0 is set.
|
||||
* @param flag
|
||||
* bit0 = invalidate any attached system area data. Same as data == NULL
|
||||
* (This re-activates eventually loaded image System Area data.
|
||||
* To erase those, submit 32 kB of zeros without flag bit0.)
|
||||
* bit1 = keep data unaltered
|
||||
* bit2 = keep options unaltered
|
||||
* @return
|
||||
* ISO_SUCCESS or error
|
||||
* @since 0.6.30
|
||||
*/
|
||||
int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
|
||||
int options, int flag);
|
||||
|
||||
/**
|
||||
* Explicitely set the four timestamps of the emerging Primary Volume
|
||||
* Descriptor. Default with all parameters is 0.
|
||||
* ECMA-119 defines them as:
|
||||
* @param vol_creation_time
|
||||
* When "the information in the volume was created."
|
||||
* A value of 0 means that the timepoint of write start is to be used.
|
||||
* @param vol_modification_time
|
||||
* When "the information in the volume was last modified."
|
||||
* A value of 0 means that the timepoint of write start is to be used.
|
||||
* @param vol_expiration_time
|
||||
* When "the information in the volume may be regarded as obsolete."
|
||||
* A value of 0 means that the information never shall expire.
|
||||
* @param vol_effective_time
|
||||
* When "the information in the volume may be used."
|
||||
* A value of 0 means that not such retention is intended.
|
||||
* @param uuid
|
||||
* If this text is not empty, then it overrides vol_creation_time and
|
||||
* vol_modification_time by copying the first 16 decimal digits from
|
||||
* uuid, eventually padding up with decimal '1', and writing a NUL-byte
|
||||
* as timezone.
|
||||
* Other than with vol_*_time the resulting string in the ISO image
|
||||
* is fully predictable and free of timezone pitfalls.
|
||||
* It should express a reasonable time in form YYYYMMDDhhmmsscc
|
||||
* E.g.: "2010040711405800" = 7 Apr 2010 11:40:58 (+0 centiseconds)
|
||||
*
|
||||
* @since 0.6.30
|
||||
*/
|
||||
int iso_write_opts_set_pvd_times(IsoWriteOpts *opts,
|
||||
time_t vol_creation_time, time_t vol_modification_time,
|
||||
time_t vol_expiration_time, time_t vol_effective_time,
|
||||
char *vol_uuid);
|
||||
|
||||
|
||||
/**
|
||||
* Inquire the start address of the file data blocks after having used
|
||||
* IsoWriteOpts with iso_image_create_burn_source().
|
||||
@ -1922,6 +1996,20 @@ int iso_read_opts_set_input_charset(IsoReadOpts *opts, const char *charset);
|
||||
*/
|
||||
int iso_read_opts_auto_input_charset(IsoReadOpts *opts, int mode);
|
||||
|
||||
/**
|
||||
* Enable or disable loading of the first 32768 bytes of the session.
|
||||
*
|
||||
* @param mode
|
||||
* Bitfield for control purposes:
|
||||
* bit0= Load System Area data and attach them to the image so that they
|
||||
* get written by the next session, if not overridden by
|
||||
* iso_write_opts_set_system_area().
|
||||
* Submit any other bits with value 0.
|
||||
*
|
||||
* @since 0.6.30
|
||||
*
|
||||
*/
|
||||
int iso_read_opts_load_system_area(IsoReadOpts *opts, int mode);
|
||||
|
||||
/**
|
||||
* Import a previous session or image, for growing or modify.
|
||||
@ -2195,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
|
||||
@ -2237,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
|
||||
@ -2278,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.
|
||||
@ -2289,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.
|
||||
@ -2297,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
|
||||
@ -2306,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
|
||||
*
|
||||
@ -2314,30 +2549,131 @@ 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);
|
||||
|
||||
/**
|
||||
* Specifies options for IsoLinux boot images. This should only be used with
|
||||
* isolinux boot images.
|
||||
* 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
|
||||
* if the type of boot image is known.
|
||||
*
|
||||
* @param options
|
||||
* bitmask style flag. The following values are defined:
|
||||
*
|
||||
* bit 0 -> 1 to patch the image, 0 to not
|
||||
* 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 will not be modified. This is
|
||||
* needed to allow isolinux images to be bootable.
|
||||
* bit 1 -> 1 to generate an hybrid image with MBR, 0 to not
|
||||
* An hybrid image is a boot image that boots from either
|
||||
* 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 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:
|
||||
* The author of syslinux, H. Peter Anvin requested that this
|
||||
* feature shall not be used any more. He intends to cease
|
||||
* support for the MBR template that is included in libisofs.
|
||||
* ----------------------------------------------------------
|
||||
* A hybrid image is a boot image that boots from either
|
||||
* CD/DVD media or from disk-like media, e.g. USB stick.
|
||||
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
|
||||
* IMPORTANT: The application has to take care that the image
|
||||
@ -2348,7 +2684,55 @@ 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
|
||||
* session, the System Area.
|
||||
* It will be written to the start of the next session unless it gets
|
||||
* overwritten by iso_write_opts_set_system_area().
|
||||
*
|
||||
* @param img
|
||||
* The image to be inquired.
|
||||
* @param data
|
||||
* A byte array of at least 32768 bytesi to take the loaded bytes.
|
||||
* @param options
|
||||
* The option bits which will be applied if not overridden by
|
||||
* iso_write_opts_set_system_area(). See there.
|
||||
* @param flag
|
||||
* Bitfield for control purposes, unused yet, submit 0
|
||||
* @return
|
||||
* 1 on success, 0 if no System Area was loaded, < 0 error.
|
||||
* @since 0.6.30
|
||||
*/
|
||||
int iso_image_get_system_area(IsoImage *img, char data[32768],
|
||||
int *options, int flag);
|
||||
|
||||
/**
|
||||
* Increments the reference counting of the given node.
|
||||
@ -2576,14 +2960,14 @@ time_t iso_node_get_ctime(const IsoNode *node);
|
||||
/**
|
||||
* Set if the node will be hidden in RR/ISO tree, Joliet tree or both.
|
||||
*
|
||||
* If the file is set as hidden in one tree, it won't be included there, so
|
||||
* If the file is set as hidden in one tree, it wil not be included there, so
|
||||
* it won't be visible in a OS accessing CD using that tree. For example,
|
||||
* GNU/Linux systems access to Rock Ridge / ISO9960 tree in order to see
|
||||
* what is recorded on CD, while MS Windows make use of the Joliet tree. If a
|
||||
* file is hidden only in Joliet, it won't be visible in Windows systems,
|
||||
* while still visible in Linux.
|
||||
* file is hidden only in Joliet, it wil not be visible in Windows systems,
|
||||
* while still visible in GNU/Linux.
|
||||
*
|
||||
* If a file is hidden in both trees, it won't be written to image.
|
||||
* If a file is hidden in both trees, it will not be written to image.
|
||||
*
|
||||
* @param node
|
||||
* The node that is to be hidden.
|
||||
@ -3034,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
|
||||
@ -3044,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
|
||||
*/
|
||||
@ -4364,7 +4749,7 @@ int aaip_xinfo_func(void *data, int flag);
|
||||
* @param default_text
|
||||
* Will return a pointer to the eventual "default" ACL or NULL if it
|
||||
* is not available.
|
||||
* (Linux directories can have a "default" ACL which influences
|
||||
* (GNU/Linux directories can have a "default" ACL which influences
|
||||
* the permissions of newly created files.)
|
||||
* @param flag
|
||||
* Bitfield for control purposes
|
||||
@ -4401,7 +4786,7 @@ int iso_node_get_acl_text(IsoNode *node,
|
||||
* @param default_text
|
||||
* The text to be set into effect as "default" ACL. NULL will delete an
|
||||
* eventually existing "default" ACL of the node.
|
||||
* (Linux directories can have a "default" ACL which influences
|
||||
* (GNU/Linux directories can have a "default" ACL which influences
|
||||
* the permissions of newly created files.)
|
||||
* @param flag
|
||||
* Bitfield for control purposes
|
||||
@ -5322,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)
|
||||
@ -5423,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
|
||||
|
@ -10,6 +10,7 @@
|
||||
/* for gettimeofday() */
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
|
||||
under GPL which is Copyright 2002-2008 H. Peter Anvin.
|
||||
|
||||
@ -25,13 +26,13 @@ and is now under the licenses to which H.Peter Anvin agreed:
|
||||
or both, at your option.
|
||||
Sincerely, H. Peter Anvin
|
||||
|
||||
In the context of xorriso-standalone, this code is under GPLv2 derived from
|
||||
LGPL. In the context of libisofs this code derives its matching open source
|
||||
In the context of GNU xorriso, this code is under GPLv3+ derived from LGPL.
|
||||
In the context of libisofs this code derives its matching free software
|
||||
license from above stem licenses, typically from LGPL.
|
||||
In case its generosity is needed, here is the 2-clause BSD license:
|
||||
|
||||
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
|
||||
and 2008-2009 libburnia project.
|
||||
and 2008-2010 Thomas Schmitt
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
@ -51,8 +52,9 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* A helper function. One could replace it by one or two macros. */
|
||||
static int lsb_to_buf(char **wpt, int value, int bits, int flag)
|
||||
static int lsb_to_buf(char **wpt, uint32_t value, int bits, int flag)
|
||||
{
|
||||
int b;
|
||||
|
||||
@ -61,6 +63,11 @@ static int lsb_to_buf(char **wpt, int value, int bits, int flag)
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================== */
|
||||
/* Deprecated Function */
|
||||
/* ====================================================================== */
|
||||
|
||||
/*
|
||||
* Create a MBR for an isohybrid enabled ISOLINUX boot image.
|
||||
*
|
||||
@ -228,3 +235,214 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================== */
|
||||
/* The New MBR Producer */
|
||||
/* ====================================================================== */
|
||||
|
||||
/* The new MBR producer for isohybrid is a slightly generalized version of
|
||||
the deprecated function make_isohybrid_mbr(). It complies to the urge
|
||||
of H.Peter Anvin not to hardcode MBR templates but rather to read a
|
||||
file from the Syslinux tree, and to patch it as was done with the old
|
||||
MBR producer.
|
||||
|
||||
The old algorithm was clarified publicly by the following mail.
|
||||
Changes towards the old algorithm:
|
||||
- 512-byte LBA of boot image is extended to 64 bit (we stay with 32)
|
||||
- check for a magic number is now gone
|
||||
|
||||
The new implementation tries to use similar terms as the mail in order
|
||||
to facilitate its future discussion with Syslinux developers.
|
||||
|
||||
From hpa@zytor.com Thu Apr 1 08:32:52 2010
|
||||
Date: Wed, 31 Mar 2010 14:53:51 -0700
|
||||
From: H. Peter Anvin <hpa@zytor.com>
|
||||
To: For discussion of Syslinux and tftp-hpa <syslinux@zytor.com>
|
||||
Cc: Thomas Schmitt <scdbackup@gmx.net>
|
||||
Subject: Re: [syslinux] port syslinux isohybrid perl script to C
|
||||
|
||||
[...]
|
||||
|
||||
[me:]
|
||||
> Currently i lack of blob and prescriptions.
|
||||
|
||||
The blobs are available in the Syslinux build tree under the names:
|
||||
|
||||
mbr/isohdp[fp]x*.bin
|
||||
|
||||
The default probably should be mbr/isohdppx.bin, but it's ultimately up
|
||||
to the user.
|
||||
|
||||
User definable parameters:
|
||||
|
||||
-> MBR ID (default random 32-bit number,
|
||||
or preserved from previous instance)
|
||||
-> Sector count (default 32, range 1-63)
|
||||
-> Head count (default 64, range 1-256)
|
||||
-> Partition offset (default 0, range 0-64)
|
||||
-> Partition number (default 1, range 1-4)
|
||||
-> Filesystem type (default 0x17, range 1-255)
|
||||
|
||||
Note: the filesystem type is largely arbitrary, in theory it can be any
|
||||
value other than 0x00, 0x05, 0x0f, 0x85, 0xee, or 0xef. 0x17 ("Windows
|
||||
IFS Hidden") seems safeish, some people believe 0x83 (Linux) is better.
|
||||
|
||||
Here is the prescriptions for how to install it:
|
||||
|
||||
All numbers are littleendian. "word" means 16 bits, "dword" means 32
|
||||
bits, "qword" means 64 bits.
|
||||
|
||||
Common subroutine LBA_to_CHS():
|
||||
s = (lba % sector_count) + 1
|
||||
t = (lba / sector_count)
|
||||
h = (t % head_count)
|
||||
c = (t / head_count)
|
||||
|
||||
if (c >= 1024):
|
||||
c = 1023
|
||||
h = head_count
|
||||
s = sector_count
|
||||
|
||||
s = s | ((c & 0x300) >> 2)
|
||||
c = c & 0xff
|
||||
|
||||
write byte h
|
||||
write byte s
|
||||
write byte c
|
||||
|
||||
Main:
|
||||
Pad image_size to a multiple of sector_count*head_count
|
||||
Use the input file unmodified for bytes 0..431
|
||||
write qword boot_lba # Offset 432
|
||||
write dword mbr_id # Offset 440
|
||||
write word 0 # Offset 444
|
||||
|
||||
# Offset 446
|
||||
For each partition entry 1..4:
|
||||
if this_partition != partition_number:
|
||||
write 16 zero bytes
|
||||
else:
|
||||
write byte 0x80
|
||||
write LBA_to_CHS(partition_offset)
|
||||
write byte filesystem_type
|
||||
write LBA_to_CHS(image_size-1)
|
||||
write dword partition_offset
|
||||
write dword image_size
|
||||
|
||||
# Offset 510
|
||||
write word 0xaa55
|
||||
|
||||
Use the input file unmodified for bytes 512..32767
|
||||
(pad with zero as necessary)
|
||||
|
||||
[...]
|
||||
|
||||
-hpa
|
||||
*/
|
||||
|
||||
|
||||
static
|
||||
int lba512chs_to_buf(char **wpt, off_t lba, int head_count, int sector_count)
|
||||
{
|
||||
int s, t, h, c;
|
||||
|
||||
s = (lba % sector_count) + 1;
|
||||
t = (lba / sector_count);
|
||||
h = (t % head_count);
|
||||
c = (t / head_count);
|
||||
if (c >= 1024) {
|
||||
c = 1023;
|
||||
h = head_count; /* >>> not -1 ? Limits head_count to 255 */
|
||||
s = sector_count;
|
||||
}
|
||||
s = s | ((c & 0x300) >> 2);
|
||||
c = c & 0xff;
|
||||
(*((unsigned char **) wpt))[0] = h;
|
||||
(*((unsigned char **) wpt))[1] = s;
|
||||
(*((unsigned char **) wpt))[2] = c;
|
||||
(*wpt)+= 3;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @param flag bit0= make own random MBR Id from current time
|
||||
*/
|
||||
int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
||||
uint32_t mbr_id, int head_count, int sector_count,
|
||||
int part_offset, int part_number, int fs_type,
|
||||
uint8_t *buf, int flag)
|
||||
{
|
||||
uint32_t spc, id, part, nominal_part_size;
|
||||
off_t hd_img_blocks, hd_boot_lba;
|
||||
char *wpt;
|
||||
/* For generating a weak random number */
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
/* Pad image_size to a multiple of sector_count*head_count
|
||||
*/
|
||||
spc = head_count * sector_count;
|
||||
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
|
||||
if (hd_img_blocks % spc) {
|
||||
hd_img_blocks += spc - (hd_img_blocks % spc);
|
||||
*img_blocks = hd_img_blocks / 4 + !!(hd_img_blocks % 4);
|
||||
}
|
||||
|
||||
wpt = (char *) buf + 432;
|
||||
|
||||
/* write qword boot_lba # Offset 432
|
||||
*/
|
||||
hd_boot_lba = ((off_t) boot_lba) * (off_t) 4;
|
||||
lsb_to_buf(&wpt, hd_boot_lba & 0xffffffff, 32, 0);
|
||||
lsb_to_buf(&wpt, hd_boot_lba >> 32, 32, 0);
|
||||
|
||||
/* write dword mbr_id # Offset 440
|
||||
(here some 32-bit random value with no crypto strength)
|
||||
*/
|
||||
if (flag & 1) {
|
||||
gettimeofday(&tv, &tz);
|
||||
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
|
||||
lsb_to_buf(&wpt, id, 32, 0);
|
||||
}
|
||||
|
||||
/* write word 0 # Offset 444
|
||||
*/
|
||||
lsb_to_buf(&wpt, 0, 16, 0);
|
||||
|
||||
/* # Offset 446
|
||||
*/
|
||||
for (part = 1 ; part <= 4; part++) {
|
||||
if (part != part_number) {
|
||||
/* if this_partition != partition_number: write 16 zero bytes */
|
||||
memset(wpt, 0, 16);
|
||||
wpt+= 16;
|
||||
continue;
|
||||
}
|
||||
/* write byte 0x80
|
||||
write LBA_to_CHS(partition_offset)
|
||||
write byte filesystem_type
|
||||
write LBA_to_CHS(image_size-1)
|
||||
write dword partition_offset
|
||||
write dword image_size
|
||||
*/
|
||||
lsb_to_buf(&wpt, 0x80, 8, 0);
|
||||
lba512chs_to_buf(&wpt, part_offset, head_count, sector_count);
|
||||
lsb_to_buf(&wpt, fs_type, 8, 0);
|
||||
lba512chs_to_buf(&wpt, hd_img_blocks - 1, head_count, sector_count);
|
||||
lsb_to_buf(&wpt, part_offset, 32, 0);
|
||||
if (hd_img_blocks - (off_t) part_offset > (off_t) 0xffffffff)
|
||||
nominal_part_size = 0xffffffff;
|
||||
else
|
||||
nominal_part_size = hd_img_blocks - (off_t) part_offset;
|
||||
lsb_to_buf(&wpt, nominal_part_size, 32, 0);
|
||||
}
|
||||
|
||||
/* write word 0xaa55 # Offset 510
|
||||
*/
|
||||
lsb_to_buf(&wpt, 0xaa55, 16, 0);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2008 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
|
||||
@ -12,28 +13,114 @@
|
||||
#include "filesrc.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/*
|
||||
* Create a MBR for an isohybrid enabled ISOLINUX boot image.
|
||||
*
|
||||
* It is assumed that the caller has verified the readiness of the boot image
|
||||
* by checking for 0xfb 0xc0 0x78 0x70 at bytes 0x40 to 0x43 of isolinux.bin.
|
||||
*
|
||||
* @param bin_lba The predicted LBA of isolinux.bin within the emerging ISO.
|
||||
* @param img_blocks The predicted number of 2048 byte blocks in the ISO.
|
||||
* It will get rounded up to full MBs and that many blocks
|
||||
* must really be written as ISO 9660 image.
|
||||
* @param mbr A buffer of at least 512 bytes to take the result which is
|
||||
* to be written as the very beginning of the ISO.
|
||||
* @param flag unused yet, submit 0
|
||||
* @return <0 = fatal, 0 = failed , 1 = ok , 2 = ok with size warning
|
||||
* See libisofs/make_isohybrid_mbr.c
|
||||
* Deprecated.
|
||||
*/
|
||||
int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
|
||||
|
||||
/*
|
||||
* The New ISOLINUX MBR Producer.
|
||||
* Be cautious with changing parameters. Only few combinations are tested.
|
||||
*
|
||||
*/
|
||||
int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
||||
uint32_t mbr_id, int head_count, int sector_count,
|
||||
int part_offset, int part_number, int fs_type,
|
||||
uint8_t *buf, int flag);
|
||||
|
||||
|
||||
/* This is the gesture of grub-mkisofs --protective-msdos-label as explained by
|
||||
Vladimir Serbinenko <phcoder@gmail.com>, 2 April 2010, on grub-devel@gnu.org
|
||||
"Currently we use first and not last entry. You need to:
|
||||
1) Zero-fill 446-510
|
||||
2) Put 0x55, 0xAA into 510-512
|
||||
3) Put 0x80 (for bootable partition), 0, 2, 0 (C/H/S of the start), 0xcd
|
||||
(partition type), [3 bytes of C/H/S end], 0x01, 0x00, 0x00, 0x00 (LBA
|
||||
start in little endian), [LBA end in little endian] at 446-462
|
||||
"
|
||||
|
||||
"C/H/S end" means the CHS address of the last block in the partition.
|
||||
It seems that not "[LBA end in little endian]" but "number of blocks"
|
||||
should go into bytes 458-461. But with a start lba of 1, this is the
|
||||
same number.
|
||||
See also http://en.wikipedia.org/wiki/Master_boot_record
|
||||
*/
|
||||
static
|
||||
int make_grub_msdos_label(int img_blocks, uint8_t *buf, int flag)
|
||||
{
|
||||
uint8_t *wpt;
|
||||
unsigned long end_lba, secs, end_sec, end_head, end_cyl;
|
||||
int sph = 63, hpc = 255, i;
|
||||
|
||||
/* Partition table unit is 512 bytes per sector, ECMA-119 unit is 2048 */
|
||||
if (img_blocks >= 0x40000000)
|
||||
img_blocks = 0x40000000 - 1; /* truncate rather than roll over */
|
||||
secs = end_lba = img_blocks * 4 - 1; /* last valid 512-lba */
|
||||
end_cyl = secs / (sph * hpc);
|
||||
secs -= end_cyl * sph * hpc;
|
||||
end_head = secs / sph;
|
||||
end_sec = secs - end_head * sph + 1; /* Sector count starts by 1 */
|
||||
if (end_cyl >= 1024) {
|
||||
end_cyl = 1023;
|
||||
end_head = hpc - 1;
|
||||
end_sec = sph;
|
||||
}
|
||||
|
||||
/* 1) Zero-fill 446-510 */
|
||||
wpt = buf + 446;
|
||||
memset(wpt, 0, 64);
|
||||
|
||||
/* 2) Put 0x55, 0xAA into 510-512 (actually 510-511) */
|
||||
buf[510] = 0x55;
|
||||
buf[511] = 0xAA;
|
||||
|
||||
/* 3) Put 0x80 (for bootable partition), */
|
||||
*(wpt++) = 0x80;
|
||||
|
||||
/* 0, 2, 0 (C/H/S of the start), */
|
||||
*(wpt++) = 0;
|
||||
*(wpt++) = 2;
|
||||
*(wpt++) = 0;
|
||||
|
||||
/* 0xcd (partition type) */
|
||||
*(wpt++) = 0xcd;
|
||||
|
||||
/* [3 bytes of C/H/S end], */
|
||||
*(wpt++) = end_head;
|
||||
*(wpt++) = end_sec | ((end_cyl & 0x300) >> 2);
|
||||
*(wpt++) = end_cyl & 0xff;
|
||||
|
||||
|
||||
/* 0x01, 0x00, 0x00, 0x00 (LBA start in little endian), */
|
||||
*(wpt++) = 0x01;
|
||||
*(wpt++) = 0x00;
|
||||
*(wpt++) = 0x00;
|
||||
*(wpt++) = 0x00;
|
||||
|
||||
/* [LBA end in little endian] */
|
||||
for (i = 0; i < 4; i++)
|
||||
*(wpt++) = (end_lba >> (8 * i)) & 0xff;
|
||||
|
||||
/* at 446-462 */
|
||||
if (wpt - buf != 462) {
|
||||
fprintf(stderr,
|
||||
"libisofs: program error in make_grub_msdos_label: \"assert 462\"\n");
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
{
|
||||
int ret;
|
||||
int img_blocks;
|
||||
|
||||
if ((t == NULL) || (buf == NULL)) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
@ -41,26 +128,41 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
/* set buf to 0s */
|
||||
memset(buf, 0, 16 * BLOCK_SIZE);
|
||||
|
||||
if (t->catalog != NULL && t->catalog->image->isolinux_options & 0x02) {
|
||||
/* We need to write a MBR for an hybrid image */
|
||||
int ret;
|
||||
int img_blocks;
|
||||
|
||||
img_blocks = t->curblock;
|
||||
ret = make_isohybrid_mbr(t->bootimg->sections[0].block, &img_blocks, (char*)buf, 0);
|
||||
|
||||
/*
|
||||
API description of el_torito_set_isolinux_options() prescribes
|
||||
to pad to full MB.
|
||||
So this is not urgent any more :
|
||||
|
||||
// FIXME the new img_blocks size should be taken into account
|
||||
*/
|
||||
img_blocks = t->curblock;
|
||||
if (t->system_area_data != NULL) {
|
||||
/* Write more or less opaque boot image */
|
||||
memcpy(buf, t->system_area_data, 16 * BLOCK_SIZE);
|
||||
|
||||
} else if (t->catalog != NULL &&
|
||||
(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->bootsrc[0]->sections[0].block,
|
||||
&img_blocks, (char*)buf, 0);
|
||||
if (ret != 1) {
|
||||
/* error, it should never happen */
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
if (t->system_area_options & 1) {
|
||||
/* Write GRUB protective msdos label, i.e. a isimple partition table */
|
||||
ret = make_grub_msdos_label(img_blocks, buf, 0);
|
||||
if (ret != 1) /* error should never happen */
|
||||
return ISO_ASSERT_FAILURE;
|
||||
} else if(t->system_area_options & 2) {
|
||||
/* Patch externally provided system area as isohybrid MBR */
|
||||
if (t->catalog == NULL || t->system_area_data == NULL) {
|
||||
/* isohybrid makes only sense together with ISOLINUX boot image
|
||||
and externally provided System Area.
|
||||
*/
|
||||
return ISO_ISOLINUX_CANT_PATCH;
|
||||
}
|
||||
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;
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
@ -908,7 +908,10 @@ ex:;
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint16_t *iso_j_file_id(const uint16_t *src)
|
||||
/*
|
||||
bit0= no_force_dots
|
||||
*/
|
||||
uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||
{
|
||||
uint16_t *dot;
|
||||
size_t lname, lext, lnname, lnext, pos, i;
|
||||
@ -954,6 +957,10 @@ uint16_t *iso_j_file_id(const uint16_t *src)
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((flag & 1) && lnext <= 0)
|
||||
goto is_done;
|
||||
|
||||
set_ucsbe(dest + pos, '.');
|
||||
pos++;
|
||||
|
||||
@ -967,6 +974,8 @@ uint16_t *iso_j_file_id(const uint16_t *src)
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
is_done:;
|
||||
set_ucsbe(dest + pos, '\0');
|
||||
return ucsdup(dest);
|
||||
}
|
||||
@ -1206,7 +1215,7 @@ void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt)
|
||||
}
|
||||
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
tm.tm_isdst = -1; /* some Linuxes change tm_isdst only if it is -1 */
|
||||
tm.tm_isdst = -1; /* some OSes change tm_isdst only if it is -1 */
|
||||
localtime_r(&t, &tm);
|
||||
|
||||
#ifdef HAVE_TM_GMTOFF
|
||||
@ -1250,7 +1259,7 @@ void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt)
|
||||
}
|
||||
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
tm.tm_isdst = -1; /* some Linuxes change tm_isdst only if it is -1 */
|
||||
tm.tm_isdst = -1; /* some OSes change tm_isdst only if it is -1 */
|
||||
localtime_r(&t, &tm);
|
||||
|
||||
localtime_r(&t, &tm);
|
||||
|
@ -151,11 +151,12 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot);
|
||||
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
|
||||
*
|
||||
* Note that version number and (;1) is not appended.
|
||||
*
|
||||
* @param flag
|
||||
* bit0= no_force_dots
|
||||
* @return
|
||||
* NULL if the original name and extension both are of length 0.
|
||||
*/
|
||||
uint16_t *iso_j_file_id(const uint16_t *src);
|
||||
uint16_t *iso_j_file_id(const uint16_t *src, int flag);
|
||||
|
||||
/**
|
||||
* Create a Joliet directory identifier that consists of name and optionally
|
||||
|
Reference in New Issue
Block a user