Compare commits

..

36 Commits

Author SHA1 Message Date
1786ceb276 Version leap to 1.4.4 2016-07-01 19:53:15 +02:00
f51fc50356 Updated changelog 2016-07-01 09:50:04 +02:00
02de4570d1 Included <unistd.h> in aaip_0_2.h to fix a build time issue with musl libc.
Thanks to Baruch Siach.
2016-05-24 13:07:00 +02:00
2a41b4817c Removed option --silent from libtool runs 2016-04-27 16:44:27 +02:00
9440e3061c Recognizing SUN Sparc Disk Label of ISOs smaller than 300 kB. 2016-04-25 11:55:57 +02:00
122dfe7b87 Re-instated recognition of libisofs PReP which was broken by rev 1295. 2016-04-24 10:38:45 +02:00
03662f0832 Recognizing the newly introduced consequences of protective msdos label
with alternative grub-mkrescue boot layouts.
2016-04-20 20:11:57 +02:00
eb09bcf9e5 Prevented option --version-script with linker run of xorriso. By Matthias Klose. 2016-04-19 09:17:34 +02:00
5880636a50 Prevented appended partition from being marked twice in GPT if it is used as
El Torito boot image.
2016-03-31 20:26:36 +02:00
b5fb98a2a3 Bug fix: Oversized text in ISO_SYSAREA_REPORT_DOC_ALPHA.
Thanks to Etienne Bergeron.
2016-03-30 21:35:53 +02:00
b269557743 Bug fix: At image loading time GRUB2 MBR was not recognized if the partition
table is not the protective one as described by UEFI.
2016-03-23 11:24:36 +01:00
0fd7d4d7eb Added "extern C" to libisofs.h 2016-03-15 21:26:06 +01:00
d8dca37d65 Replaced unused timezone parameter of gettimeofday() by NULL 2016-03-10 21:04:48 +01:00
cd84f0927f Introduced image size tolerance of 300 kB in order to recognize SUN Disk Label
that was generated by genisoimage -B "...".
2016-02-27 15:12:11 +01:00
477bbb89bb Fixed typo "occured" -> "occurred" 2016-02-05 13:52:26 +01:00
31fcdc0ba6 New API calls iso_write_opts_set_appended_as_apm(), iso_write_opts_set_part_like_isohybrid() 2016-02-05 10:47:04 +01:00
7c05d2a865 Enabled use of --interval:appended_partition_ with ISO growing. 2016-01-20 11:35:29 +01:00
3d15642307 Preventing production of surplus isohybrid MBR partition for BIOS boot image.
The problem was introduced by rev 1299.
2016-01-17 16:28:40 +01:00
872b5c6c67 New bit15 with options of iso_write_opts_set_system_area() to enforce
MBR bootable/active flag.
2016-01-01 18:17:40 +01:00
ec35bb21c0 Provisory new pseudo path for El Torito boot images:
--interval:appened_partition_N:all::
2015-12-30 18:56:32 +01:00
93f3cb1823 Another fix for Libisofs_mjg_boot_for_grub2 with original grub-mkrescue options 2015-12-28 11:51:29 +01:00
fea7be5168 Fixed result of Libisofs_mjg_boot_for_grub2 with original grub-mkrescue options 2015-12-28 11:30:53 +01:00
bd25db9283 Experimental macro Libisofs_mjg_boot_for_grub2 for alternative partition layout 2015-12-27 16:07:27 +01:00
97eec6162c Bug fix: HFS+ directories could announce more children than they actually have. 2015-12-26 12:25:28 +01:00
17e8cb6697 Bug fix: The HFS+ filesystem was not marked by in GPT of GRUB2 hybrid layout. 2015-12-23 20:49:13 +01:00
9e01d3654e Experimental macros Libisofs_protective_msdos_plus_boot_dummY and
Libisofs_pmpbd_on_lba0 to test augmentation of GRUB2 protective msdos label.
2015-12-22 14:24:08 +01:00
009ce1be8f Bug fix: When reading an ISO filesystem, the presence of
system area options flag bit0 (-protective-msdos-label)
         was not recognized if a partition is appended.
2015-12-22 12:25:50 +01:00
c79299ba08 Bug fix: Options bit0 of iso_write_opts_set_system_area() was not forwarded
to image production if no system area data were given.
         This prevented xorrisofs option --protective-msdos-label from working.
2015-12-22 12:23:13 +01:00
b3701f0b18 Removed the false prediction that HFS+ would cause GPT. 2015-12-22 11:52:33 +01:00
83b864efd2 Clarified virtual sector size of El Torito. Changed germanoid use of "eventual". 2015-12-21 17:31:30 +01:00
cd0f57dd1a Bug fix: HFS+ production could cause MBR partition of type 0xEE without GPT. 2015-12-20 18:46:44 +01:00
4c9cb6b96b Coordinated expectations of build system and source code in respect to
loacl support for ACL and extended file attributes. (Rev 1288 actually
belongs to this commit.)
2015-12-15 11:04:49 +01:00
9c334891cf Silenced a warning about unused variable if no local extended file attributes
are enabled. (Previous commit should have been part of the next one.)
2015-12-15 11:01:01 +01:00
2f6103b783 Silenced a warning about unused variable if no local extended file attributes
are enabled.
2015-12-15 10:59:23 +01:00
f32ee7da83 Completed update of change log 2015-11-28 22:08:44 +01:00
52972811f8 Version leap to 1.4.3 2015-11-28 21:49:07 +01:00
20 changed files with 840 additions and 180 deletions

View File

@ -1,3 +1,27 @@
libisofs-1.4.4.tar.gz Fri Jul 01 2016
===============================================================================
* Bug fix: HFS+ production could cause MBR partition of type 0xEE without GPT.
* Bug fix: Protective MBR was not produced if no System Area data are given.
* Bug fix: Protective MBR was not recognized if partition is appended.
* Bug fix: The HFS+ filesystem was not marked in GPT of GRUB2 hybrid layout.
* Bug fix: HFS+ directories could announce more children than they actually
have.
* Bug fix: At image loading time GRUB2 MBR was not recognized if the partition
table is not the protective one as described by UEFI.
* Bug fix: Oversized text in ISO_SYSAREA_REPORT_DOC_ALPHA.
Thanks to Etienne Bergeron.
* New pseudo path for El Torito boot images:
--interval:appened_partition_N:all::
* New bit15 with options of iso_write_opts_set_system_area() to enforce
MBR bootable/active flag.
* New API calls iso_write_opts_set_appended_as_apm(),
iso_write_opts_set_part_like_isohybrid().
* Introduced image size tolerance of 300 kB in order to recognize SUN Disk
Label that was generated by genisoimage -B "...".
* Added "extern C" to libisofs.h
* Removed option --silent from libtool runs.
libisofs-1.4.2.tar.gz Sat Nov 28 2015
===============================================================================
* Bug fix: zisofs compression caused SIGSEGV (by reading) with files larger

View File

@ -13,7 +13,7 @@ ACLOCAL_AMFLAGS = -I ./
# Build libraries
libisofs_libisofs_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) $(LIBLDFLAGS)
# Eventually enabling system adapters for ACL and EA.
# ts A90409: Eventually enabling use of zlib.

View File

@ -16,15 +16,21 @@ AC_DEFUN([TARGET_SHIZZLE],
AC_MSG_CHECKING([target operating system])
LIBBURNIA_SUPP_ACL=none
LIBBURNIA_SUPP_FATTR=none
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
case $target in
*-*-linux*)
ARCH=linux
LIBBURN_ARCH_LIBS=
LIBBURNIA_SUPP_ACL=libacl
LIBBURNIA_SUPP_FATTR=xattr
LIBBURNIA_LDCONFIG_CMD=ldconfig
;;
*-*-freebsd*)
ARCH=freebsd
LIBBURNIA_SUPP_ACL=libacl
LIBBURNIA_SUPP_FATTR=extattr
LIBBURN_ARCH_LIBS=-lcam
# This may later be overridden by configure --enable-libdir-pkgconfig
@ -141,10 +147,12 @@ AC_DEFUN([LIBISOFS_ASSERT_VERS_LIBS],
LDFLAGS="$LDFLAGS -Wl,--version-script=libisofs/libisofs.ver"
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
[vers_libs_test="yes"], [vers_libs_test="no"])
if test x$vers_libs_test = xno
if test x$vers_libs_test = xyes
then
LDFLAGS="$libburnia_save_LDFLAGS"
LIBLDFLAGS="-Wl,--version-script=libisofs/libisofs.ver"
fi
LDFLAGS="$libburnia_save_LDFLAGS"
AC_SUBST(LIBLDFLAGS)
])

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.4.2], [http://libburnia-project.org])
AC_INIT([libisofs], [1.4.4], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -26,8 +26,8 @@ dnl
dnl LT_CURRENT, LT_REVISION and LT_AGE get set directly now.
dnl
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
dnl The linker will do no finer checks. Especially no age range check for
dnl the cdrskin binary. If SONAME matches, then the couple starts.
dnl The linker will do no finer checks. If SONAME matches, then the couple
dnl starts.
dnl
dnl Therefore a run time check is provided by libisofs function
dnl iso_lib_version(). It returns the major, minor and micro revision of the
@ -41,7 +41,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=4
LIBISOFS_MICRO_VERSION=2
LIBISOFS_MICRO_VERSION=4
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2015.11.28 development jump has not yet happened
# SONAME = 84 - 78 = 6 . Library name = libisofs.6.78.0
LT_CURRENT=84
LT_AGE=78
# 2016.07.01 development jump has not yet happened
# SONAME = 86 - 80 = 6 . Library name = libisofs.6.80.0
LT_CURRENT=86
LT_AGE=80
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
@ -92,7 +92,7 @@ LIBBURNIA_ASSERT_ICONV
AC_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
LIBTOOL="$LIBTOOL --silent"
dnl LIBTOOL="$LIBTOOL --silent"
AC_PROG_INSTALL
@ -172,39 +172,66 @@ dnl Add compiler-specific flags
AC_ARG_ENABLE(libacl,
[ --enable-libacl Enable use of ACL functions by libisofs, default=yes],
, enable_libacl=yes)
if test "x$enable_libacl" = xyes; then
LIBACL_DEF=
has_acl_h_but_no_func=0
if test x$LIBBURNIA_SUPP_ACL = xlibacl
then
if test x$enable_libacl = xyes; then
dnl Check whether there is libacl-devel and libacl-runtime.
dnl If not, erase this macro which would enable use of acl_to_text and others
LIBACL_DEF="-DLibisofs_with_aaip_acL"
LIBACL_DEF="-DLibisofs_with_aaip_acL"
dnl The empty yes case obviously causes -lacl to be linked
has_acl_h_but_no_func=0
AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , has_acl_h_but_no_libacl=1 ), LIBACL_DEF= )
if test "$has_acl_h_but_no_libacl" = 1
AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , has_acl_h_but_no_libacl=1 ), LIBACL_DEF= )
if test "$has_acl_h_but_no_libacl" = 1
then
AC_CHECK_LIB(c, acl_to_text, X= , LIBACL_DEF= )
fi
fi
fi
if test x$LIBACL_DEF = x-DLibisofs_with_aaip_acL
then
if test x$has_acl_h_but_no_libacl = x1
then
AC_CHECK_LIB(c, acl_to_text, X= , LIBACL_DEF= )
fi
echo "enabled local processing of ACL"
else
echo "enabled libacl, local processing of ACL"
fi
else
LIBACL_DEF=
echo "disabled local processing of ACL"
fi
AC_SUBST(LIBACL_DEF)
dnl ts A90123
dnl ts A90123 - B51212
AC_ARG_ENABLE(xattr,
[ --enable-xattr Enable use of xattr by libisofs, default=yes],
, enable_xattr=yes)
if test "x$enable_xattr" = xyes; then
dnl Check whether there is the header for Linux xattr.
[ --enable-xattr Enable use of extended file attributes by libisofs, default=yes],
, enable_xattr=yes)
XATTR_DEF=
if test x"$LIBBURNIA_SUPP_FATTR" = xxattr
then
if test "x$enable_xattr" = xyes; then
dnl Check whether there is the header for Linux xattr.
dnl If not, erase this macro which would enable use of listxattr and others
XATTR_DEF="-DLibisofs_with_aaip_xattR"
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= , XATTR_DEF= ), XATTR_DEF= )
if test "x$XATTR_DEF" = x
then
XATTR_DEF="-DLibisofs_with_freebsd_extattR"
AC_CHECK_HEADER(sys/extattr.h, AC_CHECK_LIB(c, extattr_list_file, X=, XATTR_DEF= ), XATTR_DEF= )
XATTR_DEF="-DLibisofs_with_aaip_xattR"
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
XATTR_DEF= ), XATTR_DEF= )
fi
elif test x"$LIBBURNIA_SUPP_FATTR" = xextattr
then
if test "x$enable_xattr" = xyes; then
XATTR_DEF="-DLibisofs_with_freebsd_extattR"
AC_CHECK_HEADER(sys/extattr.h, AC_CHECK_LIB(c, extattr_list_file, X=,
XATTR_DEF= ), XATTR_DEF= )
fi
fi
if test x$XATTR_DEF = x-DLibisofs_with_aaip_xattR
then
echo "enabled xattr, local processing of extended file attributes Linux style"
elif test x$XATTR_DEF = x-DLibisofs_with_freebsd_extattR
then
echo "enabled extattr, local processing of extended file attributes FreeBSD style"
else
XATTR_DEF=
echo "disabled local processing of extended file attributes"
fi
AC_SUBST(XATTR_DEF)

View File

@ -68,9 +68,9 @@ intervals for:
- Directory trees, tables, boot catalog, embedded partitions and filesystems.
- Data file content, including content of El Torito boot images.
The Boot Record is an ECMA-119 Volume Descriptor which is eventually located
at 2 kB block number 17 (decimal). Its content points to the location of the
Boot Catalog.
The Boot Record is an ECMA-119 Volume Descriptor which is located at 2 kB block
number 17 (decimal), if present at all. Its content points to the location of
the Boot Catalog.
The format is described in part by ECMA-119 8.2 "Boot Record" and further
specified by El Torito figure 7.
@ -177,7 +177,7 @@ Byte Range | Value | Meaning
| |
5 - 5 | 0 | Unused
| |
6 - 7 | sec_count | Sector Count.
6 - 7 | sec_count | Sector Count. Sector size 512:
| | "the number of virtual/emulated sectors the system
| | will store at Load Segment during the initial boot
| | procedure."
@ -232,7 +232,7 @@ Byte Range | Value | Meaning
| | 0 if not emulation == 4.
5 - 5 | 0 | Unused
| |
6 - 7 | sec_count | Sector Count.
6 - 7 | sec_count | Sector Count. Sector size 512.
| | See above Initial/Default Entry
| | libisofs stores 1 for emulated boot_media and a
| | user defined value for boot_media == 0. Often: 4.

View File

@ -342,7 +342,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
size_t **value_lengths, char ***values, int flag)
{
int ret;
ssize_t i, num_names= 0, acl_names= 0;
ssize_t i, num_names= 0;
#ifdef Libisofs_with_aaip_acL
unsigned char *a_acl= NULL;
@ -354,6 +354,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
ssize_t value_ret, retry= 0, list_size= 0, user_list_size= 0;
ssize_t sys_list_size= 0;
int attrnamespace;
int acl_names= 0;
#endif
if(flag & (1 << 15)) { /* Free memory */
@ -408,7 +409,11 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
#ifdef Libisofs_with_aaip_acL
if(flag & 1) {
num_names++;
#ifdef Libisofs_with_freebsd_extattR
acl_names= 1;
#endif
}
#endif

View File

@ -2192,6 +2192,22 @@ ex:;
#include "aaip-os-freebsd.c"
#else
#ifdef __FreeBSD_kernel__
#ifdef NIX
#ifdef Libisofs_with_aaip_xattR
/* ts B51213: xattr system library calls are only stubs */
#include "aaip-os-linux.c"
#else
/* ts B51213: extattr system library calls are not even present */
#include "aaip-os-freebsd.c"
#endif /* ! Libisofs_with_aaip_xattR */
#else /* NIX */
/* ts B51213: so we still end up at the dummy */
#include "aaip-os-dummy.c"
#endif /* ! NIX */
#else
#ifdef __NetBSD__
@ -2215,5 +2231,6 @@ ex:;
#endif /* ! __linux */
#endif /* ! __NetBSD__ */
#endif /* ! __FreeBSD_kernel__ */
#endif /* ! __FreeBSD__ */

View File

@ -16,6 +16,9 @@
#ifndef Aaip_h_is_includeD
#define Aaip_h_is_includeD yes
/* For ssize_t */
#include <unistd.h>
/* --------------------------------- Encoder ---------------------------- */

View File

@ -104,6 +104,12 @@ void ecma119_image_free(Ecma119Image *t)
free(t->output_charset);
if (t->bootsrc != NULL)
free(t->bootsrc);
if (t->boot_appended_idx != NULL)
free(t->boot_appended_idx);
if (t->boot_intvl_start != NULL)
free(t->boot_intvl_start);
if (t->boot_intvl_size != NULL)
free(t->boot_intvl_size);
if (t->system_area_data != NULL)
free(t->system_area_data);
if (t->checksum_ctx != NULL) { /* dispose checksum context */
@ -567,8 +573,14 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
vol.vol_desc_version[0] = 1;
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 - t->eff_partition_offset,
4);
if (t->pvd_size_is_total_size) {
iso_bb(vol.vol_space_size,
t->total_size / 2048 + t->opts->ms_block - t->eff_partition_offset,
4);
} else {
iso_bb(vol.vol_space_size,
t->vol_space_size - t->eff_partition_offset, 4);
}
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);
@ -2376,12 +2388,24 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
target->num_bootsrc = target->catalog->num_bootimages;
target->bootsrc = calloc(target->num_bootsrc + 1,
sizeof(IsoFileSrc *));
if (target->bootsrc == NULL) {
target->boot_appended_idx = calloc(target->num_bootsrc + 1,
sizeof(int));
target->boot_intvl_start = calloc(target->num_bootsrc + 1,
sizeof(uint32_t));
target->boot_intvl_size = calloc(target->num_bootsrc + 1,
sizeof(uint32_t));
if (target->bootsrc == NULL || target->boot_appended_idx == NULL ||
target->boot_intvl_start == NULL ||
target->boot_intvl_size == NULL) {
ret = ISO_OUT_OF_MEM;
goto target_cleanup;
}
for (i= 0; i < target->num_bootsrc; i++)
for (i= 0; i < target->num_bootsrc; i++) {
target->bootsrc[i] = NULL;
target->boot_appended_idx[i] = -1;
target->boot_intvl_start[i] = 0;
target->boot_intvl_size[i] = 0;
}
} else {
target->num_bootsrc = 0;
target->bootsrc = NULL;
@ -2394,7 +2418,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
system_area = src->system_area_data;
system_area_options = src->system_area_options;
} else {
system_area_options = opts->system_area_options & 0xfffffffc;
system_area_options = opts->system_area_options & 0xfffffffd;
}
sa_type = (system_area_options >> 2) & 0x3f;
if (sa_type != 0 && sa_type != 3)
@ -2448,6 +2472,10 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
goto target_cleanup;
}
target->total_size = 0;
target->vol_space_size = 0;
target->pvd_size_is_total_size = 0;
target->checksum_idx_counter = 0;
target->checksum_ctx = NULL;
target->checksum_counter = 0;
@ -3370,6 +3398,8 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
wopts->appended_part_flags[i] = 0;
}
wopts->appended_as_gpt = 0;
wopts->appended_as_apm = 0;
wopts->part_like_isohybrid = 0;
wopts->ascii_disc_label[0] = 0;
wopts->will_cancel = 0;
wopts->allow_dir_id_ext = 0;
@ -3975,7 +4005,7 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
opts->system_area_size = 32768;
}
if (!(flag & 4))
opts->system_area_options = options & 0x7fff;
opts->system_area_options = options & 0xffff;
return ISO_SUCCESS;
}
@ -4091,6 +4121,18 @@ int iso_write_opts_set_appended_as_gpt(IsoWriteOpts *opts, int gpt)
return ISO_SUCCESS;
}
int iso_write_opts_set_appended_as_apm(IsoWriteOpts *opts, int apm)
{
opts->appended_as_apm = !!apm;
return ISO_SUCCESS;
}
int iso_write_opts_set_part_like_isohybrid(IsoWriteOpts *opts, int alike)
{
opts->part_like_isohybrid = !!alike;
return ISO_SUCCESS;
}
int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label)
{
strncpy(opts->ascii_disc_label, label, ISO_DISC_LABEL_SIZE - 1);

View File

@ -487,6 +487,15 @@ struct iso_write_opts {
*/
int appended_as_gpt;
/* If 1: With appended partitions: mark by APM partition
*/
int appended_as_apm;
/* If 1: Obey struct el_torito_boot_image.isolinux_options bit2-7 and bit8.
I.e. mention boot image as partition in GPT and/or APM.
*/
int part_like_isohybrid;
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
*/
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
@ -554,10 +563,19 @@ struct ecma119_image
time_t now; /**< Time at which writing began. */
/** Total size of the output. This only includes the current volume. */
/* Total size of the output. Counted in bytes.
* Includes ISO filesystem and appended data.
*/
off_t total_size;
/** Size actually governed by the ISO filesystem part of the output */
uint32_t vol_space_size;
/* 1= write the total size into the PVD of the ISO,
* 0= write vol_space_size
*/
int pvd_size_is_total_size;
/* Bytes already written to image output */
off_t bytes_written;
/* just for progress notification */
@ -640,6 +658,11 @@ struct ecma119_image
int num_bootsrc;
IsoFileSrc **bootsrc; /* location of the boot images in the new image */
int *boot_appended_idx; /* Appended partition which serve as boot images */
uint32_t *boot_intvl_start; /* In blocks of 2048 bytes */
uint32_t *boot_intvl_size; /* In blocks of 512 bytes */
/*
* System Area related information
*/

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 - 2014 Thomas Schmitt
* Copyright (c) 2010 - 2015 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
@ -19,6 +19,7 @@
#include "image.h"
#include "messages.h"
#include "writer.h"
#include "ecma119.h"
#include <stdlib.h>
#include <string.h>
@ -312,6 +313,35 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
return ++parent->nchildren;
}
/* Get start and size from "%d_start_%lus_size_%lud" */
static
void iso_parse_start_size(char *text, unsigned long *part_start,
unsigned long *part_size)
{
char *cpt;
unsigned long start, size;
cpt = strchr(text, '_');
if (cpt == NULL)
return;
if (strncmp(cpt, "_start_", 7) != 0)
return;
sscanf(cpt + 7, "%lu", &start);
cpt = strchr(cpt + 7, '_');
if (cpt == NULL)
return;
if (*(cpt - 1) != 's')
return;
if (strncmp(cpt, "_size_", 6) != 0)
return;
sscanf(cpt + 6, "%lu", &size);
for (cpt = cpt + 6; *cpt >= '0' && *cpt <= '9'; cpt++);
if (*cpt != 'd')
return;
*part_start = start;
*part_size = size;
}
static
int create_image(IsoImage *image, const char *image_path,
@ -323,36 +353,64 @@ int create_image(IsoImage *image, const char *image_path,
struct el_torito_boot_image *boot;
int boot_media_type = 0;
int load_sectors = 0; /* number of sector to load */
int part_idx = -1;
unsigned long part_start = 0, part_size = 0;
unsigned char partition_type = 0;
off_t size;
IsoNode *imgfile;
IsoStream *stream;
IsoNode *imgfile = NULL;
IsoStream *stream = NULL;
*bootnode = NULL;
ret = iso_tree_path_to_node(image, image_path, &imgfile);
if (ret < 0) {
return ret;
}
if (ret == 0) {
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0,
if (strncmp(image_path, "--interval:appended_partition_", 30) == 0) {
/* --interval:appended_partition_N... */
if (type != ELTORITO_NO_EMUL) {
/* >>> ??? lift this ban by making a temporary IsoStream from
partition source, determine size,
and read ELTORITO_HARD_DISC_EMUL MBR ?
*/
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Appended partition cannot serve as El Torito boot image with FD/HD emulation");
return ISO_BOOT_IMAGE_NOT_VALID;
}
sscanf(image_path + 30, "%d", &part_idx);
if (part_idx < 1 || part_idx > ISO_MAX_PARTITIONS) {
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Appended partition index for El Torito boot image is out of range");
return ISO_BOOT_IMAGE_NOT_VALID;
}
iso_parse_start_size((char *) (image_path + 30),
&part_start, &part_size);
part_idx--;
size = 1;
} else {
ret = iso_tree_path_to_node(image, image_path, &imgfile);
if (ret < 0) {
return ret;
}
if (ret == 0) {
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0,
"El Torito boot image file missing in ISO image: '%s'",
image_path);
return ISO_NODE_DOESNT_EXIST;
return ISO_NODE_DOESNT_EXIST;
}
if (imgfile->type != LIBISO_FILE) {
return ISO_BOOT_IMAGE_NOT_VALID;
}
*bootnode = (IsoFile *) imgfile;
stream = ((IsoFile*)imgfile)->stream;
/* we need to read the image at least two times */
if (!iso_stream_is_repeatable(stream)) {
return ISO_BOOT_IMAGE_NOT_VALID;
}
size = iso_stream_get_size(stream);
}
if (imgfile->type != LIBISO_FILE) {
return ISO_BOOT_IMAGE_NOT_VALID;
}
*bootnode = (IsoFile *) imgfile;
stream = ((IsoFile*)imgfile)->stream;
/* we need to read the image at least two times */
if (!iso_stream_is_repeatable(stream)) {
return ISO_BOOT_IMAGE_NOT_VALID;
}
size = iso_stream_get_size(stream);
if (size <= 0) {
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Boot image file is empty");
@ -441,7 +499,11 @@ int create_image(IsoImage *image, const char *image_path,
return ISO_OUT_OF_MEM;
}
boot->image = (IsoFile*)imgfile;
iso_node_ref(imgfile); /* get our ref */
boot->appended_idx = part_idx;
boot->appended_start = part_start;
boot->appended_size = part_size;
if (imgfile != NULL)
iso_node_ref(imgfile); /* get our ref */
boot->bootable = 1;
boot->seems_boot_info_table = 0;
boot->seems_grub2_boot_info = 0;
@ -538,8 +600,9 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
catalog->bootimages[i] = NULL;
catalog->node = cat_node;
catalog->sort_weight = 1000000000; /* very high */
if (!(boot_node->explicit_weight || boot_node->from_old_session))
boot_node->sort_weight = 2;
if (boot_node != NULL)
if (!(boot_node->explicit_weight || boot_node->from_old_session))
boot_node->sort_weight = 2;
iso_node_ref((IsoNode*)cat_node);
image->bootcat = catalog;
@ -555,7 +618,8 @@ boot_image_cleanup:;
iso_node_unref((IsoNode*)cat_node);
}
if (boot_image) {
iso_node_unref((IsoNode*)boot_image->image);
if (boot_image->image != NULL)
iso_node_unref((IsoNode*)boot_image->image);
free(boot_image);
}
return ret;
@ -719,8 +783,9 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
ret = create_image(image, image_path, type, &boot_img, &boot_node);
if (ret < 0)
return ret;
if (!(boot_node->explicit_weight || boot_node->from_old_session))
boot_node->sort_weight = 2;
if (boot_node != NULL)
if (!(boot_node->explicit_weight || boot_node->from_old_session))
boot_node->sort_weight = 2;
catalog->bootimages[catalog->num_bootimages] = boot_img;
catalog->num_bootimages++;
if (boot != NULL)
@ -827,12 +892,13 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
* Usable for the Default Entry
* and for Section Entries with Selection criteria type == 0
*/
static void
write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
static
int 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;
int app_idx, mode = 0;
img = t->catalog->bootimages[idx];
@ -840,16 +906,69 @@ write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
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->bootsrc[idx]->sections[0].block, 4);
if (t->boot_appended_idx[idx] >= 0)
if (t->appended_part_size[t->boot_appended_idx[idx]] > 0)
mode = 2; /* appended partition */
if (mode == 0 && t->opts->appendable &&
(t->boot_intvl_start[idx] > 0 || t->boot_intvl_size[idx] > 0) &&
t->boot_intvl_start[idx] + (t->boot_intvl_size[idx] + 3) / 4 <=
t->opts->ms_block)
mode = 1; /* image interval */
if (mode == 0 && t->boot_appended_idx[idx] >= 0) {
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Appended partition which shall serve as boot image does not exist");
return ISO_BOOT_IMAGE_NOT_VALID;
}
if (mode == 1) {
if (t->boot_intvl_start[idx] + (t->boot_intvl_size[idx] + 3) / 4 >
t->total_size / 2048 + t->opts->ms_block - t->eff_partition_offset
) {
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Block interval which shall serve as boot image is outside result range");
return ISO_BOOT_IMAGE_NOT_VALID;
}
if (t->boot_intvl_size[idx] > 65535) {
if (img->platform_id == 0xef)
iso_lsb(se->sec_count, 0, 2);
else
iso_lsb(se->sec_count, 65535, 2);
} else {
if (t->boot_intvl_size[idx] == 0) {
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Block interval which shall serve as boot image has zero size");
return ISO_BOOT_IMAGE_NOT_VALID;
}
iso_lsb(se->sec_count, t->boot_intvl_size[idx], 2);
}
iso_lsb(se->block, t->boot_intvl_start[idx], 4);
} else if (mode == 2) {
app_idx = t->boot_appended_idx[idx];
if (t->appended_part_size[app_idx] * 4 > 65535) {
if (img->platform_id == 0xef)
iso_lsb(se->sec_count, 0, 2);
else
iso_lsb(se->sec_count, 65535, 2);
} else {
iso_lsb(se->sec_count, t->appended_part_size[app_idx] * 4, 2);
}
iso_lsb(se->block, t->appended_part_start[app_idx], 4);
} else {
iso_lsb(se->sec_count, img->load_size, 2);
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);
return ISO_SUCCESS;
}
static
int catalog_open(IsoStream *stream)
{
int i, j, k, num_entries;
int i, j, k, num_entries, ret;
struct catalog_stream *data;
uint8_t *wpt;
struct el_torito_boot_catalog *cat;
@ -873,7 +992,9 @@ int catalog_open(IsoStream *stream)
boots[0]->platform_id, boots[0]->id_string);
/* write default entry = first boot image */
write_section_entry(data->buffer + 32, data->target, 0);
ret = write_section_entry(data->buffer + 32, data->target, 0);
if (ret < 0)
return ret;
/* IMPORTANT: The maximum number of boot images must fit into BLOCK_SIZE */
wpt = data->buffer + 64;
@ -894,7 +1015,9 @@ int catalog_open(IsoStream *stream)
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);
ret = write_section_entry(wpt, data->target, i);
if (ret < 0)
return ret;
wpt += 32;
i++;
}
@ -1132,6 +1255,9 @@ int patch_boot_info_table(uint8_t *buf, Ecma119Image *t,
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Isolinux image too small. We won't patch it.");
}
if (t->bootsrc[idx] == NULL)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Cannot apply ISOLINUX patching outside of ISO 9660 filesystem.");
ret = make_boot_info_table(buf, t->opts->ms_block + (uint32_t) 16,
t->bootsrc[idx]->sections[0].block,
(uint32_t) imgsize);
@ -1151,7 +1277,10 @@ int patch_grub2_boot_image(uint8_t *buf, Ecma119Image *t,
if (imgsize < pos + 8)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Isolinux image too small for GRUB2. Will not patch it.");
"Boot image too small for GRUB2. Will not patch it.");
if (t->bootsrc[idx] == NULL)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Cannot apply GRUB2 patching outside of ISO 9660 filesystem.");
blk = ((uint64_t) t->bootsrc[idx]->sections[0].block) * 4 + offst;
iso_lsb((buf + pos), blk & 0xffffffff, 4);
iso_lsb((buf + pos + 4), blk >> 32, 4);
@ -1174,6 +1303,10 @@ int iso_patch_eltoritos(Ecma119Image *t)
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x201))
continue;
if (t->bootsrc[idx] == NULL)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Cannot apply boot image patching outside of ISO 9660 filesystem");
original = t->bootsrc[idx]->stream;
size = (size_t) iso_stream_get_size(original);
if (size > Libisofs_elto_max_patchablE)
@ -1281,8 +1414,8 @@ int eltorito_writer_create(Ecma119Image *target)
{
int ret, idx, outsource_efi = 0;
IsoImageWriter *writer;
IsoFile *bootimg;
IsoFileSrc *src;
IsoFile *bootimg = NULL;
IsoFileSrc *src = NULL;
writer = calloc(1, sizeof(IsoImageWriter));
if (writer == NULL) {
@ -1315,6 +1448,23 @@ int eltorito_writer_create(Ecma119Image *target)
if (strcmp(target->opts->efi_boot_partition, "--efi-boot-image") == 0)
outsource_efi = 1;
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
target->bootsrc[idx] = NULL;
if (target->catalog->bootimages[idx]->appended_idx >= 0) {
/* Use an appended partition as boot image rather than IsoFile */
target->boot_appended_idx[idx] =
target->catalog->bootimages[idx]->appended_idx;
target->boot_intvl_start[idx] =
target->catalog->bootimages[idx]->appended_start;
target->boot_intvl_size[idx] =
target->catalog->bootimages[idx]->appended_size;
if (((target->system_area_options >> 2) & 0x3f) == 0 &&
(target->system_area_options & 3) == 1) {
/* ISO will not be a partition. It can span the whole image. */
target->pvd_size_is_total_size = 1;
}
continue;
}
bootimg = target->catalog->bootimages[idx]->image;
ret = iso_file_src_create(target, bootimg, &src);
if (ret < 0) {

View File

@ -53,6 +53,11 @@ struct el_torito_boot_catalog {
struct el_torito_boot_image {
IsoFile *image;
/* Overrides .image if >= 0 : array index of appended partition */
int appended_idx;
uint32_t appended_start; /* In blocks of 2048 bytes */
uint32_t appended_size; /* In blocks of 512 bytes */
unsigned int bootable:1; /**< If the entry is bootable. */
/**
* Whether the boot image seems to contain a boot_info_table

View File

@ -364,7 +364,7 @@ typedef struct
*/
int px_ino_status;
/* Which Rock Ridge error messages already have occured
/* Which Rock Ridge error messages already have occurred
bit0= Invalid PX entry
bit1= Invalid TF entry
bit2= New NM entry found without previous CONTINUE flag
@ -3940,6 +3940,7 @@ int iso_analyze_mbr(IsoImage *image, IsoDataSource *src, int flag)
{
int sub_type = 2, ret, is_isohybrid = 0, is_grub2_mbr = 0;
int is_protective_label = 0;
uint64_t part2_start;
char *sad;
struct iso_imported_sys_area *sai;
struct iso_mbr_partition_request *part;
@ -3963,34 +3964,11 @@ int iso_analyze_mbr(IsoImage *image, IsoDataSource *src, int flag)
sub_type = 0;
is_isohybrid = 1;
} else if(ret == 2) {
sub_type = 0;
/* will become sub_type 0 if protective_label */
is_grub2_mbr = 1;
}
if (sai->mbr_req_count == 1 && !is_isohybrid) {
part = sai->mbr_req[0];
if (part->start_block == 1 &&
part->block_count + 1 == ((uint64_t) sai->image_size) * 4) {
/* libisofs protective msdos label for GRUB2 */
is_protective_label = 1;
sub_type = 0;
} else if (part->start_block == 0 &&
part->block_count <= ((uint64_t) sai->image_size) * 4 &&
part->block_count + 600 >= ((uint64_t) sai->image_size) * 4 &&
part->type_byte == 0x96) {
/* CHRP (possibly without padding) */
sub_type = 1;
} else if (sai->mbr_req[0]->start_block > 0 &&
(sai->mbr_req[0]->start_block % 4) == 0 &&
(sai->mbr_req[0]->start_block +
sai->mbr_req[0]->block_count) / 4 <= sai->image_size &&
part->type_byte == 0x41) {
/* mkisofs PReP partition */
sai->prep_part_start = sai->mbr_req[0]->start_block / 4;
sai->prep_part_size = (sai->mbr_req[0]->block_count + 3) / 4;
sub_type = 0;
}
} else if (sai->mbr_req_count == 3 && !is_isohybrid) {
if (sai->mbr_req_count == 3 && !is_isohybrid) {
/* Check for libisofs PReP partitions :
0xee or 0xcd from 0 to a-1
0x41 from a to b
@ -4013,6 +3991,42 @@ int iso_analyze_mbr(IsoImage *image, IsoDataSource *src, int flag)
sub_type = 0;
}
}
if (sai->mbr_req_count >= 1 &&
(sai->mbr_req[0]->type_byte == 0xee || !is_isohybrid) &&
!sai->prep_part_start > 0) {
part = sai->mbr_req[0];
part2_start = 0;
if (sai->mbr_req_count >= 2)
part2_start = sai->mbr_req[1]->start_block;
if (part->start_block == 1 &&
(part->block_count + 1 == ((uint64_t) sai->image_size) * 4 ||
(part->type_byte == 0xee &&
part->block_count + 1 >= ((uint64_t) sai->image_size) * 4 &&
(sai->mbr_req_count == 1 ||
(sai->mbr_req_count == 2 &&
sai->mbr_req[1]->type_byte == 0x00))) ||
part->block_count + 1 == part2_start)) {
/* libisofs protective msdos label for GRUB2 */
is_protective_label = 1;
sub_type = 0;
} else if (sai->mbr_req_count == 1 && part->start_block == 0 &&
part->block_count <= ((uint64_t) sai->image_size) * 4 &&
part->block_count + 600 >= ((uint64_t) sai->image_size) * 4 &&
part->type_byte == 0x96) {
/* CHRP (possibly without padding) */
sub_type = 1;
} else if (sai->mbr_req_count == 1 &&
sai->mbr_req[0]->start_block > 0 &&
(sai->mbr_req[0]->start_block % 4) == 0 &&
(sai->mbr_req[0]->start_block +
sai->mbr_req[0]->block_count) / 4 <= sai->image_size &&
part->type_byte == 0x41) {
/* mkisofs PReP partition */
sai->prep_part_start = sai->mbr_req[0]->start_block / 4;
sai->prep_part_size = (sai->mbr_req[0]->block_count + 3) / 4;
sub_type = 0;
}
}
/* Check for partition offset with extra set of meta data */
if (sai->mbr_req_count > 0) {
@ -4572,7 +4586,8 @@ int iso_analyze_sun(IsoImage *image, IsoDataSource *src, int flag)
iso_read_msb(usad + 144, 2) != 0x10 ||
iso_read_msb(usad + 444, 4) != 0 ||
sai->image_size > 0x3fffffff ||
iso_read_msb(usad + 448, 4) != sai->image_size * 4)
iso_read_msb(usad + 448, 4) < ((int64_t) sai->image_size * 4) - 600 ||
iso_read_msb(usad + 448, 4) > sai->image_size * 4)
return 0;
checksum[0] = checksum[1] = 0;
for (i = 0; i < 510; i += 2) {

View File

@ -405,7 +405,8 @@ int create_tree(Ecma119Image *t, IsoNode *iso, uint32_t parent_id)
if (cret < 0)
return cret;
pos = pos->next;
t->hfsp_leafs[cleaf].nchildren++;
if (cret > 0)
t->hfsp_leafs[cleaf].nchildren++;
}
}
return ISO_SUCCESS;
@ -1667,7 +1668,8 @@ int hfsplus_writer_create(Ecma119Image *target)
goto ex;
}
pos = pos->next;
target->hfsp_leafs[0].nchildren++;
if (cret > 0)
target->hfsp_leafs[0].nchildren++;
}
qsort(target->hfsp_leafs, target->hfsp_nleafs,

View File

@ -1,7 +1,7 @@
/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
Message handling facility of libisofs.
Copyright (C) 2006 - 2008 Thomas Schmitt <scdbackup@gmx.net>,
Copyright (C) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2 or later
*/
@ -33,14 +33,13 @@ static int libiso_msgs_item_new(struct libiso_msgs_item **item,
int ret;
struct libiso_msgs_item *o;
struct timeval tv;
struct timezone tz;
(*item)= o=
(struct libiso_msgs_item *) malloc(sizeof(struct libiso_msgs_item));
if(o==NULL)
return(-1);
o->timestamp= 0.0;
ret= gettimeofday(&tv,&tz);
ret= gettimeofday(&tv, NULL);
if(ret==0)
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
o->process_id= getpid();

View File

@ -4,7 +4,7 @@
/*
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
* Copyright (c) 2009-2015 Thomas Schmitt
* Copyright (c) 2009-2016 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
@ -16,6 +16,10 @@
libisofs/libisofs.ver
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
*
* Applications must use 64 bit off_t.
@ -90,7 +94,7 @@
*/
#define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 4
#define iso_lib_header_version_micro 2
#define iso_lib_header_version_micro 4
/**
* Get version of the libisofs library at runtime.
@ -2215,8 +2219,10 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* @since 1.2.6
* bit10-13= System area sub type
* @since 1.2.4
* With type 0 = MBR:
* Gets overridden by bit0 and bit1.
* With type 0:
* if options bit0 ... MBR with partition start at block 1
* if options bit1 ... ISOLINUX isohybrid MBR
* else:
* 0 = no particular sub type, use unaltered
* 1 = CHRP: A single MBR partition of type 0x96 covers the
* ISO image. Not compatible with any other feature
@ -2228,8 +2234,12 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* Patch system area at byte 0x1b0 to 0x1b7 with
* (512-block address + 4) of the first boot image file.
* Little-endian 8-byte.
* Should be combined with options bit0.
* Is normally combined with options bit0.
* Will not be in effect if options bit1 is set.
* bit15= Only with System area type MBR but not with CHRP
* Enforce MBR "bootable/active" flag. In worst case by dummy
* partition of type 0x00 which occupies block 0.
* @since 1.4.4
* @param flag
* bit0 = invalidate any attached system area data. Same as data == NULL
* (This re-activates eventually loaded image System Area data.
@ -2505,7 +2515,7 @@ int iso_interval_reader_destroy(struct iso_interval_reader **ivr, int flag);
* Pointer to memory for filling in at least 2048 bytes.
* @param buf_fill
* Will in case of success return the number of valid bytes.
* If this is smaller than 2048, then end-of-interval has occured.
* If this is smaller than 2048, then end-of-interval has occurred.
* @param flag
* Unused yet. Submit 0.
* @return
@ -2644,6 +2654,54 @@ int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
*/
int iso_write_opts_set_appended_as_gpt(IsoWriteOpts *opts, int gpt);
/**
* Control whether partitions created by iso_write_opts_set_partition_img()
* are to be represented in Apple Partition Map.
*
* @param opts
* The option set to be manipulated.
* @param apm
* 0= do not represent appended partitions in APM
* 1= represent in APM, even if not
* iso_write_opts_set_part_like_isohybrid() enables it and no
* other APM partitions emerge.
* @return
* ISO_SUCCESS or error
*
* @since 1.4.4
*/
int iso_write_opts_set_appended_as_apm(IsoWriteOpts *opts, int apm);
/**
* Control whether bits 2 to 8 of el_torito_set_isolinux_options()
* shall apply even if not isohybrid MBR patching is enabled (bit1 of
* parameter options of iso_write_opts_set_system_area()):
* - Mentioning of El Torito boot images in GPT.
* - Mentioning of El Torito boot images in APM.
*
* In this case some other behavior from isohybrid processing will apply too:
* - No MBR partition of type 0xee emerges, even if GPT gets produced.
* - Gaps between GPT and APM partitions will not be filled by more partitions.
*
* An extra feature towards isohybrid is enabled:
* - Appended partitions get mentioned in APM if other APM partitions emerge.
*
* @param opts
* The option set to be manipulated.
* @param alike
* 0= Apply the described behavior only with ISOLINUX isohybrid.
* Do not mention appended partitions in APM unless
* iso_write_opts_set_appended_as_apm() is enabled.
* 1= Apply the described behavior even without ISOLINUX isohybrid.
*
* @return
* ISO_SUCCESS or error
*
* @since 1.4.4
*/
int iso_write_opts_set_part_like_isohybrid(IsoWriteOpts *opts, int alike);
/**
* Inquire the start address of the file data blocks after having used
* IsoWriteOpts with iso_image_create_burn_source().
@ -3402,6 +3460,9 @@ int iso_image_get_pvd_times(IsoImage *image,
* returns an error and the image remains unmodified.
* @param image_path
* The absolute path of a IsoFile to be used as default boot image.
>>> or --interval:appended_partition_$number_start_$start_size_$size:...
* @param type
* The boot media type. This can be one of 3 types:
* - Floppy emulation: Boot image file must be exactly
@ -3443,7 +3504,10 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
* 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.
* The absolute path of a IsoFile to be used as boot image.
>>> or --interval:appended_partition_${number}s_start_${start}d_size_$size:...
* @param type
* The boot media type. See iso_image_set_boot_image
* @param flag
@ -3488,6 +3552,9 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
* @param imgnode
* When not NULL, it will be filled with the image tree node. No extra ref
* is added, you can use iso_node_ref() to get one if you need it.
>>> The returned value is NULL if the boot image source is no IsoFile.
* @param catnode
* When not NULL, it will be filled with the catnode tree node. No extra
* ref is added, you can use iso_node_ref() to get one if you need it.
@ -3545,6 +3612,11 @@ int iso_image_get_bootcat(IsoImage *image, IsoBoot **catnode, uint32_t *lba,
* @param bootnodes
* Returns NULL or an allocated array of pointers to the IsoFile nodes
* which bear the content of the boot images in boots.
>>> An array entry is NULL if the boot image source is no IsoFile.
>>> Need getter for partition index
* @param flag
* Bitfield for control purposes. Unused yet. Submit 0.
* @return
@ -4166,7 +4238,7 @@ int iso_image_get_system_area(IsoImage *img, char data[32768],
#define ISO_SYSAREA_REPORT_DOC_ALPHA \
"If a DEC Alpha SRM boot sector is present:", \
" DEC Alpha ldr size : decimal", \
" tells the number of 512-byte blocks in DEC Alpha Secondary Bootstrap" \
" tells the number of 512-byte blocks in DEC Alpha Secondary Bootstrap", \
" Loader file.", \
" DEC Alpha ldr adr : decimal", \
" tells the start of the loader file in units of 512-byte blocks.", \
@ -8724,16 +8796,16 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
/* ! PLACE NEW ERROR CODES ABOVE. NOT AFTER THIS LINE ! */
/** Read error occured with IsoDataSource (SORRY,HIGH, -513) */
/** Read error occurred with IsoDataSource (SORRY,HIGH, -513) */
#define ISO_DATA_SOURCE_SORRY 0xE030FCFF
/** Read error occured with IsoDataSource (MISHAP,HIGH, -513) */
/** Read error occurred with IsoDataSource (MISHAP,HIGH, -513) */
#define ISO_DATA_SOURCE_MISHAP 0xE430FCFF
/** Read error occured with IsoDataSource (FAILURE,HIGH, -513) */
/** Read error occurred with IsoDataSource (FAILURE,HIGH, -513) */
#define ISO_DATA_SOURCE_FAILURE 0xE830FCFF
/** Read error occured with IsoDataSource (FATAL,HIGH, -513) */
/** Read error occurred with IsoDataSource (FATAL,HIGH, -513) */
#define ISO_DATA_SOURCE_FATAL 0xF030FCFF
@ -8911,4 +8983,8 @@ struct burn_source {
#define Libisofs_with_rrip_rR yes
*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LIBISO_LIBISOFS_H_*/

View File

@ -308,6 +308,7 @@ iso_write_opts_set_allow_longer_paths;
iso_write_opts_set_allow_lowercase;
iso_write_opts_set_always_gmt;
iso_write_opts_set_appendable;
iso_write_opts_set_appended_as_apm;
iso_write_opts_set_appended_as_gpt;
iso_write_opts_set_default_dir_mode;
iso_write_opts_set_default_file_mode;
@ -337,6 +338,7 @@ iso_write_opts_set_omit_version_numbers;
iso_write_opts_set_output_charset;
iso_write_opts_set_overwrite_buf;
iso_write_opts_set_part_offset;
iso_write_opts_set_part_like_isohybrid;
iso_write_opts_set_partition_img;
iso_write_opts_set_prep_img;
iso_write_opts_set_pvd_times;

View File

@ -37,6 +37,8 @@
#include "ecma119.h"
#include "eltorito.h"
#include "system_area.h"
#include "image.h"
#include "messages.h"
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
@ -60,7 +62,7 @@ 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-2014 Thomas Schmitt
and 2008-2015 Thomas Schmitt
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
@ -156,7 +158,6 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
/* For generating a weak random number */
struct timeval tv;
struct timezone tz;
if (bin_lba < 0 || bin_lba >= (1 << 29))
return (0); /* 1 TB limit of signed 32 bit addressing of 512 byte blocks */
@ -211,7 +212,7 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
from. An environment variable ?
125: Whatever, i use some 32-bit random value with no crypto strength.
*/
gettimeofday(&tv, &tz);
gettimeofday(&tv, NULL);
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
/*
@ -400,12 +401,15 @@ int lba512chs_to_buf(char **wpt, off_t lba, int head_count, int sector_count)
/* Find out whether GPT and APM are desired
flag bit0 = register APM and GPT requests in Ecma119Image
bit1 = do not asses and register APM
bit2 = do not register overall GPT partition
*/
int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
int *apm_count, int flag)
{
int i, ilx_opts, j, ret, num_img;
uint32_t block_count;
uint64_t start_block;
uint8_t gpt_name[72];
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
static uint8_t basic_data_uuid[16] = {
@ -428,11 +432,13 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
num_img = 0;
for (i = 0; i < num_img; i++) {
ilx_opts = t->catalog->bootimages[i]->isolinux_options;
if (((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) {
if ((((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) &&
!(t->boot_appended_idx[i] >= 0 && t->opts->appended_as_gpt)) {
if (*gpt_count < 128)
gpt_idx[*gpt_count]= i;
gpt_idx[*gpt_count] = i;
(*gpt_count)++;
if ((flag & 1) && t->bootsrc[i] != NULL) {
if ((flag & 1) &&
(t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) {
/* Register GPT entry */
memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "ISOHybrid%d", *gpt_count);
@ -441,27 +447,44 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
uuid = hfs_uuid;
else
uuid = basic_data_uuid;
block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
if (t->boot_appended_idx[i] >= 0) {
block_count = t->appended_part_size[
t->boot_appended_idx[i]];
start_block = ((uint64_t) t->appended_part_start[
t->boot_appended_idx[i]]) * 4;
} else {
block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
start_block = ((uint64_t) t->bootsrc[i]->sections[0].block)
* 4;
}
ret = iso_quick_gpt_entry(
t->gpt_req, &(t->gpt_req_count),
((uint64_t) t->bootsrc[i]->sections[0].block) * 4,
((uint64_t) block_count) * 4,
start_block, ((uint64_t) block_count) * 4,
uuid, zero_uuid, gpt_flags, (uint8_t *) gpt_name);
if (ret < 0)
return ret;
}
}
if (ilx_opts & 256) {
if ((ilx_opts & 256) && !(flag & 2)) {
(*apm_count)++;
if ((flag & 1) && t->bootsrc[i] != NULL) {
if ((flag & 1) &&
(t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) {
/* Register APM entry */
block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
if (t->boot_appended_idx[i] >= 0) {
block_count = t->appended_part_size[
t->boot_appended_idx[i]];
start_block = t->appended_part_start[
t->boot_appended_idx[i]];
} else {
block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
start_block = t->bootsrc[i]->sections[0].block;
}
ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
t->bootsrc[i]->sections[0].block,
(uint32_t) start_block,
block_count, "EFI", "Apple_HFS");
if (ret < 0)
return ret;
@ -471,7 +494,12 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
}
}
}
if ((flag & 1) && *gpt_count > 0) {
if (*gpt_count > 0 && !(flag & 4)) {
(*gpt_count)++;
if (*gpt_count < 128)
gpt_idx[*gpt_count] = -1;
}
if ((flag & 1) && *gpt_count > 0 && !(flag & 4)) {
/* Register overall GPT partition */
memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "ISOHybrid");
@ -536,19 +564,28 @@ static int insert_apm_head(uint8_t *buf, int apm_count)
static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
int gpt_idx[128], int *gpt_cursor)
{
int ilx_opts;
int ilx_opts, skip = 0;
off_t hd_blocks;
static uint8_t dummy_chs[3] = {
0xfe, 0xff, 0xff,
};
if (gpt_idx[*gpt_cursor] < 0)
skip = 1;
else if (t->bootsrc[gpt_idx[*gpt_cursor]] == NULL)
skip = 1;
if (skip) {
(*gpt_cursor)++;
return 2;
}
wpt[0] = 0;
memcpy(wpt + 1, dummy_chs, 3);
ilx_opts = t->catalog->bootimages[gpt_idx[*gpt_cursor]]->isolinux_options;
if (((ilx_opts >> 2) & 63) == 2)
wpt[4] = 0x00; /* HFS gets marked as "Empty" */
else
((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16/" */
((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16)" */
memcpy(wpt + 5, dummy_chs, 3);
@ -580,10 +617,16 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
char *wpt;
uint32_t boot_lba;
int head_count, sector_count, ret;
int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor;
int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor, i;
/* For generating a weak random number */
struct timeval tv;
struct timezone tz;
if (t->bootsrc[0] == NULL)
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Cannot refer by isohybrid MBR to data outside of ISO 9660 filesystem.");
for (i = 0; i < 128; i++)
gpt_idx[i] = -1;
if (flag & 2) {
part_number = 1;
@ -625,7 +668,7 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
(here some 32-bit random value with no crypto strength)
*/
if (flag & 1) {
gettimeofday(&tv, &tz);
gettimeofday(&tv, NULL);
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
lsb_to_buf(&wpt, id, 32, 0);
} else {

View File

@ -380,7 +380,7 @@ const char *iso_error_to_msg(int errcode)
case ISO_DATA_SOURCE_MISHAP:
case ISO_DATA_SOURCE_FAILURE:
case ISO_DATA_SOURCE_FATAL:
return "Read error occured with IsoDataSource";
return "Read error occurred with IsoDataSource";
case ISO_AAIP_IGNORED:
return "AAIP info with ACL or xattr in ISO image will be ignored";
case ISO_AAIP_BAD_ACL:

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2010 - 2015 Thomas Schmitt
* Copyright (c) 2010 - 2016 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
@ -993,6 +993,24 @@ int iso_quick_apm_entry(struct iso_apm_partition_request **req_array,
}
static int iso_find_gpt_entry(struct iso_gpt_partition_request **req_array,
int gpt_req_count,
uint64_t start_block, uint64_t block_count,
int *index, int flag)
{
struct iso_gpt_partition_request *entry;
for (*index = 0; *index < gpt_req_count; (*index)++) {
entry = req_array[*index];
if (entry->start_block == start_block &&
entry->block_count == block_count)
return 1;
}
*index = -1;
return 0;
}
/* Convenience frontend for iso_register_gpt_entry().
name has to be already encoded as UTF-16LE.
*/
@ -1187,6 +1205,9 @@ static int fill_apm_gaps(Ecma119Image *t, uint32_t img_blocks)
qsort(t->apm_req, t->apm_req_count,
sizeof(struct iso_apm_partition_request *), cmp_partition_request);
if (t->opts->part_like_isohybrid)
return 1; /* No filling, only sorting */
/* t->apm_req_count will grow during the loop */
up_to = t->apm_req_count + 1;
for (i = 1; i < up_to; i++) {
@ -1567,6 +1588,69 @@ void iso_ascii_utf_16le(uint8_t gap_name[72])
}
static int intvl_overlap(uint64_t start1, uint64_t end1,
uint64_t start2, uint64_t end2, int second)
{
if (start1 >= start2 && start1 <= end2)
return 1;
if (end1 >= start2 && end1 <= end2)
return 1;
if (!second)
return intvl_overlap(start2, end2, start1, end1, 1);
return 0;
}
/* Check APM HFS+ partitions whether they would fit in gaps.
If so, add them as GPT partitions, too.
*/
static int iso_copy_apmhfs_to_gpt(Ecma119Image *t, int flag)
{
int a, i, counter = 0, ret;
uint64_t bfac = 4;
static uint8_t hfs_plus_uuid[16] = {
0x00, 0x53, 0x46, 0x48, 0x00, 0x00, 0xaa, 0x11,
0xaa, 0x11, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac
};
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uint8_t gpt_name[72];
static uint64_t gpt_flags = (((uint64_t) 1) << 60) | 1;
if ((t->apm_req_flags & 4) && t->opts->apm_block_size / 512 > 0)
bfac = t->opts->apm_block_size / 512;
for (a = 0; a < t->apm_req_count; a++) {
if (strcmp((char *) t->apm_req[a]->type, "Apple_HFS") != 0)
continue;
for (i = 0; i < t->gpt_req_count; i++)
if (intvl_overlap(t->apm_req[a]->start_block * bfac,
(t->apm_req[a]->start_block +
t->apm_req[a]->block_count - 1) * bfac,
t->gpt_req[i]->start_block,
t->gpt_req[i]->start_block +
t->gpt_req[i]->block_count - 1, 0))
break;
if (i >= t->gpt_req_count) {
memset(gpt_name, 0, 72);
counter++;
if (counter > 1)
sprintf((char *) gpt_name, "HFSPLUS_%d", counter);
else
sprintf((char *) gpt_name, "HFSPLUS");
iso_ascii_utf_16le(gpt_name);
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
t->apm_req[a]->start_block * bfac,
t->apm_req[a]->block_count * bfac,
hfs_plus_uuid, zero_uuid,
gpt_flags, gpt_name);
if (ret < 0)
return ret;
}
}
return 1;
}
static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
{
static uint8_t basic_data_uuid[16] = {
@ -1586,6 +1670,10 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
return 2;
backup_end_lba = ((uint64_t) t->gpt_backup_end - t->gpt_backup_size) * 4;
ret = iso_copy_apmhfs_to_gpt(t, 0);
if (ret <= 0)
return ret;
/* Sort and fill gaps */
qsort(t->gpt_req, t->gpt_req_count,
sizeof(struct iso_gpt_partition_request *), cmp_partition_request);
@ -1593,6 +1681,10 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
up_to = t->gpt_req_count + 1;
goal = 0;
part_end = 0;
if (t->opts->part_like_isohybrid)
up_to = 0; /* No gap filling */
for (i = 0; i < up_to; i++) {
if (i < up_to - 1) {
goal = t->gpt_req[i]->start_block;
@ -1671,12 +1763,40 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
}
/* Add a dummy MBR partition of type 0 with boot flag */
static void iso_dummy_mbr_partition(uint8_t *buf, int mode)
{
int i;
/* bootable , start 0/0/1, type 0x00, end 0/0/1,
start LBA 0, block count 1 */
static uint8_t dummy_entry[16] = {
0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 };
for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] == 0x00) {
memcpy(buf + 446 + 16 * i, dummy_entry, 16);
return;
}
}
/* Abundance of 0xee and 0xef partitions. No other one free. */
for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] != 0xef) {
buf[446 + 16 * i] |= 0x80;
return;
}
}
i = 3;
buf[446 + 16 * i] |= 0x80;
}
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
{
int ret, int_img_blocks, sa_type, i, will_append = 0, do_isohybrid = 0;
int first_partition = 1, last_partition = 4, apm_flag, part_type = 0;
int gpt_count = 0, gpt_idx[128], apm_count = 0, no_boot_mbr = 0;
int offset_flag = 0;
int offset_flag = 0, risk_of_ee = 0;
uint32_t img_blocks, gpt_blocks, mbrp1_blocks, pml_blocks;
uint64_t blk;
uint8_t *wpt;
@ -1709,6 +1829,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
/* Check for isolinux image with magic number of 3.72 and produce
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
*/
if (t->bootsrc[0] == NULL)
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Cannot refer by isohybrid MBR to data outside of ISO 9660 filesystem.");
if (img_blocks < 0x80000000) {
int_img_blocks= img_blocks;
} else {
@ -1767,8 +1890,11 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
"Cannot set up MBR partition table");
return ret;
}
if (t->mbr_req_count > 0 && sa_type != 0)
return ISO_NON_MBR_SYS_AREA;
if (t->mbr_req_count > 0) {
if (sa_type != 0)
return ISO_NON_MBR_SYS_AREA;
risk_of_ee = 1;
}
if (t->gpt_backup_outside)
gpt_blocks = t->total_size / BLOCK_SIZE + t->opts->ms_block;
@ -1784,7 +1910,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
if (t->mbr_req_count == 0){
/* Write GRUB protective msdos label, i.e. a simple partition
table */
if (t->gpt_req_count > 0) {
if (t->gpt_req_count > 0 && ! t->opts->part_like_isohybrid) {
part_type = 0xee;
pml_blocks = gpt_blocks;
} else {
@ -1796,6 +1922,11 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
(uint8_t) part_type, buf, 0);
if (ret != ISO_SUCCESS) /* error should never happen */
return ISO_ASSERT_FAILURE;
risk_of_ee = 1;
} else if (t->gpt_req_count > 0) {
/* >>> ??? change first partition type to 0xee */;
}
} else if (do_isohybrid) {
/* Patch externally provided system area as isohybrid MBR */
@ -1813,6 +1944,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
if (t->opts->appended_as_gpt && t->have_appended_partitions) {
part_type = 0xee;
risk_of_ee = 1;
img_blocks = gpt_blocks;
no_boot_mbr = 2;
}
@ -1855,9 +1987,14 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
(uint8_t) 0xcd, buf, 2);
if (ret != ISO_SUCCESS) /* error should never happen */
return ISO_ASSERT_FAILURE;
risk_of_ee = 1;
if (t->opts->appended_as_gpt && t->have_appended_partitions) {
/* >>> ??? Do this in any case of t->gpt_req_count > ? */;
/* Re-write partion entry 1 : protective MBR for GPT */
part_type = 0xee;
risk_of_ee = 1;
ret = write_mbr_partition_entry(1, part_type,
(uint64_t) 1, ((uint64_t) gpt_blocks) * 4 - 1,
t->partition_secs_per_head, t->partition_heads_per_cyl,
@ -1881,7 +2018,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
With t->mbr_req_count > 0 this has already been done,
*/
img_blocks = t->curblock; /* value might be altered */
if (part_type == 0xee) {
if (part_type == 0xee && t->gpt_req_count > 0) {
mbrp1_blocks = t->total_size / BLOCK_SIZE + t->opts->ms_block;
offset_flag |= 2 | 1; /* protective MBR, no other partitions */
} else {
@ -1926,6 +2063,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
if (sa_type == 0 && (t->system_area_options & 0x4000) && !do_isohybrid) {
/* Patch MBR for GRUB2 */
if (t->bootsrc[0] == NULL)
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Cannot refer by GRUB2 MBR to data outside of ISO 9660 filesystem.");
blk = t->bootsrc[0]->sections[0].block * 4 +
Libisofs_grub2_mbr_patch_offsT;
wpt = buf + Libisofs_grub2_mbr_patch_poS;
@ -1933,6 +2073,50 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
wpt[i] = blk >> (i * 8);
}
/* Prevent partition type 0xee if no GPT emerged */
/* >>> ??? check for GPT magic number at byte 512 ff. ? */;
if (sa_type == 0 && ((t->system_area_options & 3) || risk_of_ee) &&
(t->opts->part_like_isohybrid || t->gpt_req_count == 0)) {
for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] == 0xee) {
iso_msgs_submit(0,
"Prevented partition type 0xEE in MBR without GPT",
0, "WARNING", 0);
buf[446 + 16 * i + 4] = 0xcd;
}
}
}
if (sa_type == 0 && (
(t->system_area_options & 3) ||
(t->system_area_options & (1 << 14)) ||
(((t->system_area_options >> 2) & 0x3f) == 2 &&
(t->system_area_options & (1 << 15)))
)) {
/* This is an MBR which shall have a bootable/active flag
protective-msdos-label, isohybrid, grub2-mbr, mbr-force-bootable
*/
for (i = 0; i < 4; i++)
if (buf[446 + 16 * i] & 0x80)
break;
if (i >= 4) { /* no bootable/active flag set yet */
for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] != 0x00 &&
buf[446 + 16 * i + 4] != 0xee &&
buf[446 + 16 * i + 4] != 0xef) {
buf[446 + 16 * i] |= 0x80;
break;
}
}
if (i >= 4) { /* still no bootable/active flag set */
if (t->system_area_options & (1 << 15)) /* Force it */
iso_dummy_mbr_partition(buf, 0);
}
}
}
return ISO_SUCCESS;
}
@ -2188,7 +2372,6 @@ void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16])
static uint8_t uuid_urandom[16];
uint32_t rnd, salt;
struct timeval tv;
struct timezone tz;
pid_t pid;
static int counter = 0, use_urandom = 0;
int i, ret, fd;
@ -2238,7 +2421,7 @@ fallback:;
per day.
*/
memcpy(u, uuid_template, 16);
gettimeofday(&tv, &tz);
gettimeofday(&tv, NULL);
for (i = 0; i < 4; i++)
u[i] = (salt >> (8 * i)) & 0xff;
for (i = 0; i < 2; i++)
@ -2270,7 +2453,7 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b
};
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int i, ret;
int i, ret, do_apm = 0, do_gpt = 0, index, already_in_gpt;
uint8_t gpt_name[72], *type_uuid;
#ifndef Libisofs_appended_partitions_inlinE
@ -2278,31 +2461,51 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
return 2;
#endif
/* Represent in GPT only if other GPT partitions are already registered
or if appended partitions are explicitely desired for GPT-only.
*/
if (t->gpt_req_count == 0 &&
!(t->have_appended_partitions && t->opts->appended_as_gpt))
return 2;
if ((t->apm_req_count > 0 && t->opts->part_like_isohybrid) ||
(t->have_appended_partitions && t->opts->appended_as_apm))
do_apm = 1;
if (t->gpt_req_count > 0 ||
(t->have_appended_partitions && t->opts->appended_as_gpt))
do_gpt = 1;
if (do_apm == 0 && do_gpt == 0)
return 2;
/* Represent appended partitions */
for (i = 0; i <= 3; i++) {
if (t->opts->appended_partitions[i] == NULL)
continue;
memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "Appended%d", i + 1);
iso_ascii_utf_16le(gpt_name);
if (t->opts->appended_part_types[i] == 0xef)
type_uuid = efi_sys_uuid;
else
type_uuid = basic_data_uuid;
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
if (do_apm) {
memset(gpt_name, 0, 32);
sprintf((char *) gpt_name, "Appended%d", i + 1);
ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
t->appended_part_start[i] * t->hfsp_iso_block_fac,
t->appended_part_size[i] * t->hfsp_iso_block_fac,
(char *) gpt_name, "Data");
if (ret < 0)
return ret;
}
if (do_gpt)
already_in_gpt = iso_find_gpt_entry(t->gpt_req, t->gpt_req_count,
((uint64_t) t->appended_part_start[i]) * 4,
((uint64_t) t->appended_part_size[i]) * 4,
&index, 0);
if (do_gpt && !already_in_gpt) {
memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "Appended%d", i + 1);
iso_ascii_utf_16le(gpt_name);
if (t->opts->appended_part_types[i] == 0xef)
type_uuid = efi_sys_uuid;
else
type_uuid = basic_data_uuid;
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
((uint64_t) t->appended_part_start[i]) * 4,
((uint64_t) t->appended_part_size[i]) * 4,
type_uuid, zero_uuid,
(uint64_t) 0, gpt_name);
if (ret < 0)
return ret;
if (ret < 0)
return ret;
}
}
return ISO_SUCCESS;
}
@ -2341,6 +2544,23 @@ static int precompute_gpt(Ecma119Image *t)
return ret;
}
/* With part_like_isohybrid:
If no GPT is registered yet, and MBR, but neither CHRP nor ISOLINUX
isohybrid is desired, then try to apply the isohybrid GPT and APM flags
nevertheless. Avoid an overall ISO image GPT partition.
*/
if (t->opts->part_like_isohybrid && t->gpt_req_count <= 0 &&
((t->system_area_options >> 2) & 0x3f) == 0 &&
((t->system_area_options >> 10) & 0xf) != 1 &&
(!(t->system_area_options & 2))) {
ret = assess_isohybrid_gpt_apm(t, &gpt_count, gpt_idx, &apm_count,
1 | ((t->apm_req_count > 0) << 1) | 4);
if (ret <= 0)
return ret;
t->apm_req_flags |= 2; /* Do not fill APM gaps,
do not adjust final APM partition size */
}
/* Rectify APM requests early in order to learn the size of GPT.
iso_write_apm() relies on this being already done here.
@ -2596,8 +2816,7 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
with_chrp = ((t->system_area_options & 0x3cff) == 0x0400);
if (t->opts->efi_boot_partition != NULL ||
(t->opts->hfsplus && !with_chrp) ||
t->gpt_req_count > 0)
t->gpt_req_count > 0) /* Might not catch all cases with GPT */
will_have_gpt = 1;
if (t->opts->efi_boot_partition != NULL) {